From d424833e61443f5cb12be067ef2927c2ff2507ce Mon Sep 17 00:00:00 2001 From: JorisJonkers Agent Date: Thu, 9 Jul 2026 17:47:55 +0000 Subject: [PATCH] fix: use deploy- tag prefix and fix oras resolve for artifact digest Two issues in publish.sh: 1. Deploy artifacts were pushed to the same OCI tag as container images (e.g. ghcr.io//agents-ui:v0.18.11), causing the deploy artifact push to overwrite the container image. Changed to deploy- tag (e.g. deploy-v0.18.11) so both coexist in the same GHCR repository. 2. oras 1.2.3 does not support --digest-file. Removed that flag and instead resolve the digest via `oras resolve` after push. --- actions/deploy-artifact/publish.sh | 35 +++++++++++++++--------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/actions/deploy-artifact/publish.sh b/actions/deploy-artifact/publish.sh index 23ddbc4..c43aa1f 100755 --- a/actions/deploy-artifact/publish.sh +++ b/actions/deploy-artifact/publish.sh @@ -46,7 +46,11 @@ main() { local artifact_version="${ARTIFACT_VERSION:?ARTIFACT_VERSION is required}" local render_hash="${RENDER_HASH:?RENDER_HASH is required}" local artifact_ref - artifact_ref="ghcr.io/jorisjonkers-dev/${artifact_name}:${artifact_version}" + # Use a "deploy-" tag prefix to avoid colliding with the container image tag. + # Container images are pushed as ghcr.io//: by + # container-publish.yml; deploy artifacts use ghcr.io//:deploy- + # so they coexist in the same GHCR repository without overwriting each other. + artifact_ref="ghcr.io/jorisjonkers-dev/${artifact_name}:deploy-${artifact_version}" # (0) Authenticate to GHCR so oras push and cosign sign can write packages. # GITHUB_TOKEN is always injected by GitHub Actions (packages: write on the @@ -72,13 +76,10 @@ main() { local artifact_digest - # (2) Check if a deploy artifact tag already exists (idempotent publish). - # Use --media-type to distinguish deploy artifacts from container images that - # share the same tag (container images have a different manifest media type - # and will not match, preventing false-positive idempotency hits). - if oras manifest fetch "$artifact_ref" \ - --media-type "application/vnd.jorisjonkers.deployment.artifact.v1+tar" \ - > /dev/null 2>&1; then + # (2) Check if the deploy artifact tag already exists (idempotent publish). + # The "deploy-" tag prefix (e.g. "deploy-v1.2.3") ensures this tag can only + # ever point to a deploy artifact — container images use a plain version tag. + if oras manifest fetch "$artifact_ref" > /dev/null 2>&1; then # Deploy artifact tag exists: verify render-hash; fail on mismatch. local existing_digest existing_digest=$(oras resolve "$artifact_ref" 2>/dev/null) @@ -102,21 +103,19 @@ main() { warn "artifact already exists with matching render-hash; skipping push (idempotent)" else # (3) Push artifact + # oras 1.x does not support --digest-file; capture digest via oras resolve + # after push, which also serves as the post-push verification (step 4). oras push "$artifact_ref" \ --artifact-type "application/vnd.jorisjonkers.deployment.artifact.v1+tar" \ - artifact.tar \ - --digest-file pushed.digest + artifact.tar + # (4) Resolve digest after push (also detects tag-move races) local pushed_digest - pushed_digest=$(cat pushed.digest) - - # (4) Post-push resolve verification (detect tag-move race) - local resolved_digest - resolved_digest=$(oras resolve "$artifact_ref" 2>/dev/null) - if [[ "$resolved_digest" != "$pushed_digest" ]]; then + pushed_digest=$(oras resolve "$artifact_ref" 2>/dev/null) + if [[ -z "$pushed_digest" || "$pushed_digest" != sha256:* ]]; then emit_gate_summary "deploy-artifact" "Deploy Artifact" "fail" \ - "publish-race-tag-moved" "none" - fail "E_PUBLISH_RACE_TAG_MOVED: pushed=${pushed_digest} resolved=${resolved_digest} (concurrent push moved tag)" + "publish-resolve-failed" "none" + fail "E_PUBLISH_RESOLVE_FAILED: could not resolve digest for ${artifact_ref} after push" fi artifact_digest="$pushed_digest"