Skip to content

Commit d0aa802

Browse files
krlmlrclaude
andcommitted
ci: Wrap the commit status update into an action
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 9f699e8 commit d0aa802

2 files changed

Lines changed: 109 additions & 99 deletions

File tree

.github/workflows/R-CMD-check.yaml

Lines changed: 16 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -93,39 +93,11 @@ jobs:
9393

9494
- name: Update status for rcc (pending)
9595
if: github.actor != 'Copilot' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository)
96-
# FIXME: Wrap into action
97-
# `inputs.ref` is free-form text supplied by whoever dispatched the run
98-
# and `github.workflow` comes from the workflow file of the ref under
99-
# test, so both are passed through the environment rather than spliced
100-
# into the script with `${{ }}`.
101-
env:
102-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
103-
REPO: ${{ github.repository }}
104-
RUN_ID: ${{ github.run_id }}
105-
INPUT_REF: ${{ inputs.ref }}
106-
EVENT_SHA: ${{ github.sha }}
107-
DESCRIPTION: ${{ github.workflow }} / ${{ github.job }}
108-
run: |
109-
set -euo pipefail
110-
echo "Actor: ${{ github.actor }}"
111-
112-
# Check status of this workflow
113-
state="pending"
114-
sha="${INPUT_REF:-${EVENT_SHA}}"
115-
sha=$(git rev-parse "${sha}")
116-
117-
html_url=$(gh api \
118-
-H "Accept: application/vnd.github+json" \
119-
-H "X-GitHub-Api-Version: 2022-11-28" \
120-
"repos/${REPO}/actions/runs/${RUN_ID}" | jq -r .html_url)
121-
122-
gh api \
123-
--method POST \
124-
-H "Accept: application/vnd.github+json" \
125-
-H "X-GitHub-Api-Version: 2022-11-28" \
126-
"repos/${REPO}/statuses/${sha}" \
127-
-f "state=${state}" -f "target_url=${html_url}" -f "description=${DESCRIPTION}" -f "context=rcc"
128-
shell: bash
96+
uses: ./.github/workflows/commit-status
97+
with:
98+
token: ${{ secrets.GITHUB_TOKEN }}
99+
state: pending
100+
sha: ${{ inputs.ref }}
129101

130102
- name: Report the GitHub API rate limit
131103
uses: ./.github/workflows/rate-limit
@@ -297,77 +269,22 @@ jobs:
297269
shell: bash
298270

299271
- name: Update status for rcc (final)
300-
# FIXME: Wrap into action
301272
if: always() && (github.actor != 'Copilot') && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository)
302-
env:
303-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
304-
REPO: ${{ github.repository }}
305-
RUN_ID: ${{ github.run_id }}
306-
JOB_STATUS: ${{ job.status }}
307-
COMMIT_SHA: ${{ steps.commit.outputs.sha }}
308-
INPUT_REF: ${{ inputs.ref }}
309-
EVENT_SHA: ${{ github.sha }}
310-
DESCRIPTION: ${{ github.workflow }} / ${{ github.job }}
311-
run: |
312-
set -euo pipefail
313-
# Check status of this workflow
314-
if [ "${JOB_STATUS}" = "success" ]; then
315-
state="success"
316-
else
317-
state="failure"
318-
fi
319-
320-
sha="${COMMIT_SHA:-${INPUT_REF:-${EVENT_SHA}}}"
321-
sha=$(git rev-parse "${sha}")
322-
323-
html_url=$(gh api \
324-
-H "Accept: application/vnd.github+json" \
325-
-H "X-GitHub-Api-Version: 2022-11-28" \
326-
"repos/${REPO}/actions/runs/${RUN_ID}" | jq -r .html_url)
327-
328-
gh api \
329-
--method POST \
330-
-H "Accept: application/vnd.github+json" \
331-
-H "X-GitHub-Api-Version: 2022-11-28" \
332-
"repos/${REPO}/statuses/${sha}" \
333-
-f "state=${state}" -f "target_url=${html_url}" -f "description=${DESCRIPTION}" -f "context=rcc"
334-
shell: bash
273+
uses: ./.github/workflows/commit-status
274+
with:
275+
token: ${{ secrets.GITHUB_TOKEN }}
276+
state: ${{ job.status }}
277+
# The commit that the commit-back step created, if there was one
278+
sha: ${{ steps.commit.outputs.sha || inputs.ref }}
335279

336280
- name: Update status for rcc (Copilot)
337281
# Update status directly when triggered by Copilot or bots, since they can't dispatch workflows
338282
if: always() && (github.actor == 'Copilot')
339-
env:
340-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
341-
REPO: ${{ github.repository }}
342-
RUN_ID: ${{ github.run_id }}
343-
JOB_STATUS: ${{ job.status }}
344-
INPUT_REF: ${{ inputs.ref }}
345-
EVENT_SHA: ${{ github.sha }}
346-
DESCRIPTION: ${{ github.workflow }} / ${{ github.job }}
347-
run: |
348-
set -euo pipefail
349-
# Set status to success if job succeeded, failure otherwise
350-
if [ "${JOB_STATUS}" = "success" ]; then
351-
state="success"
352-
else
353-
state="failure"
354-
fi
355-
356-
sha="${INPUT_REF:-${EVENT_SHA}}"
357-
sha=$(git rev-parse "${sha}")
358-
359-
html_url=$(gh api \
360-
-H "Accept: application/vnd.github+json" \
361-
-H "X-GitHub-Api-Version: 2022-11-28" \
362-
"repos/${REPO}/actions/runs/${RUN_ID}" | jq -r .html_url)
363-
364-
gh api \
365-
--method POST \
366-
-H "Accept: application/vnd.github+json" \
367-
-H "X-GitHub-Api-Version: 2022-11-28" \
368-
"repos/${REPO}/statuses/${sha}" \
369-
-f "state=${state}" -f "target_url=${html_url}" -f "description=${DESCRIPTION}" -f "context=rcc"
370-
shell: bash
283+
uses: ./.github/workflows/commit-status
284+
with:
285+
token: ${{ secrets.GITHUB_TOKEN }}
286+
state: ${{ job.status }}
287+
sha: ${{ inputs.ref }}
371288

372289
rcc-smoke-check-matrix:
373290
runs-on: ubuntu-26.04
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
name: "Update the commit status"
2+
description: >
3+
Set the commit status that pull requests are gated on.
4+
A workflow reports on the commit it runs on,
5+
which for a pull request is the merge commit,
6+
and for a run that commits back is the commit before that,
7+
so the status has to be set explicitly for the commit
8+
the pull request actually shows.
9+
10+
inputs:
11+
token:
12+
description: "Token used to write the commit status"
13+
required: true
14+
state:
15+
description: >
16+
One of `pending`, `success`, `failure` or `error`,
17+
or a job status, whose `cancelled` counts as a failure.
18+
Anything else fails the step:
19+
the status is a merge gate,
20+
and a typo must not turn into a green one.
21+
required: true
22+
sha:
23+
description: >
24+
Commit to attach the status to, as a sha or as a ref.
25+
A ref is resolved with `git rev-parse`,
26+
which needs the repository in the workspace;
27+
a full sha is used as it stands.
28+
Empty means the commit the workflow runs on.
29+
required: false
30+
default: ""
31+
context:
32+
description: "Status context, the name that pull requests are gated on"
33+
required: false
34+
default: "rcc"
35+
description:
36+
description: "Status description, empty means `<workflow> / <job>`"
37+
required: false
38+
default: ""
39+
target-url:
40+
description: "Where the status links to, empty means this workflow run"
41+
required: false
42+
default: ""
43+
44+
runs:
45+
using: "composite"
46+
steps:
47+
- name: "Set the ${{ inputs.context }} status to ${{ inputs.state }}"
48+
# Nothing is spliced into the script with `${{ }}`:
49+
# `inputs.sha` is free-form text supplied by whoever dispatched the run,
50+
# and `github.workflow` comes from the workflow file of the ref under test.
51+
env:
52+
GH_TOKEN: ${{ inputs.token }}
53+
STATE: ${{ inputs.state }}
54+
SHA: ${{ inputs.sha }}
55+
CONTEXT: ${{ inputs.context }}
56+
DESCRIPTION: ${{ inputs.description }}
57+
TARGET_URL: ${{ inputs.target-url }}
58+
# `github.job` is the job that uses this action, not a step of it
59+
DEFAULT_DESCRIPTION: "${{ github.workflow }} / ${{ github.job }}"
60+
DEFAULT_TARGET_URL: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
61+
run: |
62+
## -- Update the commit status --
63+
set -euo pipefail
64+
65+
case "${STATE}" in
66+
pending | success | failure | error) ;;
67+
# The one value of `job.status` that is not a commit status state
68+
cancelled) STATE=failure ;;
69+
*)
70+
echo "::error::Unknown commit status state: '${STATE}'"
71+
exit 1
72+
;;
73+
esac
74+
75+
sha="${SHA:-${GITHUB_SHA}}"
76+
77+
# `workflow_dispatch` takes a branch or a tag, a status needs a commit.
78+
# `--end-of-options` because the ref is free-form text,
79+
# `^{commit}` because an annotated tag resolves to the tag object.
80+
if ! printf '%s' "${sha}" | grep -qE '^[0-9a-f]{40}$'; then
81+
sha=$(git rev-parse --verify --end-of-options "${sha}^{commit}")
82+
fi
83+
84+
gh api \
85+
--method POST \
86+
-H "Accept: application/vnd.github+json" \
87+
-H "X-GitHub-Api-Version: 2022-11-28" \
88+
"repos/${GITHUB_REPOSITORY}/statuses/${sha}" \
89+
-f "state=${STATE}" \
90+
-f "target_url=${TARGET_URL:-${DEFAULT_TARGET_URL}}" \
91+
-f "description=${DESCRIPTION:-${DEFAULT_DESCRIPTION}}" \
92+
-f "context=${CONTEXT}"
93+
shell: bash

0 commit comments

Comments
 (0)