Skip to content

Commit 50724fd

Browse files
authored
fix(ci): stop publish failing on existing immutable edge tags (#3259)
1 parent 62fb33a commit 50724fd

1 file changed

Lines changed: 55 additions & 24 deletions

File tree

‎.github/workflows/publish.yml‎

Lines changed: 55 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -564,8 +564,22 @@ jobs:
564564
EXISTING_SHA="${REMOTE_PEELED:-${REMOTE_RAW}}"
565565
SHORT_SHA=$(echo "$EXISTING_SHA" | head -c 8)
566566
567-
# Fail-fast on wrong-target. A wrong-target tag means
568-
# create-git-tag would hard-fail 20-40 minutes later after
567+
# Auto-publish (create_edge_docker_tag=true) runs on every push
568+
# to master, but component versions only change when a human
569+
# bumps them. So the same immutable tag (e.g. server-0.8.1-edge.1)
570+
# is re-seen on every run after the one that first created it.
571+
# That is the expected steady state, not an error: the version
572+
# is already released. The run still refreshes the rolling :edge
573+
# Docker image; it just skips the versioned git tag / crate /
574+
# :version manifest for that component. An existing tag here - at
575+
# ANY commit - is therefore informational, never fatal.
576+
# WRONG_TARGET_TAGS stays empty in this mode so the fail-fast
577+
# exit 1 below cannot trigger.
578+
if [ "${{ inputs.create_edge_docker_tag }}" = "true" ]; then
579+
echo "ℹ️ $NAME: $TAG already exists at $SHORT_SHA - already released, run will refresh :edge only"
580+
echo "| $NAME | $VERSION | $TAG | ℹ️ Already released ($SHORT_SHA) - :edge refresh only |" >> $GITHUB_STEP_SUMMARY
581+
# Fail-fast on wrong-target for MANUAL publish. A wrong-target tag
582+
# means create-git-tag would hard-fail 20-40 minutes later after
569583
# publishing artifacts to crates.io / PyPI / npm / Maven /
570584
# NuGet / DockerHub. Catching it at check-tags converts that
571585
# into a fast, cheap failure at the top of the run.
@@ -579,7 +593,7 @@ jobs:
579593
# manually or run a follow-up without skip_tag_creation to
580594
# converge. The fail-fast exit 1 below is gated on
581595
# skip_tag_creation != true.
582-
if [ "$EXISTING_SHA" != "${{ needs.validate.outputs.commit }}" ]; then
596+
elif [ "$EXISTING_SHA" != "${{ needs.validate.outputs.commit }}" ]; then
583597
WRONG_TARGET_TAGS+=("$TAG|$SHORT_SHA")
584598
if [ "${{ inputs.skip_tag_creation }}" = "true" ]; then
585599
echo "⚠️ Tag exists on remote at WRONG target: $TAG (points to $SHORT_SHA, not enforced: skip_tag_creation=true)"
@@ -879,6 +893,19 @@ jobs:
879893
SHOULD_TAG=false
880894
fi
881895
896+
# Git tags are immutable. A component version is bumped by a human;
897+
# auto-publish then re-runs on every subsequent master push with that
898+
# same version until the next bump. Once the tag exists the versioned
899+
# release (git tag + :version manifest) is already done - this run
900+
# only refreshes the rolling :edge image. Querying the remote (not the
901+
# shallow local clone) so this agrees with create-git-tag's own
902+
# authoritative ls-remote check.
903+
if [ "$SHOULD_TAG" = "true" ] && [ -n "$TAG" ] \
904+
&& git ls-remote --tags --exit-code origin "refs/tags/${TAG}" >/dev/null 2>&1; then
905+
echo "ℹ️ $TAG already exists on remote - versioned release already done, refreshing :edge only"
906+
SHOULD_TAG=false
907+
fi
908+
882909
{
883910
echo "version=$VERSION"
884911
echo "tag=$TAG"
@@ -924,59 +951,63 @@ jobs:
924951
925952
- name: Create and push manifest
926953
working-directory: ${{ runner.temp }}/digests
954+
env:
955+
SHOULD_TAG: ${{ steps.ver.outputs.should_tag }}
927956
run: |
928957
IMAGE="${{ steps.config.outputs.image }}"
929958
VERSION="${{ steps.ver.outputs.version }}"
930959
931960
echo "Creating manifests for $IMAGE from digests:"
932961
ls -la
933962
934-
# Create :edge tag if requested (for auto-publish from post-merge)
935963
if [ "${{ inputs.create_edge_docker_tag }}" = "true" ]; then
964+
# Auto-publish: :edge is the rolling tag and is ALWAYS refreshed.
936965
docker buildx imagetools create \
937966
-t "${IMAGE}:edge" \
938967
$(printf "${IMAGE}@sha256:%s " *)
939968
echo "✅ Pushed manifest: ${IMAGE}:edge"
940-
fi
941969
942-
# Create versioned tag
943-
# When called from auto-publish (create_edge_docker_tag=true), only create
944-
# versioned tag for pre-release versions to match original post-merge behavior.
945-
# Manual publish always creates versioned tag.
946-
if [ "${{ inputs.create_edge_docker_tag }}" = "true" ]; then
947-
if [[ "$VERSION" =~ -(edge|rc) ]]; then
970+
# The versioned :version manifest is part of the immutable release
971+
# and ships only alongside a new git tag. should_tag is false when
972+
# the version is stable (versioned release is manual-only) OR when
973+
# the tag already exists (already released). In both cases this run
974+
# refreshes :edge and nothing else.
975+
if [ "$SHOULD_TAG" = "true" ]; then
948976
docker buildx imagetools create \
949977
-t "${IMAGE}:${VERSION}" \
950978
$(printf "${IMAGE}@sha256:%s " *)
951979
echo "✅ Pushed manifest: ${IMAGE}:${VERSION}"
952980
else
953-
echo "ℹ️ Skipping versioned tag for stable version in auto-publish mode"
981+
echo "ℹ️ should_tag=false - :edge refreshed, skipping versioned :${VERSION} manifest"
954982
fi
955983
else
984+
# Manual publish: always push the versioned manifest, plus :latest
985+
# for stable (non edge/rc) releases.
956986
docker buildx imagetools create \
957987
-t "${IMAGE}:${VERSION}" \
958988
$(printf "${IMAGE}@sha256:%s " *)
959989
echo "✅ Pushed manifest: ${IMAGE}:${VERSION}"
960-
fi
961990
962-
# Create :latest for stable releases (not edge/rc)
963-
# Only create :latest in manual publish mode - auto-publish should never update :latest
964-
if [ "${{ inputs.create_edge_docker_tag }}" != "true" ] && [[ ! "$VERSION" =~ -(edge|rc) ]]; then
965-
echo "Creating 'latest' manifest"
966-
docker buildx imagetools create \
967-
-t "${IMAGE}:latest" \
968-
$(printf "${IMAGE}@sha256:%s " *)
969-
echo "✅ Pushed manifest: ${IMAGE}:latest"
991+
if [[ ! "$VERSION" =~ -(edge|rc) ]]; then
992+
echo "Creating 'latest' manifest"
993+
docker buildx imagetools create \
994+
-t "${IMAGE}:latest" \
995+
$(printf "${IMAGE}@sha256:%s " *)
996+
echo "✅ Pushed manifest: ${IMAGE}:latest"
997+
fi
970998
fi
971999
9721000
- name: Inspect manifest
1001+
env:
1002+
SHOULD_TAG: ${{ steps.ver.outputs.should_tag }}
9731003
run: |
9741004
IMAGE="${{ steps.config.outputs.image }}"
9751005
VERSION="${{ steps.ver.outputs.version }}"
9761006
977-
# In auto-publish mode with stable version, we only pushed :edge
978-
if [ "${{ inputs.create_edge_docker_tag }}" = "true" ] && [[ ! "$VERSION" =~ -(edge|rc) ]]; then
979-
echo "Inspecting :edge manifest (versioned tag was skipped for stable version)"
1007+
# Auto-publish pushed :version only when should_tag was true; in
1008+
# every other auto-publish case (:edge-only) inspect :edge instead.
1009+
if [ "${{ inputs.create_edge_docker_tag }}" = "true" ] && [ "$SHOULD_TAG" != "true" ]; then
1010+
echo "Inspecting :edge manifest (versioned manifest was skipped: should_tag=false)"
9801011
docker buildx imagetools inspect "${IMAGE}:edge"
9811012
else
9821013
docker buildx imagetools inspect "${IMAGE}:${VERSION}"

0 commit comments

Comments
 (0)