diff --git a/docs/changelog.d/add-container-versioning-prereq.infra.md b/docs/changelog.d/add-container-versioning-prereq.infra.md new file mode 100644 index 0000000..8646f29 --- /dev/null +++ b/docs/changelog.d/add-container-versioning-prereq.infra.md @@ -0,0 +1 @@ +Add Mikado prereq for commit-based container tagging scheme to harden-zot-registry chain diff --git a/docs/how-to/how-to.md b/docs/how-to/how-to.md index f863881..36e87ba 100644 --- a/docs/how-to/how-to.md +++ b/docs/how-to/how-to.md @@ -72,6 +72,7 @@ Mikado chain for hardening the zot registry. Track progress with `mise run docs- - [[register-zot-oidc-client]] - [[wire-ci-registry-auth]] - [[enforce-tag-immutability]] +- [[adopt-commit-based-container-tags]] ## Authentik diff --git a/docs/how-to/zot/adopt-commit-based-container-tags.md b/docs/how-to/zot/adopt-commit-based-container-tags.md new file mode 100644 index 0000000..aa42018 --- /dev/null +++ b/docs/how-to/zot/adopt-commit-based-container-tags.md @@ -0,0 +1,90 @@ +--- +title: Adopt Commit-Based Container Tags +modified: 2026-02-20 +status: active +tags: + - how-to + - containers + - ci + - zot +--- + +# Adopt Commit-Based Container Tags + +Replace the current git-tag-triggered container build system with path-based triggers and commit-SHA-based image tags, so that container versions reflect the actual bundled app version and are traceable to exact source commits. + +## Context + +Currently, container builds trigger on git tags matching `-vX.Y.Z`. The version is chosen arbitrarily at release time and is not connected to the upstream app version bundled in the image. This creates several problems: + +- **Version opacity** — `v1.0.0` of a container tells you nothing about which upstream version it bundles +- **Manual release step** — `mise run container-tag-and-release` must be run by hand for every build +- **No automatic rebuilds** — changes to a container's build files don't trigger builds unless someone creates a tag +- **Mutable risk** — version tags can be re-pushed (addressed separately by [[enforce-tag-immutability]], but commit SHAs are inherently unique) + +## New Scheme + +### Triggers + +1. **Merged changes to main** — any push to `main` that modifies files under `containers//` triggers builds for that container +2. **Manual workflow dispatch** — for ad-hoc builds (e.g., testing on a branch). Accepts two inputs: + - `container` (required) — which container to build + - `ref` (optional, string) — the source commit SHA to build, defaulting to `HEAD` of `main` + +Both the Dockerfile and Nix workflows fire for each trigger, each bailing out if the container lacks the relevant build file (same as today). + +### Version Source + +Each container declares the version of its primary bundled app. The mechanism for declaring this (e.g., a `VERSION` file, parsing a Dockerfile `ARG`, or a convention per container) should be determined during implementation. + +### Image Tag Format + +The registry image tag encodes the app version and the exact source commit: + +| Scenario | Dockerfile tag | Nix tag | +|----------|---------------|---------| +| Main branch build | `vX.Y.Z-` and `vX.Y.Z--main` | `vX.Y.Z--nix` and `vX.Y.Z--main-nix` | +| Manual dispatch | `vX.Y.Z-` | `vX.Y.Z--nix` | + +Where: +- `X.Y.Z` is the version of the most relevant bundled app (e.g., miniflux `2.2.5`, navidrome `0.53.3`) +- `` is the short commit SHA of the source tree used for the build + +The `-main` tag indicates a build from the merged main branch, suitable for production deployment. Non-main builds (manual dispatch) omit this suffix. + +### What This Replaces + +- The `container-tag-and-release` mise task is **renamed and repurposed** to `container-build-and-release` — it triggers a manual workflow dispatch instead of creating git tags. It sends the current `HEAD` SHA so that it works from any branch, not just main +- Git tags of the form `-vX.Y.Z` are no longer used to trigger builds +- The `container-list` mise task should be updated to display the new tag format + +## Key Files + +| File | Change | +|------|--------| +| `.forgejo/workflows/build-container.yaml` | Replace tag trigger with path + dispatch triggers; compute version and SHA; push multiple tags | +| `.forgejo/workflows/build-container-nix.yaml` | Same trigger changes; add `-nix` suffix to new tag format | +| `.dagger/src/blumeops_ci/main.py` | Accept SHA parameter; publish with new tag format | +| `mise-tasks/container-build-and-release` | Rename from `container-tag-and-release`; trigger workflow dispatch with current HEAD SHA | +| `mise-tasks/container-list` | Update tag display for new format | +| `docs/how-to/deployment/build-container-image.md` | Document new workflow | + +## Interaction With Other Prereqs + +- **[[enforce-tag-immutability]]** — Commit SHA tags are inherently unique, reducing the scope of immutability enforcement to the `-main` rolling tag (if that is treated as mutable/latest) or eliminating it entirely if `-main` tags are also SHA-qualified (as proposed above) +- **[[wire-ci-registry-auth]]** — Auth changes apply regardless of tagging scheme; no conflict + +## Verification + +- [ ] Push to main modifying `containers/nettest/` triggers both Docker and Nix builds +- [ ] Resulting image tags match `vX.Y.Z-` and `vX.Y.Z--main` format +- [ ] Nix tags have `-nix` suffix +- [ ] Manual workflow dispatch builds with correct tags (no `-main` suffix) +- [ ] `mise run container-list` shows new tag format +- [ ] Existing deployments referencing old tags still work (images not deleted) + +## Related + +- [[harden-zot-registry]] — Parent goal +- [[enforce-tag-immutability]] — Complementary prereq (scope may narrow) +- [[build-container-image]] — How-to doc to update diff --git a/docs/how-to/zot/harden-zot-registry.md b/docs/how-to/zot/harden-zot-registry.md index 7314bed..58d21dd 100644 --- a/docs/how-to/zot/harden-zot-registry.md +++ b/docs/how-to/zot/harden-zot-registry.md @@ -6,6 +6,7 @@ requires: - register-zot-oidc-client - wire-ci-registry-auth - enforce-tag-immutability + - adopt-commit-based-container-tags tags: - how-to - zot @@ -56,4 +57,5 @@ Update `ansible/roles/zot/templates/config.json.j2` to add: - [[register-zot-oidc-client]] — Prereq: register OIDC client in Authentik - [[wire-ci-registry-auth]] — Prereq: update CI push paths with credentials - [[enforce-tag-immutability]] — Prereq: prevent version tag overwrites +- [[adopt-commit-based-container-tags]] — Prereq: commit-SHA-based image tags - [[agent-change-process]] — C2 methodology