Search code examples
githubgithub-actions

Github Actions retrigger workflow on comment


When a developer comments /retest, I want to re-trigger PR build. Note: I'm also calling different workflow here.

My workflow file:

# Workflow for retrigger pr builder on comment and reuse workflow
# caller workflow

    name: Pull request comment
    on:
      issue_comment:
        types: [ created ]
    
    permissions:
      contents: read
    
    jobs:
      build:
        uses: ./.github/workflows/pr-build.yml
        if: contains(github.event.comment.body, '/retest')
        secrets: inherit
          

It triggers a build, but it does not show from the PR (page), that a build is running. We know only a build was triggered and ran successfully when one clicks on Actions tab and checks this manually.

This is achieved with the current step we have on Jenkins. Even though it's a new build, the check shows that build is running (white wheel loading). But with GitHub Actions I'm unable to achieve this.

enter image description here

What am I missing to achieve a similar use case? I want to achieve how it's happening on Jenkins:

enter image description here


Solution

  • You can re-run a previously run check via the checks API. Unfortunately there's no easy way to get the information necessary to query that api. But we can get there with a few steps.

    A workflow for how to rerun a check for a commit that is part of a PR, that we can search by the job name;

    This will take the issue, get the PR number, use that to get the latest commit sha, then use that to try and find all jobs associated with the latest commit that match a certain name, and re run all of them. It will take about 15 to 30 seconds for the status of the job to appear on the page of the PR, but it will eventually do so.

    name: Pull request comment
    on:
      issue_comment:
        types:
        - created
    defaults:
      run:
        shell: bash
    permissions: {}
    env:
      OWNER: name-of-repo-owner
      REPO: name-of-repo
      JOB_NAME: "PR Build"
    jobs:
      create-check:
        name: Create Check
        if: contains(github.event.comment.body, '/retest')
        runs-on: ubuntu-latest
        permissions:
          # checks read ~ /repos/OWNER/REPO/commits/REF/check-suites
          # checks write ~ /repos/OWNER/REPO/check-suites/CHECK_SUITE_ID/rerequest
          # contents read ~ actions/checkout
          # pull-requests read ~ gh pr view
          checks: write 
          contents: read
          pull-requests: read
        steps:
        - uses: actions/checkout@v3
        # https://docs.github.com/en/webhooks/webhook-events-and-payloads#issue_comment
        # No easy way to get the sha of the current PR. So instead get its number and use
        # the number with https://cli.github.com/manual/gh_pr_view to get name and sha.
        - name: Get PR sha
          env:
            GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          run: |-
            export PR_URL="${{ github.event.issue.pull_request.url }}"
            export PR_NUMBER=${PR_URL##*/}
            export BRANCH_NAME=$(gh pr view $PR_NUMBER --json headRefName --jq '.headRefName')
            export BRANCH_HEAD=$(gh pr view $PR_NUMBER --json commits --jq '.commits[-1].oid')
            echo "PR $PR_NUMBER is for $BRANCH_NAME @ $BRANCH_HEAD"
            echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_ENV
            echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV
            echo "BRANCH_HEAD=$BRANCH_HEAD" >> $GITHUB_ENV
        # From this stage you can use BRANCH_NAME or BRANCH_HEAD
        # Now we have both / either the branch name, and the head commit sha. They
        # can be used in the checks + check-suites APIs to list 
        # https://docs.github.com/en/rest/checks?apiVersion=2022-11-28
        # Rerun by run's suite ID
        - name: Get check run ID
          env:
            GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          # https://docs.github.com/en/rest/checks/runs?apiVersion=2022-11-28#list-check-runs-for-a-git-reference
          run: |-
            {
              echo "CHECK_SUITE_IDS<<EOF"
              gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" \
              /repos/${{ env.OWNER }}/${{ env.REPO }}/commits/${{ env.BRANCH_HEAD }}/check-runs | \
              jq '.check_runs[] | select(.name == "${{ env.JOB_NAME }}") | select(.pull_requests != null) | select(.pull_requests[].number == ${{ env.PR_NUMBER }}) | .check_suite.id'
              echo "EOF"
            } >> $GITHUB_ENV
        - name: Rerequest check suite
          env:
            GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          # https://docs.github.com/en/rest/checks/suites?apiVersion=2022-11-28#rerequest-a-check-suite
          run: >-
            while IFS= read -r CHECK_SUITE_ID ; do
            gh api --method POST -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28"
            /repos/${{ env.OWNER }}/${{ env.REPO }}/check-suites/$CHECK_SUITE_ID/rerequest
            ; done <<< "${{ env.CHECK_SUITE_IDS }}"