Search code examples
github-actionsgithub-api

How to add custom check status in PR for Gtihub actions


I'm using GitHub super-linter and like its feature to set multiple detailed statuses that can be checked via UI (--> Linted: ...):

Github Actions Statuses

I'm learning how it works and trying to implement same feature.

The successed status triggered on multiple PR events at the picture is simply printing out GitHub context and environment variables of this job.

So I used these ENVs and created simple script:

#!/usr/bin/env bash

CTX="test context"
GITHUB_API_URL=api.github.com
GITHUB_REPOSITORY=org-name/repository-name
GITHUB_SHA=sha_that_i_copied_from_printed_data
GITHUB_TOKEN=ghp_secretsecretsecret
GITHUB_RUN_ID=12345678_also_copied_from_job_printed_envs

curl --show-error -X POST \
  --url "https://${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/statuses/${GITHUB_SHA}" \
  -H 'accept: application/vnd.github.v3+json' \
  -H "authorization: Bearer ${GITHUB_TOKEN}" \
  -H 'content-type: application/json' \
  -d "{ \"state\": \"error\",
    \"target_url\": \"https://${GITHUB_DOMAIN:-github.com}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}\",
    \"description\": \"set to failed\", \"context\": \"${CTX}\"
  }"

When I run it I've got response like:

{
  "url": "https://api.github.com/repos/org-name/repository-name/statuses/sha_that_i_copied_from_printed_data",
  "avatar_url": "https://avatars.githubusercontent.com/u/12345678?v=4",
  "id": 1234567890,
  "node_id": "SC_ABCDEF0123456-iw",
  "state": "error",
  "description": "set to failed",
  "target_url": "https://github.com/...",
  "context": "test context",
  "created_at": "2023-03-13T13:42:54Z",
  "updated_at": "2023-03-13T13:42:54Z",
  "creator": {
    "login": "user",
    "id": 123456789,
    "node_id": "ABCDEF123456",
    "avatar_url": "https://avatars.githubusercontent.com/u/12345678?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/user",
    "html_url": "https://github.com/",
    "followers_url": "https://api.github.com/users/user/followers",
    "following_url": "https://api.github.com/users/user/following{/other_user}",
    "gists_url": "https://api.github.com/users/user/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/user/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/user/subscriptions",
    "organizations_url": "https://api.github.com/users/user/orgs",
    "repos_url": "https://api.github.com/users/user/repos",
    "events_url": "https://api.github.com/users/user/events{/privacy}",
    "received_events_url": "https://api.github.com/users/user/received_events",
    "type": "User",
    "site_admin": false
  }
}

Also when I'm trying to get statuses by using:

curl -L \
  -H "Accept: application/vnd.github+json" \
  -H "Authorization: Bearer ${GITHUB_TOKEN}"\
  -H "X-GitHub-Api-Version: 2022-11-28" \
  "https://${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/statuses/${GITHUB_SHA}"

It's working good too and I able to see all statuses that I added.

But. I can't see any changes in UI. triggered on multiple PR events Job is still marked as successfully completed and no new status appear in list (like --> Linted: ... in case of super-linter). So what I'm doing wrong and how to add statuses that can be browsed via UI?

I tried to add manually by running curl from my PC and by using Github Actions (and used EVNs like GITHUB_SHA of actual job). Result is the same - nothing happens in UI.


Solution

  • The problem is that GITHUB_SHA wasn't correct. head SHA (it can be found in github.event.after context variable) should be used to add status.

    Also github.event.pull_request.statuses_url context variable may be used to get statuses URL as is. So I used this workflow to add extra check status:

    ---
    name: Some Test
    
    on:
      push:
        branches:
          - test/*
      pull_request:
        branches:
          - develop
    
    jobs:
      test:
        runs-on: ubuntu-latest
        name: Run Test
    
        permissions:
          id-token: write
          contents: read
          statuses: write
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          STATUSES_URL: ${{ github.event_name == 'pull_request' && github.event.pull_request.statuses_url || '' }}
    
        steps:
          - name: Add error status
            run: |
              if [ -n "${GITHUB_TOKEN}" ] && [ -n "${GITHUB_REPOSITORY}" ] && [ -n "${STATUSES_URL}" ]; then
                curl -f -s --show-error -X POST \
                  --url "${STATUSES_URL}" \
                  -H 'accept: application/vnd.github.v3+json' \
                  -H "authorization: Bearer ${GITHUB_TOKEN}" \
                  -H 'content-type: application/json' \
                  -d "{ \"state\": \"error\",
                    \"target_url\": \"https://${GITHUB_DOMAIN:-github.com}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}\",
                    \"description\": \"following after context description\", \"context\": \"some message here\"
                     }"
              fi