💸Save up to $132K/month in CI costs!👉 Try Free
Skip to main content
Understanding "working-directory" in GitHub Actions
3 min read

Understanding "working-directory" in GitHub Actions

Optimize Your CI/CD Pipeline

Get instant insights into your CI/CD performance and costs. Reduce build times by up to 45% and save on infrastructure costs.

45% Faster Builds
60% Cost Reduction

Introduction

The working directory plays an important role with GitHub Actions in placing your scripts and commands in the right position. By default, GitHub Actions works from the topmost level in your repository tree. You can define where the shell commands will execute by setting the working-directory and giving good organization and structure to your workflows. This is beneficial for projects that might be sparsely complicated, like monorepos, which lead to many directories.

Steps we will cover in this article:

Understanding working-directory

In GitHub Actions, the working-directory option specifies in what directory the shell should run for a given step, job or workflow. By default, each command is executed in the root of the repository, but you can override this behavior by using working-directory with an explicit path.

Basic Example

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Run build command in scripts directory
run: npm run build
working-directory: ./scripts

Here the following command npm run build is executed in the scripts directory itself, instead of the main directory of the repository.

Setting the Defaults at the Job Level

You also can set default options of working-directory for all job using jobs.<job_id>.defaults.run. That way you won't have to repeat directory specifications in every step's definition.

jobs:
job1:
runs-on: ubuntu-latest
defaults:
run:
shell: bash
working-directory: ./scripts
steps:
- name: Install dependencies
run: npm install
- name: Run tests
run: npm test

Here, all actions of this job will execute from the ./scripts directory. IR ischemic maintains consistency and also reduces repetition in workflow configuration files.

Overriding working-directory for Specific Steps

Configuring a default working directory for the job may be useful but most of the time at least one or more of the steps needs a different directory. You are allowed to override any of working-directory of any step without affecting the defaults for the job.

Overriding Working Directory for a Step

jobs:
job1:
runs-on: ubuntu-latest
defaults:
run:
shell: bash
working-directory: ./scripts
steps:
- name: Install dependencies
run: npm install
- name: Run cleanup in a different directory
run: rm -rf *
working-directory: ./temp

Here all the steps will change their working directory to ./scripts except the cleanup step which changes its working directory to ./temp.

Setting working-directory at the Workflow Level

You can define the parameter working-directory on the workflow level and it will be applied to every job. It is useful when all jobs intend to run in some common directory structure.

Workflow-Level Working Directory

defaults:
run:
working-directory: ./src

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Install dependencies
run: npm install
- name: Build project
run: npm run build

In this setup, all the tasks in the workflow will execute their actions in the ./src directory unless specified to be otherwise.

Conclusion

Wrappers like GitHub Actions allow setting a working directory, hence giving control over where your commands will execute. By setting defaults either at the job or workflow level, you remove redundancy and make your CI/CD pipelines leaner. Moreover, knowing when and how to override the working-directory for specific steps provides the needed flexibility for complex projects. Follow these best practices to make your workflows more manageable, readable, and maintain consistency across all your jobs.