Files
gitdan-actions/.gitea/workflows
claudeandClaude Sonnet 5 dc1e6317c6 fix(ci): make the v1 push monotonic, not just mutually exclusive
The concurrency group added in af1233f only excludes two release-tag
jobs that are simultaneously Running/Waiting/Blocked
(services/actions/clear_tasks.go:64-80,
models/actions/run_job.go:641-660 at the v1.27.2 tag this instance
runs) -- it has no notion of commit order between jobs that never
overlap. On a 2-slot runner shared across 4 repos, with a
multi-minute selftest gating each release-tag job, two merges landing
close together routinely finish in the opposite order from the pushes
that triggered them: if the newer commit's job completes and exits
first, the older commit's job later finds no live holder in the
group, is not blocked, and force-pushes v1 backward to itself. The
concurrency comment's "never regress it to an older one" and af1233f's
commit message both asserted the opposite -- true of the simultaneous
case the guard covers, false of the staggered one it doesn't, so
authored-false rather than drift.

Added a merge-base check before the push: skip if v1 already points
at this commit or a descendant of it (`--is-ancestor` treats a commit
as its own ancestor, so "at" and "ahead" are the same branch). A v1
that doesn't exist yet, or shares no history with this commit, falls
through to the push -- the guard only ever skips, never fails. Needs
`fetch-depth: 0` on the checkout: actions/checkout's own description
for that value is "all history for all branches and tags", and its
source (dist/index.js: fetchDepth <= 0 selects
getRefSpecForAllHistory, which includes the tags refspec) confirms
tags are fetched as part of that, not gated behind the separate
fetch-tags input -- so refs/tags/v1 and the history behind it are both
guaranteed present locally without a second fetch step.

Rewrote both false claims: the concurrency comment now says what the
group actually bounds (simultaneous competing pushes, not completion
order), and states plainly that the guard below is what makes the
outcome order-independent.

Verified the check's five cases (no tag yet, tag ahead of this
commit, tag behind this commit, tag equal to this commit, unrelated
history) against a real scratch git repo, extracting the exact
condition used in the workflow step -- all five resolved as intended
(skip only when v1 is already at or ahead). The workflow step itself
cannot be exercised outside a real Actions run.

bash scripts/selftest.sh: all 6 suites green (67 prune-cache
assertions, unchanged). shellcheck -x --source-path=scripts
scripts/*.sh: clean -- note this does not cover the inline `run:`
shell in ci.yaml, which shellcheck was never wired to check in this
repo (verified against the CI job itself, which shellchecks only
scripts/*.sh).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UkSjXXtU6JYcN2vPntWhfb
2026-09-22 12:24:27 -05:00
..