diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 9f01b875..866f4476 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -208,9 +208,19 @@ jobs: run: | while IFS= read -r image_tag; do [[ -n "${image_tag}" ]] || continue - docker buildx imagetools create \ - --tag "${TCR_IMAGE_NAME}:${image_tag}" \ - "${GHCR_IMAGE_NAME}:${image_tag}" + for attempt in 1 2 3; do + if docker buildx imagetools create \ + --tag "${TCR_IMAGE_NAME}:${image_tag}" \ + "${GHCR_IMAGE_NAME}:${image_tag}"; then + break + fi + if [[ "${attempt}" -eq 3 ]]; then + echo "Failed to mirror ${image_tag} after ${attempt} attempts" >&2 + exit 1 + fi + echo "Mirror attempt ${attempt} failed for ${image_tag}; retrying" >&2 + sleep "$((attempt * 15))" + done done <<< "${MIRROR_TAGS}" - name: Verify mirrored anonymous image access diff --git a/scripts/docker-release.test.mjs b/scripts/docker-release.test.mjs index 0e6ecea0..4edb0cd0 100644 --- a/scripts/docker-release.test.mjs +++ b/scripts/docker-release.test.mjs @@ -89,6 +89,9 @@ describe("Docker release contract", () => { expect(workflow).toContain('docker buildx imagetools create \\'); expect(workflow).toContain('--tag "${TCR_IMAGE_NAME}:${image_tag}"'); expect(workflow).toContain('"${GHCR_IMAGE_NAME}:${image_tag}"'); + expect(workflow).toContain("for attempt in 1 2 3; do"); + expect(workflow).toContain('Failed to mirror ${image_tag} after ${attempt} attempts'); + expect(workflow).toContain('sleep "$((attempt * 15))"'); expect(workflow).not.toContain('echo "${TCR_IMAGE_NAME}:${RELEASE_TAG}"'); expect(workflow).toContain('docker logout ccr.ccs.tencentyun.com'); expect(workflow).toContain('test "${ghcr_digest}" = "${tcr_digest}"');