From 3b1dab9d6f16915174839c70c5bb8bb2ad831f32 Mon Sep 17 00:00:00 2001 From: skudasov Date: Wed, 21 Oct 2026 17:08:30 +0200 Subject: [PATCH] retry cosign --- .changeset/retry-cosign-sign.md | 7 ++++ actions/build-push-docker-manifest/action.yml | 33 +++++++++++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 .changeset/retry-cosign-sign.md diff --git a/.changeset/retry-cosign-sign.md b/.changeset/retry-cosign-sign.md new file mode 100644 index 000000000..613ad97e8 --- /dev/null +++ b/.changeset/retry-cosign-sign.md @@ -0,0 +1,7 @@ +--- +"build-push-docker-manifest": minor +--- + +feat: retry `cosign sign` on failure (5 attempts, 20s apart by default) to absorb +transient GitHub OIDC/Fulcio errors. Configurable via `cosign-sign-attempts` and +`cosign-sign-retry-interval-seconds`. diff --git a/actions/build-push-docker-manifest/action.yml b/actions/build-push-docker-manifest/action.yml index 54be8cb40..94a4006bc 100644 --- a/actions/build-push-docker-manifest/action.yml +++ b/actions/build-push-docker-manifest/action.yml @@ -26,6 +26,17 @@ inputs: description: "OIDC issuer for cosign" required: false default: "https://token.actions.githubusercontent.com" + cosign-sign-attempts: + required: false + description: | + How many times to attempt `cosign sign` before failing. Absorbs transient + errors such as the GitHub OIDC token endpoint returning a non-JSON body + ("fetching ambient OIDC credentials: invalid character ..."). + default: "5" + cosign-sign-retry-interval-seconds: + required: false + description: "Seconds to wait between `cosign sign` attempts." + default: "20" docker-manifest-sign: required: false description: "Sign the docker manifest" @@ -474,11 +485,29 @@ runs: - name: Sign Docker Manifest using GH OIDC if: inputs.docker-manifest-sign == 'true' - shell: sh + shell: bash env: MANIFEST_NAME_WITH_DIGEST: ${{ steps.inspect-docker-manifest.outputs.manifest-name-with-digest }} - run: cosign sign "${MANIFEST_NAME_WITH_DIGEST}" --yes + ATTEMPTS: ${{ inputs.cosign-sign-attempts }} + INTERVAL: ${{ inputs.cosign-sign-retry-interval-seconds }} + run: | + set -uo pipefail + + # Retry to absorb transient OIDC/Fulcio/Rekor errors. Signing the same + # digest again is safe: it only adds another signature. + for (( attempt = 1; attempt <= ATTEMPTS; attempt++ )); do + if cosign sign "${MANIFEST_NAME_WITH_DIGEST}" --yes; then + exit 0 + fi + if (( attempt < ATTEMPTS )); then + echo "::warning::cosign sign failed (attempt ${attempt}/${ATTEMPTS}); retrying in ${INTERVAL}s..." + sleep "${INTERVAL}" + fi + done + + echo "::error::cosign sign failed after ${ATTEMPTS} attempts for ${MANIFEST_NAME_WITH_DIGEST}" + exit 1 - name: Verify Docker image signature if: