Is there any way to get the EXPECTED status checks from the Github API?

Hello

We are using github actions and we would like to configure required checks for the PRs that go over the repository. In doing so we have seen, given the nature of our repositories, that some workflows do not fired because they are configured to trigger to changes in certain paths, so we see PRs that cannot be merged due to having active branch protection with these mandatory checks.
My question is if there is any way to obtain, through the API, the checks whose status is expected (and probably will not end up being triggered for this PR) to be able to control them from a new workflow.

The approach that we are carrying out we are implementing it using the GITHUB_TOKEN (to avoid rate limits) that is available from the github actions, but we see that this token does not have access to the endpoint of repository branch protections so if we could get these checks that are expected. could serve for it.

query($owner:String!, $name:String!, $pr_number:Int!) {
              repository(owner:$owner, name:$name) {
                pullRequest(number:$pr_number) {
                  baseRef {
                    branchProtectionRule {
                      pattern
                      requiredStatusCheckContexts
                    }
GraphqlError: Resource not accessible by integration
    at /home/runner/work/_actions/actions/github-script/v4/dist/index.js:6022:13
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at async eval (eval at callAsyncFunction (/home/runner/work/_actions/actions/github-script/v4/dist/index.js:2451:56), <anonymous>:22:16)
    at async main (/home/runner/work/_actions/actions/github-script/v4/dist/index.js:2505:20) {
  data: { repository: { pullRequest: [Object] } },

Curiously we have been able to obtain, through the graphql api using the GITHUB_TOKEN, if a executed checkrun is required, with the following query:

query($owner:String!, $name:String!, $pr_number:Int!) {
  repository(owner:$owner, name:$name) {
    pullRequest(number:$pr_number) {
      commits(last:1) {
        nodes {
          commit {
            statusCheckRollup {
              contexts(first:100) {
                nodes {
                  ... on CheckRun{
                    conclusion
                    status
                    name
                    isRequired(pullRequestNumber:$pr_number)
                  }

but we don’t see a way to get all the expected checks in a commit, if they are not executed.

Adding logic that interacts with your branch protection rules at runtime creates fragility in your Code Review process and increases the potential for bad code to make it into your protected branches. Are you sure that this approach is best for your needs?

I think an easy mistake to make when designing GitHub Workflows is a feeling that you must use the GitHub native features (like paths and paths-ignore) however in many cases the actual behaviour of these features is not suitable.

As a simple rule: if you have a required Workflow then you should always run that Workflow and allow the Workflow itself to determine if it is satisfied. The Pull Request required checks are described as follows:

All required statuses and check runs on this pull request must run successfully to enable automatic merging.

There are 4 possible outcomes for a GitHub Workflow, success failure cancelled and skipped. success and skipped are both successful runs, failure and cancelled are not. We can satisfy the Workflow successful run requirement without running unnecessary tests by instructing the the Workflow to skip when there aren’t matching path changes.

There are some great Actions like Paths Changes Filter and Has Changed Path that can determine if there have been changes made within specified paths, here’s an example of a Workflow that will skip a job when there have not been changes within the specified path.

on:
  push:
    branches:
      - "**"

jobs:
  check-for-changes:
    outputs:
      has-changes: ${{ steps.changes.outputs.src }}
    runs-on: ubuntu-latest
    steps:
      - uses: dorny/paths-filter@v2
        id: changes
        with:
          filters: |
            src:
                - 'src/**'
  perform-expensive-tests:
    runs-on: ubuntu-latest
    needs:
      - check-for-changes
    if: ${{ needs.check-for-changes.outputs.has-changes == 'true' }}
    steps:
      - run: echo "Performing expensive tests"

Let me know if you need any further insight! I hope this helps shape your thinking around how to tackle this problem :slight_smile:

1 Like

Thank you very much for your answer. This was our first approach, but the amount of checks required and the workflows to be executed may vary by repository, so we would like to have a generic mechanism that allows us to determine these required checks and see if they are actually going to be executed, without having to depend on carrying out this check within each workflow to see if certain jobs of a workflow should be executed or not.