Monorepos and Limiting Workflows by changed files, required status checks

This post has an accepted solution that doesn’t seem to work in the way that I thought.

Is it outdated?

When I follow this example, I have two workflows with the same name and the same job names. When both workflows are triggered (the fake job runs all the time, and the actual build runs when a changed file matches), i see two status checks in the PR with the same name, same job, but different “details” links.

I believe when I tried this a few months ago, it worked out that the first status check would get overwritten by the second. Is this no longer the case? I’d like to keep my status checks as clean as possible.

My use case is that I want to essentially create conditional required checks, conditional on if the files changed or not. If the files did not change, default to the check passing.

@bagel-dawg,

You can try to only set up one workflow, and add the if conditional on each step in the job (jobs.<job_id>.steps.if).
In this way,

  • if the specified files are changed, all the steps in the job will be executed. The status of the job will depend on if there is any failed step.
  • if the specified files are not changed, all the steps in the job will be skipped. The status of the job will be set as success.

Is there a variable that contains changed files already defined that I can use in the if key?

I am doing just as you suggested, but I determine changed files by running an action and a bash script to collect a list of changed files, compare them to a set of strings to see if this job pertains to those files, and then basing my if${{}}'s off of that step output.

@bagel-dawg,

Is there a variable that contains changed files already defined that I can use in the if key?

As far as I know, there is no such variable.
I checked in the Default environment variables and github context, and did not find any environment variable or property can return the list of changed files.

As you mentioned, you need to use some actions or git commands to get the changed files.
Here I have an example as reference:

jobs:
  job1:
    . . .
    steps:
      - name: Check changed files
        id: check_files
        run: |
          echo "List changed files:"
          git diff --name-only HEAD^ HEAD

          echo "Compare changed files:"
          git diff --name-only HEAD^ HEAD > changed_files.txt
          while IFS= read -r file
          do
            echo $file
            if [[ $file == <required_file> ]]; then
              echo "::set-output name=run_subseq_steps::true"
              break
            else
              echo "::set-output name=run_subseq_steps::false"
            fi
          done < changed_files.txt
          rm changed_files.txt

      - name: subseq_step_1
        if: ${{ steps.check_files.outputs.run_subseq_steps == 'true' }}

      - name: subseq_step_2
        if: ${{ steps.check_files.outputs.run_subseq_steps == 'true' }}

      . . .

      - name: subseq_step_N
        if: ${{ steps.check_files.outputs.run_subseq_steps == 'true' }}

In this example, “<required_file>” is a string for the path of a file. When this file is contained in the changed files, the subsequent steps in the job will be executed, otherwise the subsequent steps will be skipped.

In addition, below is a similar topic as reference:

1 Like