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

Merged
David merged 1 commit from fix/GOV-14-trigger-derived-publish-channels into main 2026-06-25 10:26:37 +02:00
Owner

Background

Each build-binary workflow (build-binary-linux.yml, build-binary-windows.yml) triggers on 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 generic-package file at the <version> channel, producing intermittent 409 package file already exists and red release CI. This is GOV-13 / CLAUDE-122.

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 <version> channel (github.ref_name), and 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. Mirrors the fix proven in CI on the monkey repo (PR #51).

The change is confined to the Get artifact tags step in each workflow; downstream publish and print steps that iterate the channel list are unchanged. umbra's get-tags.nu only ever emitted <version> and latest, so there are no additional release-only channels to preserve.

Files

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

Verification

just pre-commit passes locally (fmt + clippy + build + tests). The change is YAML-only; no source code touched.

Refs GOV-14, GOV-13, CLAUDE-122.

## Background Each build-binary workflow (`build-binary-linux.yml`, `build-binary-windows.yml`) triggers on `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 generic-package file at the `<version>` channel, producing intermittent `409 package file already exists` and red release CI. This is GOV-13 / CLAUDE-122. ## 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 `<version>` channel (`github.ref_name`), and 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. Mirrors the fix proven in CI on the monkey repo (PR #51). The change is confined to the `Get artifact tags` step in each workflow; downstream publish and print steps that iterate the channel list are unchanged. `umbra`'s `get-tags.nu` only ever emitted `<version>` and `latest`, so there are no additional release-only channels to preserve. ## Files - `.forgejo/workflows/build-binary-linux.yml` - `.forgejo/workflows/build-binary-windows.yml` ## Verification `just pre-commit` passes locally (fmt + clippy + build + tests). The change is YAML-only; no source code touched. Refs GOV-14, GOV-13, CLAUDE-122.
fix(ci): derive publish channel from trigger to end 409 race
All checks were successful
Check / fmt + clippy + build + tests (pull_request) Successful in 39s
Create release / Create release from merged PR (pull_request) Has been skipped
1b1932ec2e
Each build-binary workflow triggers on 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. Both resolved their 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 generic-package file at the <version> channel, producing intermittent 409 package file already exists and red release CI.

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 <version> channel, and 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. Mirrors the fix proven in CI on the monkey repo (PR #51). Applied identically to the Linux and Windows build workflows; downstream publish/print steps are unchanged.

#GOV-14

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
David merged commit 816a9e734b into main 2026-06-25 10:26:37 +02:00
David deleted branch fix/GOV-14-trigger-derived-publish-channels 2026-06-25 10:26:37 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
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/umbra!26
No description provided.