André Roaldseth
André Roaldseth

Reputation: 550

How to trigger a GitHub Action workflow for every successful commit

I want to run a GitHub Actions workflow for every successful commit (e.g. after all check suites have ran successfully).

It seems like the check_suite events will be fired for each individual check suite, and contain no information about the other suites. I want to wait for all registered check suites.

The status event seems to be exactly what I want:

Statuses can include a context to indicate what service is providing that status. For example, you may have your continuous integration service push statuses with a context of ci, and a security audit tool push statuses with a context of security. You can then use the combined status endpoint to retrieve the whole status for a commit.

But the status lives completely unrelated to the check_suites events, and most CI services now uses the check_suites (including GitHub Actions itself), and not status.

How can I, with a GitHub Actions workflow, check that all check_suites finished and the commit has successfully passed all checks and tests?

Upvotes: 2

Views: 1860

Answers (2)

Eric
Eric

Reputation: 842

It looks like you are now able to trigger actions based on commit status (reference).

on:
  status
jobs:
  if_error_or_failure:
    runs-on: ubuntu-latest
    if: >-
      github.event.state == 'error' ||
      github.event.state == 'failure'
    steps:
      - env:
          DESCRIPTION: ${{ github.event.description }}
        run: |
          echo The status is error or failed: $DESCRIPTION

Upvotes: 0

n6g7
n6g7

Reputation: 408

You can use the GitHub API to list the check suites belonging to a ref: https://octokit.github.io/rest.js/#octokit-routes-checks-list-suites-for-ref.

So, within your action (triggered by check_suite), you can list all the suites for the current ref, check they're all successful and then run your code.

If you're building a javascript action it could look like this:

import * as github from "@actions/github";

const response = await client.checks.listSuitesForRef({
  owner: github.context.repo.owner,
  repo: github.context.repo.repo,
  ref: sha
});

const passes = response.data.check_suites.every(...)

if (passes) { ... }

The major drawback of this approach is that this very action is itself a check suite belonging to the current commit, so it will appear in response.data.check_suites (and will never be successful at this point ... because it's still running!). I don't have a solution for this part yet...

Upvotes: 1

Related Questions