fix(ci): derive publish channel from trigger to end 409 race #21

Merged
David merged 3 commits from fix/GOV-14-trigger-derived-publish-channels into main 2026-06-22 19:19:56 +02:00
Owner

Background

The three binary build workflows (build-binary.yml Linux glibc, build-binary-static.yml static musl, build-binary-windows.yml Windows) each trigger on a push to BOTH branches: [main] and tags: [v*]. A release commit is simultaneously a push to main and the v* tag push, so both events fire. Each run resolved its publish tag set from git describe via oci-build/get-tags.nu --joined, which on a tagged commit yields [<version>, latest] for BOTH events. The two runs then raced to DELETE-then-PUT the same immutable <version> generic-package file, producing intermittent 409 package file already exists and red release CI. Tracked as GOV-14; same failure class as CLAUDE-122 / GOV-13.

Fix

Resolve the publish channel from the workflow TRIGGER instead of git describe, so the two events publish DISJOINT channels: a tag push (github.ref_type == 'tag') publishes the immutable <version> channel; a push to main publishes ONLY latest. This removes the concurrent writer on the immutable <version> file. latest still tracks the release commit because the tag sits on the same SHA pushed to main. This is the same minimal trigger-derived change proven in CI on the monkey repo (PR #51); the full forgejo-cli --mode get-tags rewrite is intentionally not introduced here, and oci-build/get-tags.nu is left in place and untouched.

Files changed

  • .forgejo/workflows/build-binary.yml
  • .forgejo/workflows/build-binary-static.yml
  • .forgejo/workflows/build-binary-windows.yml

Each "Get artifact tags" step swaps the ^nu oci-build/get-tags.nu --joined call for trigger-derived logic using github.ref_type / github.ref_name. No downstream publish/print step in these workflows had a release-only-channel conditional, so the resulting channels are exactly <version> on a tag push and latest on a main push. All other behavior (build, sha256 sidecar, DELETE-then-PUT publish, printed URLs) is unchanged.

Verification

just pre-commit passes locally (fmt + clippy + build + tests, 41 passed). Change is YAML-only; no Rust touched.

#GOV-14

## Background The three binary build workflows (`build-binary.yml` Linux glibc, `build-binary-static.yml` static musl, `build-binary-windows.yml` Windows) each trigger on a push to BOTH `branches: [main]` and `tags: [v*]`. A release commit is simultaneously a push to main and the v* tag push, so both events fire. Each run resolved its publish tag set from `git describe` via `oci-build/get-tags.nu --joined`, which on a tagged commit yields `[<version>, latest]` for BOTH events. The two runs then raced to DELETE-then-PUT the same immutable `<version>` generic-package file, producing intermittent `409 package file already exists` and red release CI. Tracked as GOV-14; same failure class as CLAUDE-122 / GOV-13. ## Fix Resolve the publish channel from the workflow TRIGGER instead of `git describe`, so the two events publish DISJOINT channels: a tag push (`github.ref_type == 'tag'`) publishes the immutable `<version>` channel; a push to main publishes ONLY `latest`. This removes the concurrent writer on the immutable `<version>` file. `latest` still tracks the release commit because the tag sits on the same SHA pushed to main. This is the same minimal trigger-derived change proven in CI on the monkey repo (PR #51); the full forgejo-cli `--mode` get-tags rewrite is intentionally not introduced here, and `oci-build/get-tags.nu` is left in place and untouched. ## Files changed - `.forgejo/workflows/build-binary.yml` - `.forgejo/workflows/build-binary-static.yml` - `.forgejo/workflows/build-binary-windows.yml` Each "Get artifact tags" step swaps the `^nu oci-build/get-tags.nu --joined` call for trigger-derived logic using `github.ref_type` / `github.ref_name`. No downstream publish/print step in these workflows had a release-only-channel conditional, so the resulting channels are exactly `<version>` on a tag push and `latest` on a main push. All other behavior (build, sha256 sidecar, DELETE-then-PUT publish, printed URLs) is unchanged. ## Verification `just pre-commit` passes locally (fmt + clippy + build + tests, 41 passed). Change is YAML-only; no Rust touched. #GOV-14
fix(ci): derive publish channel from trigger to end 409 race
All checks were successful
Check / fmt + clippy + build + tests (pull_request) Successful in 40s
5563adbeca
The three binary build workflows (Linux glibc, static musl, Windows) each trigger on a push to both `branches: [main]` and `tags: [v*]`. A release commit is simultaneously a push to main and a v* tag push, so both events fire. Each resolved its publish tag set from `git describe` via `oci-build/get-tags.nu --joined`, which on a tagged commit yields `[<version>, latest]` for BOTH events. The two runs then raced to DELETE-then-PUT the same immutable `<version>` generic-package file, producing intermittent `409 package file already exists` and red release CI (CLAUDE-122 / GOV-13).

Resolve the publish channel from the workflow TRIGGER instead: a tag push (`github.ref_type == 'tag'`) publishes the `<version>` channel; a push to main publishes only `latest`. The two events now write DISJOINT channels, removing the concurrent writer on the immutable `<version>` file. `latest` still tracks the release commit because the tag sits on the same SHA pushed to main. This is the same minimal trigger-derived fix proven in CI on the monkey repo (PR #51); the get-tags.nu script is left in place and untouched.

#GOV-14

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Merge branch 'main' into fix/GOV-14-trigger-derived-publish-channels
All checks were successful
Check / fmt + clippy + build + tests (pull_request) Successful in 46s
0765167cad
Merge branch 'main' into fix/GOV-14-trigger-derived-publish-channels
All checks were successful
Check / fmt + clippy + build + tests (pull_request) Successful in 28s
Create release / Create release from merged PR (pull_request) Has been skipped
105c218d27
David merged commit 4871a95ccd into main 2026-06-22 19:19:56 +02:00
David deleted branch fix/GOV-14-trigger-derived-publish-channels 2026-06-22 19:19:56 +02:00
Commenting is not possible because the repository is archived.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
pandoras-box/forgejo-mcp!21
No description provided.