1. Introduction

By default, Github Actions operates in our repo’s root. However, sometimes our workflow needs to operate on data nested in the filesystem. To solve this, we can script or configure our workflow for efficient file access in subdirectories.

In this tutorial, we’ll discuss a few ways to run Github Actions to operate on files in our subdirectories.

2. Using the Path of Target File or Directory

When executing a command on a file or directory that isn’t in the root directory, we can simply specify the path of the target. Let’s have a workflow file containing:

name: Path Demo
on:
  push:
    branches:
      - main
jobs:
  demo:
    name: demo
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: cat directory_1/file_1
      - run: cat directory_2/file_2

As expected, the runs operated on the targets based on the specified paths:

using path in Github Actions run steps

This is straightforward for simple operations on individual files, but it could get pretty complex and inefficient if we had to do it for a lot of them. Also, we can only specify the path of the target file or directory this way when running a step.

When using file or directory paths, absolute paths are preferable because they are more predictable; relative paths may produce unexpected behavior.

3. Running the cd Command

To run Github Actions in a specific directory, we can add the cd command to our run steps:

name: cd Command Demo
on:
  push:
    branches:
      - main
jobs:
  demo:
    name: demo
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: |
          cd directory_1
          cat file_1
      - run: |
          cd directory_2
          cat file_2

When we run the workflow above, each step switches to the specified directory and executes the defined command:

changing directory in Github Actions with cd command

Compared to using the target’s path, the cd command can be more effective and require less repetition. If multiple targets are in the same subdirectory, one cd command execution could suffice.

We should note that we can only change directory with the cd command in run steps. In other words, we cannot change directory at the job level using the cd command.

4. Using the working-directory Keyword

GitHub Actions provides explicit support for setting a working directory. We can use the working-directory keyword at the workflow, job, and step levels.

4.1. Working Directory for a Step

We’ll start by using working-directory in steps:

name: working-directory Demo
on:
  push:
    branches:
      - main
jobs:
  demo:
    name: demo
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: cat file_1
        working-directory: directory_1
      - run: cat file_2
        working-directory: directory_2

Once again, we have the same outcome:

Changing working directory in Github Actions steps

4.2. Using working-directory at the Job Level

When we use working-directory in a step, we’d have to define the working directory for each step – pretty much the same thing we did in the previous sections. But if all the steps in a job have the same working directory, we can specify that directory at the job level:

name: working-directory Demo
on:
  push:
    branches:
      - main
jobs:
  demo:
    name: demo
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: directory_3
    steps:
      - uses: actions/checkout@v4
      - run: cat file_3
      - run: cat file_4

In the configuration above, the two runs happened in the same working directory. So, specifying the working-directory at the job level was enough for their execution:

Changing working directory in Github Actions steps

4.3. Using working-directory at the Workflow Level

We can also define the working directory at the workflow level, and this would be handy when most or all jobs have to run in a subdirectory:

name: working-directory Demo
on:
  push:
    branches:
      - main
defaults:
  run:
    working-directory: directory_3

jobs:
  job1:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: cat file_1
  job2:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: cat file_2
  job3:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: cat file_3
  job4:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: cat file_4

In the command above, the jobs used the same working directory. So, instead of defining the working directory for each job, we defined the working directory just once at the job level.

5. Conclusion

In this article, we described how to make Github Actions run in a different directory using the cd command, absolute path, and working-directory keyword.

Of all three methods, the working-directory keyword is the most efficient option as we can use it at the workflow, job, and steps level.