how.wtf

Run workflow, step, or job based on file changes GitHub Actions

· Thomas Taylor

There are options for conditionally running GitHub actions at the workflow, job, or step level based on file changes.

Trigger GitHub Action workflow on file changes

GitHub actions natively support triggering workflows based on file changes:

 1on:
 2  push:
 3    paths:
 4    - 'src/**'
 5
 6jobs:
 7  job1:
 8    steps:
 9    - uses: actions/checkout@v3
10    - name: tests
11      run: ...

On a push to any file within the src/** directory, this workflow will execute job1 and its steps.

Run job based on file changes in GitHub Actions

GitHub actions do not natively support triggering jobs based on file changes; however, there is a marketplace action that supports this use-case named dorny/paths-filter.

 1on:
 2  push:
 3    branches:
 4    - main
 5
 6jobs:
 7  changes:
 8    runs-on: ubuntu-latest
 9    outputs:
10      src: ${{ steps.changes.outputs.src }}
11      infra: ${{ steps.changes.outputs.infra }}
12    steps:
13    - uses: actions/checkout@v3
14    - uses: dorny/paths-filter@v2
15      id: changes
16      with:
17        filters: |
18          src:
19            - 'src/**'
20          infra:
21            - 'infra/**'          
22
23  src:
24    needs: changes
25    if: ${{ needs.changes.outputs.src == 'true' }}
26    runs-on: ubuntu-latest
27    steps:
28    - uses: actions/checkout@v3
29    - run: ...
30
31  infra:
32    needs: changes
33    if: ${{ needs.changes.outputs.infra == 'true' }}
34    runs-on: ubuntu-latest
35    steps:
36    - uses: actions/checkout@v3
37    - run: ...

On a push to the main branch, this workflow will execute; however, the first action checks where changes occurred and outputs true or false for the specified filtered paths.

Run step based on file changes in GitHub Actions

Similarly to jobs, GitHub actions to not natively support triggering individual steps based on file changes. dorny/paths-filter supports this use-case as well.

 1on:
 2  push:
 3    branches:
 4    - main
 5
 6jobs:
 7  job1:
 8    steps:
 9    - uses: actions/checkout@v3
10    - uses: dorny/paths-filter@v2
11      id: changes
12      with:
13        filters: |
14          src:
15            - 'src/**'
16          infra:
17            - 'infra/**'
18                      
19    - name: src deploy
20      if: steps.changes.outputs.src == 'true'
21      run: ...
22      
23    - name: infra deploy
24      if: steps.changes.outputs.infra == 'true'
25      run: ...
26    
27    - name: e2e
28      if: steps.changes.outputs.src == 'true' || steps.changes.outputs.infra == 'true'
29      run: ...

Pull requests

On a side note, dorny/paths-filter does not need the checkout action for pull request triggered actions.

 1on:
 2  pull_request:
 3    branches:
 4    - main
 5
 6jobs:
 7  build:
 8    runs-on: ubuntu-latest
 9    # For pull requests, it's not necessary to checkout code
10    permissions:
11      pull-requests: read
12    steps:
13    - uses: dorny/paths-filter@v2
14      id: filter
15      with:
16        filters: ... # Configure your filters

#github-actions  

Reply to this post by email ↪