ci: make the docker duplicate check able to see tags

Pushing master and a release tag fires two workflow runs, and `should-build`
exists to keep only one of them building: a branch run skips when its commit
is already tagged. It never worked — `actions/checkout` does not fetch tags
(`fetch-tags` defaults to false, and `fetch-depth` does not imply it), so
`git tag --points-at "$GITHUB_SHA"` came up empty and the master run built the
same commit the tag run was building: two ~6 minute docker builds pushing the
same image, for v1.9.0 and again for v1.9.1.

The check step now fetches the tags itself, immediately before deciding, so
the view is as fresh as it can be. Reproduced and fixed against this repo: a
clone made the way the action makes it (`--no-tags`) reports "NO TAG ->
build=true (duplicate build!)" for the tagged v1.9.1 commit, and the same
clone after the step's `git fetch --tags --force origin` reports
"tag(s): v1.9.1 -> build=false (skip)".

A tag pushed *after* the branch run started cannot be anticipated, so the
release flow is documented as one push (`git push origin master vX.Y.Z`) in
both the workflow and AGENTS.md; pushing master first is exactly what made
today's pair build twice.

`cargo fmt --check`, `clippy`, the test suite and the workflow's YAML parse
are all clean (workflow/docs only, no Rust changes).
This commit is contained in:
2026-09-21 15:38:44 +08:00
parent d60f849864
commit f8796913e5
2 changed files with 16 additions and 2 deletions
+15 -1
View File
@@ -39,7 +39,10 @@ concurrency:
jobs:
# A tag push and a branch push to the same commit fire two workflow runs;
# build only once. Tag runs always build; master runs build only when the
# pushed commit is not already tagged (the tag run covers it).
# pushed commit is not already tagged (the tag run covers it) — which needs
# the tags to be present and to have been pushed by the time this runs, so
# `docker.yml`'s check step fetches them and the release flow pushes both
# refs together.
should-build:
runs-on: ubuntu-latest
timeout-minutes: 10
@@ -73,6 +76,17 @@ jobs:
- id: check
shell: bash
run: |
if [ "$GITHUB_REF_TYPE" = "branch" ]; then
# The check below is only as good as the tags in this clone, and
# `actions/checkout` does not fetch them (fetch-tags defaults to
# false, and fetch-depth does not imply it) — which is why the
# master run used to build the very commit the tag run was building
# in parallel. Fetched here, right before the decision, so a tag
# pushed moments ago is seen too. A tag pushed *after* this run
# started cannot be anticipated: push the branch and the tag
# together (`git push origin master v1.9.1`) or the tag first.
git fetch --tags --force --quiet origin
fi
if [ "$GITHUB_REF_TYPE" = "branch" ] && git tag --points-at "$GITHUB_SHA" | grep -q .; then
echo "commit already tagged; the tag run builds the image"
echo "build=false" >> "$GITHUB_OUTPUT"