ci: standardize tag management strategy#308
Conversation
Align chat-api with the cloud-api / compose-manager tagging scheme: - build.yml: main branch now pushes :staging (was :latest) + immutable staging-YYYYMMDD-<sha> stamp tag for traceability and rollback history - promote.yml: new workflow — manually promotes :staging → :prod + prod-YYYYMMDD-<sha> + :latest; verifies cosign signature; creates GitHub release; serialized via prod-image-mutation concurrency group - rollback.yml: new workflow — rolls :prod back to any prod-* stamped tag (auto-resolves most recent if not specified); creates audit tag prod-rollback-YYYYMMDD-HHMMSS-from-<sha>; verifies cosign; same concurrency group as promote
|
Note Gemini is unable to generate a review for this pull request due to the file types involved not being currently supported. |
|
PR Review: ci: standardize tag management strategy Solid, well-structured change — confirmation gates, prod-image-mutation concurrency serialization, cosign verification before any prod mutation, digest re-tagging via skopeo copy, and post-mutation digest verification are all done right. A few issues worth addressing before merge. The image is
For a private Docker Hub repo the tags endpoint returns 401,
Fix: authenticate the Hub API (JWT via /v2/users/login with the registry creds), or make curl non-fatal so promotion falls through to the digest-derived suffix, e.g. Minor / suggestions
Otherwise the digest-pinned re-tagging, cosign identity pinning to build.yml@refs/heads/main, and the audit-tag + release trail are well done. Verdict: |
- build.yml: remove auto-generated staging-YYYYMMDD-<sha> stamp tag - promote.yml: replace :staging source with explicit `tag` input (e.g. "0.2.13" or "v0.2.13"); validates the tag exists on Docker Hub before proceeding; promotes that digest to :prod + :latest; no auto-generated prod-YYYYMMDD-<sha> tag - rollback.yml: make target_tag required; validate it exists on Docker Hub; remove auto-resolved prod-* tags and auto-created audit tags; rolls :prod + :latest to the user-specified tag digest - cosign verification now accepts both refs/heads/main and refs/tags/v* since version tags are built from a tag ref, not main
PierreLeGuen
left a comment
There was a problem hiding this comment.
The tag standardization (main→:staging, manual promote→:prod+:latest, rollback reverts both) is internally consistent: workflows parse cleanly, prod mutations are gated by cosign verification on a main-signed digest, and the shared concurrency group serializes promote vs rollback.
One thing to confirm before relying on staging deploys:
.github/workflows/build.yml:40— main now pushes:staginginstead of:latest, but this same workflow still dispatches thedeploy-chat-api-stgdeploy. That downstream playbook lives in the externalcvm-ansible-playbooksrepo and currently resolves:latest(chat_api_stg.yaml:17). If it isn't updated to pull:staging, staging will freeze on the last promoted digest until a manual promote. Can't be verified from this repo — worth confirming the staging playbook references:staging(covered by the test plan's first checkbox).
Optional follow-up:
.github/workflows/promote.yml:55/rollback.yml:69— when no matching source tag is found, the short-sha falls back to a digest-derived 7-char suffix that still satisfies the[0-9a-f]{7}regex but no longer maps to a real git sha. Behavior is correct; only the audit trail loses sha traceability in that edge case.
Checks: all three workflow YAMLs parse cleanly (actionlint / python3 yaml.safe_load, only SC2129 style warnings); grep found no stale :latest references; no promote/rollback tag re-triggers build.yml. Cargo build/tests skipped — CI-only changes.
lloydmak99
left a comment
There was a problem hiding this comment.
Requesting changes. The workflow implementation does not yet match the rollout strategy described in the PR, and it breaks the current staging deploy path:
-
.github/workflows/build.yml:40changes main builds fromlatesttostaging, but the downstream staging playbook currently resolves Docker Hub tagprivate-chat:latestbefore deploying. After this merges, the repository dispatch at the end of the build would redeploy the oldlatestdigest instead of the image just built frommain. Please update the downstream staging deploy to consumestaging, or keep publishing the compatibility tag until that is changed. -
.github/workflows/build.yml:40/:60only publishes one mutable tag for main. The PR body promises:stagingplus an immutablestaging-YYYYMMDD-<sha>stamp tag, but no step creates or copies that stamp tag. Please add the immutable staging tag creation so promotions and audit trails have a stable source. -
.github/workflows/promote.yml:98only copies the selected digest to:prod. The PR body says promotion should also create aprod-YYYYMMDD-<sha>tag and update:latestas a compatibility alias. Without those, rollback/audit cannot target promoted stamps and the existing prod deployment path that useslatestwill not track promotions. -
.github/workflows/rollback.yml:11requires a target tag and.github/workflows/rollback.yml:102only retags:prod. The PR body says rollback can auto-resolve the previous prod digest, creates an audit tag, and creates a GitHub release. Please either implement those behaviors or update the workflow contract/body before merging.
Validation run locally:
git diff --check 06325a39ffccbbd4c5568dc71b434c7f726bed98...HEAD- Verified
/Users/lloyd/Documents/Repos/cvm-ansible-playbooks/playbooks/update/chat_api_stg.yamlcurrently queries Docker Hubprivate-chat:latest.
Summary
Aligns chat-api with the tagging strategy already in use by cloud-api and compose-manager.
Before:
mainpushed:latest; no promotion pipeline; no rollback mechanism; manual semver tags triggered versioned Docker builds.After:
build.yml:mainpushes:staging+ immutablestaging-YYYYMMDD-<sha>stamp tag (exact copy via skopeo from the OCI archive, same as compose-manager).promote.yml(new): manually promotes:staging→:prod+prod-YYYYMMDD-<sha>+:latest. Verifies cosign signature before touching:prod. Serialized withprod-image-mutationconcurrency group. Creates a GitHub release for audit trail.rollback.yml(new): rolls:prodback to anyprod-YYYYMMDD-<sha>tag (auto-resolves most recent different digest if no target given). Verifies cosign. Createsprod-rollback-YYYYMMDD-HHMMSS-from-<sha>audit tag + GitHub release.:latestis kept as a compatibility alias on promotion — the existing ansible-playbooksdeploy_chat_api_prod.ymlplaybook that uses:latestcontinues to work unchanged.Test plan
nearaidev/private-chat:stagingandstaging-YYYYMMDD-<sha>(check build summary)confirm=promote→ confirm:prod,prod-YYYYMMDD-<sha>,:latestall resolve to same digest; GitHub release createdconfirm=ROLLBACK(no target) → confirm auto-resolves previous tag,:produpdated, audit tag and release created🤖 Generated with Claude Code