Derive OCI publish mode from trigger to stop twin-publish race (GOV-15) #382
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/GOV-15-twin-trigger-publish-mode"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Ports the GOV-13 twin-trigger publish-mode fix into mokosh-server's
.forgejo/workflows/build-oci-image.ymland itsoci-build/get-tags.nuhelper. Part of the GOV-15 per-repo rollout.Why
The build workflow triggers on push to both
branches: [main]andtags: [v*]and resolved its tag set fromgit describeviaoci-build/get-tags.nu --joined, which returned[vX.Y.Z, latest]on a tagged commit. A release commit is simultaneously a main push and av*tag push, so both events fired, both built the same image, and both raced to overwrite the mutable:latesttag (and 409'd on immutable version artifacts). This is the race tracked as governance GOV-13 / claude-run CLAUDE-122.How
Derive the publish mode from the workflow trigger rather than from
git describe: a tag ref resolves to thereleasetrain and publishes only:vX.Y.Z, a main push resolves to thelatesttrain and publishes only:latest, and a manualworkflow_dispatchresolves to adry-runthat builds and prints but mutates nothing. The two push runs now write disjoint destinations and never race.oci-build/get-tags.nuis replaced with the canonical--modeversion returning a{ mode, train, tag, describe }record; the workflow gainsworkflow_dispatchdry_run/simulate_taginputs, a resolve step that maps the trigger to a single mode/train/tag, a dry-run-gated build-and-push (--loadwith no cache export on dry-run,--push --cache-tootherwise), and a dry-run-aware URL print.Scope
Minimal port: the image name, registry/secret wiring, build-args, Dockerfile path, and the
type=ghacache strategy are unchanged. Only the trigger-derived publish-mode logic changed.Verification
Local nu/yaml gate per the GOV-15 recipe, all green: YAML parses,
nu-checkon the helper returnstrue, the four functional modes resolve the expected tags (release->v9.9.9,latest->latest,dry-run --simulate-tag v9.9.9-> release/v9.9.9,dry-run-> latest/latest), and both error paths (--mode bogus,--mode releasewith no version) exit non-zero. The repo'sE2E (staging)CI check is always-red by design (staging/prod split) and is not a gate here.