fix(ci): derive OCI publish mode from trigger to end twin-publish race #61
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?
Ports the GOV-13 twin-trigger publish-mode fix into rusty-links' single OCI build workflow, as part of the GOV-15 per-repo rollout.
The build workflow triggered 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. Because a release commit is simultaneously a main push and av*tag push, both events fired, both built the same image, and both raced to overwrite the mutable:latesttag (and 409'd on immutable artifacts). The fix derives the publish MODE from the trigger rather than fromgit describe, so the two runs push DISJOINT tags and never write the same destination.oci-build/get-tags.nuis replaced with the canonical--modeversion that returns a{ mode, train, tag, describe }record: av*tag ref resolves thereleasetrain (publishes only the immutablevX.Y.Z), a main push resolves thelatesttrain (publishes only the rollinglatest), and aworkflow_dispatchresolves a dry-run that builds and prints without mutating the registry.The workflow gains a
workflow_dispatchtrigger withdry_run/simulate_taginputs, a "Resolve publish mode, train and tag" step that derives the mode fromgithub.event_name/github.ref_type, and single-tag build/verify/print steps gated on dry-run. Everything repo-specific is preserved unchanged: the image name, registry/secret wiring, thetype=ghabuild cache, the--iidfiledigest capture, the registry digest-verification step, and the Dockerfile path. On a dry-run the build uses--loadand writes no cache, and the verify step is skipped because nothing was pushed.Verification run locally: YAML parses,
nu-checkon the helper returns true, all four functional modes resolve the expected tag/train (release v9.9.9, latest, dry-run simulate v9.9.9 -> release, dry-run plain -> latest), and both error paths (unknown mode, release with no version) exit non-zero. The pre-commit hook (fmt + full build + tests) passed.The build workflow triggered on push to both `branches: [main]` and `tags: [v*]` and resolved its tag set from `git describe` via `oci-build/get-tags.nu --joined`, which returned `[vX.Y.Z, latest]` on a tagged commit. A release commit is simultaneously a main push and a `v*` tag push, so both events fired, both built the same image, and both raced to overwrite the mutable `:latest` tag (and 409'd on immutable artifacts). Derive the publish MODE from the trigger instead of `git describe`: a `v*` tag ref resolves the `release` train and publishes only the immutable `vX.Y.Z`, a main push resolves the `latest` train and publishes only the rolling `latest`, and a `workflow_dispatch` resolves a dry-run that builds and prints without mutating the registry. The two real triggers now write DISJOINT tags, so the two runs never race for the same destination. `get-tags.nu` is replaced with the canonical `--mode` version returning a `{ mode, train, tag, describe }` record; the workflow gains a `workflow_dispatch` trigger with `dry_run`/`simulate_tag` inputs, a "Resolve publish mode, train and tag" step, and single-tag build/verify/print steps gated on dry-run. The repo's gha build cache, `--iidfile` digest capture, and registry digest verification are preserved unchanged. This ports the GOV-13 fix as part of the GOV-15 per-repo rollout. #GOV-15 #GOV-13