Github Workflow — Feature branch changes— How to trigger a job based on changes to specific path

Imagine you have the following requirements:

  • Workflow triggers when a commit is pushed to a feature branch
  • Capture if changes have been made to files in a specific path
  • Run Step only if changes have been made to files in that path.

Because the workflow was triggered when a change was pushed to the feature branch and the checkout action would set the feature branch as the active branch, to detect the changes cannot be done the same way you would do it when the Workflow is triggered by a Pull Request.

After trying multiple options/parameters of the git diff command ( a lot of trial an error), finally the below version worked.

Steps:

  • Fetch-depth needs to be set to 2 or more, otherwise it was not working for me.
  • get the latest commit hash
  • use git diff-tree for that hash and filter on the specific path you want to monitor for changes
  • Output the returned list of files to a variable. when multiple files were returned I would get an error trying to assign the value to the output variable so I did a quick/dirty fix to trim the result.
  • Output variable is then used in a subsequent Step or in my case in a different JOB to determine if the job needs to run

In the example below I have 2 GitHub workflow jobs ( BUILD and INIT). In the BUILD job, there is a step that checks the file changes in the last commit and outputs these changes to a output variable. The INIT job check if there are any changes in the output variable. The job only runs if there are changes in the output variable, otherwise it will skip the job.

Example

1- Checking file changes in specific file path

Checking for file changes in the last commit in specific path → INIT_PATH: ‘src/init_account/**’ and output changes to output variable → init_changes: ${{ steps.file_changes.outputs.changes }}

DEPLOY:
    name: na
    runs-on: ubuntu-latest
    environment: DEV
    outputs:
      init_changes: ${{ steps.file_changes.outputs.changes }}
    needs: [BUILD]
    steps:
      - uses: actions/checkout@v3 
        with:
          fetch-depth: 2
      - name: Export file changes
        id: file_changes
        env:
          INIT_PATH: 'src/init_account/**' 
        run: |
          commit_hashes=$(git log -n 1 --pretty=format:"%H")
          echo "Last commit hashes: $commit_hashes"
          result=$(git diff-tree --no-commit-id --name-only -r $commit_hashes -- ${{env.INIT_PATH}})
          echo "File changes: $result"
          echo "changes=${result:0:18}" >> $GITHUB_OUTPUT 

2- Use the output variable as a condition to run or skip the INIT job.

INIT:
    name: Init Workspace
    runs-on: ubuntu-latest
    environment: DEV
    needs: [DEPLOY]
    if: ${{needs.DEPLOY.outputs.init_changes != ''}}

Read more recent blogs

Get started on the right path to cloud success today. Our Crew are standing by to answer your questions and get you up and running.