Search code examples
github-actionspull-request

How can I handle a required check that isn't always triggered?


I am using GitHub Actions to check code to verify commits. There are many workflows and those actions are triggered by different conditions.

Currently: I set Require status checks to pass before merging to true and Status checks that are required set with actions. e.g. action#1, action#3, action#9

Problem: action#3 is not triggered because there is no code changed. On the other hand, action#3 is required. Therefore, action#3 never runs and the pull request checks are never passed.

Potential solution #1: change action#3 to always run and action#3 takes 30-45 minutes to build and test code. This is time consuming if no code changes in the project.

Potential solution #2: remove action#3 from Require status checks to pass before merging. Other developers can click the "Merge pull request" button before the action#3 success/fail.

I am looking for a different way to check actions status. For example, if all triggered status (actions) are success, then enable the "Merge pull request" button.

Is there any way to accomplish this goal?


Solution

  • The official recommendation for this scenario (required check that isn't always triggered) has changed a few times. Currently, it's actually not telling you what to do for the case of path/branch filtering:

    If a workflow is skipped due to path filtering, branch filtering or a commit message, then checks associated with that workflow will remain in a "Pending" state. A pull request that requires those checks to be successful will be blocked from merging.

    If, however, a job within a workflow is skipped due to a conditional, it will report its status as "Success". For more information, see "Using conditions to control job execution."

    The previous advice was

    For this reason you should not use path or branch filtering to skip workflow runs if the workflow is required.

    And before that, the recommendation was to create a second workflow with the exact same name that is always triggered, and has successful exit status. The example from the documentation back then:

    A workflow with a path filter:

    name: ci
    on:
      pull_request:
        paths:
          - 'scripts/**'
    jobs:
      build:
        runs-on: ubuntu-latest
        strategy:
          matrix:
            node-version: [12.x, 14.x, 16.x]
        steps:
        - uses: actions/checkout@v4
        - name: Use Node.js ${{ matrix.node-version }}
          uses: actions/setup-node@v3
          with:
            node-version: ${{ matrix.node-version }}
            cache: 'npm'
        - run: npm ci
        - run: npm run build --if-present
        - run: npm test
    

    and a "generic" workflow that is triggered when the real one isn't, and always succeeds:

    name: ci
    on:
      pull_request:
        paths-ignore:
          - 'scripts/**'
    jobs:
      build:
        runs-on: ubuntu-latest
        steps:
          - run: 'echo "No build required"'
    

    If the workflows call reusable workflows, there's a caveat that either both the "real" and the generic workflow must make such a call, or none of them; else they won't be recognized as the same check.