All checks were successful
check / check (push) Successful in 3m0s
The check workflow ran `script/cibuild`, a plain `docker build .`. With a warm layer cache the lint and builder stages replayed instead of running, so a commit could report "Successful in 4s" without being formatted, linted, tested, or built. Squash-merging an already-built branch onto `next` hits exactly that path, so no merge was actually validated. The workflow now writes `.ci-fingerprint` into the build context: the hash of the last commit that touched the context. Any commit that changes code gets a new value, invalidates the `COPY . .` layer of both check stages, and really runs `make fmt-check`, `make lint`, `make test` and `make build`. A docs-only commit leaves it unchanged and still replays from cache in seconds, as `.dockerignore` already intends. The module download layer sits above `COPY . .` and stays cached either way, so this is cheaper than a scoped `--no-cache-filter`. `script/cibuild` is a model script shared across repos and is left untouched. The second half of the problem was that Gitea cancels the in-flight run when a newer commit lands on the same branch and records the cancellation as `failure`, marking commits red that were never tested. That cancellation is unconditional server-side for push events, so the superseding run now rewrites the exact `Has been cancelled` status to `skipped`. Genuine failures are never touched.
64 lines
2.6 KiB
YAML
64 lines
2.6 KiB
YAML
name: check
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- '**'
|
|
|
|
jobs:
|
|
check:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 2024-10-23
|
|
with:
|
|
# The fingerprint step below needs history to find the last commit
|
|
# that touched the Docker build context.
|
|
fetch-depth: 0
|
|
|
|
- name: Neutralize superseded run statuses
|
|
# Gitea cancels the in-flight run when another commit is pushed to the
|
|
# same branch and records the cancellation as `failure`, so a commit
|
|
# that was never tested reads red. The cancellation is unconditional
|
|
# server-side for push events and cannot be disabled from a workflow
|
|
# file, so the superseding run rewrites those statuses to `skipped`.
|
|
# Only the exact cancellation status is touched; a real failure is
|
|
# left alone.
|
|
env:
|
|
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
|
run: |
|
|
set -eu
|
|
api="${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}"
|
|
ctx='check / check (push)'
|
|
for sha in $(git rev-list --max-count=20 "${GITHUB_SHA}^" || true); do
|
|
latest="$(curl -sf "${api}/commits/${sha}/status" | jq -r \
|
|
--arg c "$ctx" \
|
|
'[.statuses[] | select(.context == $c)][0] // empty
|
|
| "\(.status)|\(.description)"')" || continue
|
|
[ "$latest" = 'failure|Has been cancelled' ] || continue
|
|
curl -sf -X POST "${api}/statuses/${sha}" \
|
|
-H "Authorization: token ${GITEA_TOKEN}" \
|
|
-H 'Content-Type: application/json' \
|
|
-d "$(jq -nc --arg c "$ctx" '{
|
|
context: $c,
|
|
state: "skipped",
|
|
description: "Superseded by a newer commit; never tested"
|
|
}')" >/dev/null
|
|
echo "neutralized superseded status on ${sha}"
|
|
done
|
|
|
|
- name: Fingerprint the build context
|
|
# `.dockerignore` keeps docs out of the build context, so a docs-only
|
|
# commit legitimately replays the whole image from cache and stays
|
|
# cheap. Every other commit writes a new fingerprint into the context,
|
|
# which invalidates the `COPY . .` layer of both check stages: a
|
|
# commit that was never linted, formatted-checked, tested and built
|
|
# cannot report success from cache.
|
|
run: |
|
|
set -eu
|
|
fp="$(git log -1 --format=%H -- . ':!*.md' ':!LICENSE' ':!.editorconfig')"
|
|
printf '%s\n' "${fp:-$GITHUB_SHA}" > .ci-fingerprint
|
|
|
|
- name: Build Docker image (runs make check)
|
|
run: script/cibuild
|