270

I've just started exploring Github actions however I've found myself placing a command in multiple places.

I have a PHP project where the composer.json is not in the root, my structure looks like:

my-project:
    readme.md
    app:
        composer.json

Obviously there is more to it and there is a reason why, but my composer.json sits in a subdirectory called 'app'. As a result in my workflow, I have to cd into that folder every time to run a command:

name: CI

on: [push]

jobs:
  phpunit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - name: Setup Symfony
        run: |
          cd app
          cp .env.dev .env
      - name: Install Composer Dependencies
        run: |
          cd app
          composer install --prefer-dist
      - name: Run Tests
        run: |
          cd app
          php bin/phpunit

How can I remove the cd app in every stage?

rmunn
  • 34,942
  • 10
  • 74
  • 105
MylesK
  • 3,349
  • 2
  • 9
  • 31

3 Answers3

366

Update: It's now possible to set a working-directory default for a job. See this answer.

There is an option to set a working-directory on a step, but not for multiple steps or a whole job. I'm fairly sure this option only works for script steps, not action steps with uses.

https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstepsrun

Using working-directory, your workflow would look like this. It's still quite verbose but maybe a bit cleaner.

name: CI

on: [push]

jobs:
  phpunit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - name: Setup Symfony
        working-directory: ./app
        run: cp .env.dev .env
      - name: Install Composer Dependencies
        working-directory: ./app
        run: composer install --prefer-dist
      - name: Run Tests
        working-directory: ./app
        run: php bin/phpunit

Alternatively, you can run it all in one step so that you only need to specify working-directory once.

name: CI

on: [push]

jobs:
  phpunit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - name: Setup and run tests
        working-directory: ./app
        run: |
          cp .env.dev .env
          composer install --prefer-dist
          php bin/phpunit
koppor
  • 19,079
  • 15
  • 119
  • 161
peterevans
  • 34,297
  • 7
  • 84
  • 83
  • 1
    Is it possible to set different `working-directory` for different steps? – idkman Jul 28 '22 at 17:20
  • 1
    @idkman yes, you can add working-directory: ./app to every step. Thats exactly what this answer is about :) – Pfinnn Oct 06 '22 at 15:35
  • if you are using `uses` such as the UploadArtifact action. what is the solution for this edgecase? – Kay Aug 16 '23 at 13:46
290

You can now add a default working directory for all steps in a job: docs

For the example here, this would be:

name: CI

on: [push]

jobs:
  phpunit:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: ./app
    steps:
      - uses: actions/checkout@v1
      - name: Setup Symfony
        run: .env.dev .env
      - name: Install Composer Dependencies
        run: composer install --prefer-dist
      - name: Run Tests
        run: php bin/phpunit

Caveat: this only applies to run steps; eg you'll still need to add the subdirectory to with parameters of uses steps, if required.

Tomas
  • 3,086
  • 2
  • 15
  • 8
  • 38
    Do you know how to use `working-directory` with `uses`? As you mentioned, do you have any example using `with` and `uses`? Thanks – theprogrammer Mar 03 '21 at 18:09
  • 1
    Which action do you `uses` and does it have any arguments (specified with `with`) that need given a path? If so, these paths must be given relative to the default root dir, and not the `default.run.working-directory`. – Tomas Mar 10 '21 at 11:58
  • 4
    @theprogrammer if you use `uses` the author of the package has to specifically support `working-directory` or implement something similar for their purpose and context. As far as I have seen, most dont. – perelin Apr 13 '22 at 12:51
  • Can we use variable in working-directory eg ./app/$SOME_DIR? – Sufiyan Ansari May 13 '22 at 09:50
  • For the FirebaseHosting push, you can add to `with:` following field `entryPoint: "./someDirectory` – JoKr Feb 16 '23 at 08:47
69

Hope this will help somebody

name: CI

on:
 ...

defaults:
 run:
  working-directory: ./app

jobs:
 ...
Vlad R
  • 1,851
  • 15
  • 13