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

Merged
David merged 2 commits from fix/GOV-14-trigger-derived-publish-channels into main 2026-06-21 15:18:58 +02:00
Owner

What

Resolve the generic-package publish channel in .forgejo/workflows/build-package.yml from the workflow trigger (github.ref_type) instead of from git describe, so the two events a release commit fires publish disjoint channels.

Why (the race, GOV-14)

A release commit is simultaneously a push to main and a push of the v* tag on the same SHA, so the Build Linux package workflow fires twice. Both runs computed the package version from oci-build/get-version.nu, which collapses vX.Y.Z-0-g<sha> to a bare X.Y.Z on the exact tag commit (with fetch-depth: 0, the main-push run sees the tag on HEAD too). Both events therefore computed the identical X.Y.Z and raced to write the SAME immutable pinned generic-package files at api/packages/<owner>/generic/vervain-agent/<version>/..., producing intermittent 409 file already exists and red release CI. The pre-existing 409-tolerance only masked the failure; it did not remove the race.

The fix

Gate the publish on github.ref_type:

  • tag push (ref_type == "tag") publishes ONLY the immutable pinned X.Y.Z channel.
  • push to main publishes ONLY the moving stable channel.

The channels are now disjoint per event, so the two runs never touch the same file. stable still tracks the release commit because the v* tag sits on the same SHA pushed to main. This mirrors the trigger-derived fix proven in CI on the monkey repo (PR #51) under GOV-13 / CLAUDE-122; the only adaptation is the moving channel here is named stable (not latest), and there is no get-tags.nu; the channel logic lives inline in the upload step.

YAML-only. No source code changed. upload_immutable / upload_moving helpers are preserved unchanged.

Verification

just pre-commit (the full Docker fmt + clippy + build + test suite, run by the pre-commit hook) passed green on the committed change.

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

## What Resolve the generic-package publish channel in `.forgejo/workflows/build-package.yml` from the workflow trigger (`github.ref_type`) instead of from `git describe`, so the two events a release commit fires publish disjoint channels. ## Why (the race, GOV-14) A release commit is simultaneously a push to `main` and a push of the `v*` tag on the same SHA, so the `Build Linux package` workflow fires twice. Both runs computed the package version from `oci-build/get-version.nu`, which collapses `vX.Y.Z-0-g<sha>` to a bare `X.Y.Z` on the exact tag commit (with `fetch-depth: 0`, the main-push run sees the tag on HEAD too). Both events therefore computed the identical `X.Y.Z` and raced to write the SAME immutable pinned generic-package files at `api/packages/<owner>/generic/vervain-agent/<version>/...`, producing intermittent `409 file already exists` and red release CI. The pre-existing 409-tolerance only masked the failure; it did not remove the race. ## The fix Gate the publish on `github.ref_type`: - tag push (`ref_type == "tag"`) publishes ONLY the immutable pinned `X.Y.Z` channel. - push to main publishes ONLY the moving `stable` channel. The channels are now disjoint per event, so the two runs never touch the same file. `stable` still tracks the release commit because the `v*` tag sits on the same SHA pushed to main. This mirrors the trigger-derived fix proven in CI on the `monkey` repo (PR #51) under GOV-13 / CLAUDE-122; the only adaptation is the moving channel here is named `stable` (not `latest`), and there is no `get-tags.nu`; the channel logic lives inline in the upload step. YAML-only. No source code changed. `upload_immutable` / `upload_moving` helpers are preserved unchanged. ## Verification `just pre-commit` (the full Docker fmt + clippy + build + test suite, run by the pre-commit hook) passed green on the committed change. Refs GOV-14, GOV-13, CLAUDE-122.
fix(ci): derive publish channel from trigger to end 409 race
All checks were successful
Check / clippy + fmt + tests (pull_request) Successful in 3m50s
2e8fc0bbb1
A release commit is simultaneously a push to `main` and a push of the `v*` tag on the same SHA, so the build-package workflow fires twice. Both runs resolved the package version from `git describe` (via `oci-build/get-version.nu`), which collapses `vX.Y.Z-0-g<sha>` to a bare `X.Y.Z` on the exact tag commit. Both events therefore computed the identical `X.Y.Z` and raced to write the SAME immutable pinned generic-package files, producing intermittent HTTP 409 ("file already exists") and red release CI. The existing 409-tolerance only masked the failure on the immutable channel.

Resolve the publish channel from the workflow trigger (`github.ref_type`) so the two events publish DISJOINT channels: a tag push publishes the immutable pinned `X.Y.Z`; a push to main publishes ONLY the moving `stable`. The `stable` channel still tracks the release commit because the `v*` tag sits on the same SHA pushed to main. No source code changed; this is a YAML-only fix to the upload step.

#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 + tests (pull_request) Successful in 16m53s
Create release / Create release from merged PR (pull_request) Has been skipped
7373767031
David merged commit 765bfcf175 into main 2026-06-21 15:18:58 +02:00
David deleted branch fix/GOV-14-trigger-derived-publish-channels 2026-06-21 15:18:58 +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
psa-systems/vervain-agent!69
No description provided.