From 3abfb467a2afdb5fc63a37c4388d993c4a773ac7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 4 Nov 2026 17:28:11 +0000 Subject: [PATCH 1/2] chore(deps): update dependency farcloser/limen to v0.25.0 Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .hermetic/hermetic.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.hermetic/hermetic.yaml b/.hermetic/hermetic.yaml index 5e345d46..2e1a96f6 100644 --- a/.hermetic/hermetic.yaml +++ b/.hermetic/hermetic.yaml @@ -18,7 +18,7 @@ registries: packages: # --- farcloser tools (local registry; standard once registered upstream) --- - - name: farcloser/limen@v0.24.0 # renovate: depName=farcloser/limen + - name: farcloser/limen@v0.25.0 # renovate: depName=farcloser/limen registry: local # --- toolchain + binary-release tools (standard registry, aqua-verified) --- - name: mikefarah/yq@v4.54.1 From 3186b4513a802080284c378835a959a06d4107b2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 4 Nov 2026 17:28:38 +0000 Subject: [PATCH 2/2] chore: refresh checksums and converge the limen baseline Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .hermetic/aqua-checksums.json | 20 +++++++------- .limen/just/apple.just | 49 ++++++++++++++++++++++++++++------- .limen/just/release.just | 21 +++++++++++++++ 3 files changed, 70 insertions(+), 20 deletions(-) diff --git a/.hermetic/aqua-checksums.json b/.hermetic/aqua-checksums.json index 31ae92d1..e699bdf1 100644 --- a/.hermetic/aqua-checksums.json +++ b/.hermetic/aqua-checksums.json @@ -66,28 +66,28 @@ "algorithm": "sha256" }, { - "id": "github_release/github.com/farcloser/limen/v0.24.0/limen_0.24.0_darwin_arm64.tar.gz", - "checksum": "BB7F8386488E585FE59F871CD3D5A4F74E8DA17B51118A11FE6FABA1C91E6FEB", + "id": "github_release/github.com/farcloser/limen/v0.25.0/limen_0.25.0_darwin_arm64.tar.gz", + "checksum": "7D2179EEEA49466B7B8EF834C94AF27273CBA1886E798E36894B17A4DD81EAEF", "algorithm": "sha256" }, { - "id": "github_release/github.com/farcloser/limen/v0.24.0/limen_0.24.0_linux_amd64.tar.gz", - "checksum": "8FD7C868E5C26E3E04C2F0F83D0904D271A9D7FD596E8D4303DC9689B8869209", + "id": "github_release/github.com/farcloser/limen/v0.25.0/limen_0.25.0_linux_amd64.tar.gz", + "checksum": "0739BC4C12D7754CB95DA24F4F6143F0DABCB498047A26AB96BD1F619C7F2D05", "algorithm": "sha256" }, { - "id": "github_release/github.com/farcloser/limen/v0.24.0/limen_0.24.0_linux_arm64.tar.gz", - "checksum": "BDC58258E2B6280AFEF8AD7D8965D19B4AC3AB0C741C9FDC126403847F279E04", + "id": "github_release/github.com/farcloser/limen/v0.25.0/limen_0.25.0_linux_arm64.tar.gz", + "checksum": "DD719BB5BCB231B42EA26172B90F91432AE2292EC88EA31752ECE1428A223242", "algorithm": "sha256" }, { - "id": "github_release/github.com/farcloser/limen/v0.24.0/limen_0.24.0_windows_amd64.tar.gz", - "checksum": "9B862D79FCBB33676F2304FDA902A39F7623BB543EB43693F1F8015B2531730B", + "id": "github_release/github.com/farcloser/limen/v0.25.0/limen_0.25.0_windows_amd64.tar.gz", + "checksum": "826533D0573A75F61193F8C41B2156267BD9C2CBF709F3B9C0EC00BF24218675", "algorithm": "sha256" }, { - "id": "github_release/github.com/farcloser/limen/v0.24.0/limen_0.24.0_windows_arm64.tar.gz", - "checksum": "05F751B5F5DB7FDB8544ACC055D9330A6CFDA64897FE31339B210A64C5C1CC49", + "id": "github_release/github.com/farcloser/limen/v0.25.0/limen_0.25.0_windows_arm64.tar.gz", + "checksum": "0610256371832BF1616633F2A50787632CA35E8DBEED479E88B2FC17329DE100", "algorithm": "sha256" }, { diff --git a/.limen/just/apple.just b/.limen/just/apple.just index c9480410..1188c471 100644 --- a/.limen/just/apple.just +++ b/.limen/just/apple.just @@ -63,8 +63,8 @@ apple-verify-notarized bundle: echo "apple-verify-notarized: $bundle carries a valid stapled ticket" # Submit the signed bundle to Apple and staple the ticket. The verdict is -# notarytool's own "status: Accepted": --wait's exit status is not it. Without -# an identity (a local build) there is nothing to notarize and the recipe says +# notarytool's own "status: Accepted", never an exit status. Without an +# identity (a local build) there is nothing to notarize and the recipe says # so; with one and no credentials it fails, since a Developer ID build that # leaves here unnotarized would be refused on every install. [doc('Notarize a signed bundle with notarytool and staple the ticket')] @@ -84,17 +84,46 @@ apple-notarize bundle: rm -f "$archive" ditto -c -k --sequesterRsrc --keepParent "$bundle" "$archive" key=(--key "${APPLE_NOTARY_KEY:?}" --key-id "${APPLE_NOTARY_KEY_ID:?}" --issuer "${APPLE_NOTARY_ISSUER_ID:?}") - submission=$(xcrun notarytool submit "$archive" --wait "${key[@]}" 2>&1 | tee /dev/stderr) || true + # Submit, wait and the verdict are separate calls, each retried on its + # own: a connection that drops during the wait loses the verdict on an + # upload Apple already holds. Only a submit that exits 0 has finished its + # upload, so a failed one is submitted again; once one has, its id is + # waited on and asked about, never submitted again. + for attempt in 1 2 3; do + submission=$(xcrun notarytool submit "$archive" --no-wait "${key[@]}" 2>&1 | tee /dev/stderr) && break + [ "$attempt" -lt 3 ] || { echo "apple-notarize: $archive could not be submitted" >&2; exit 1; } + sleep $((attempt * 15)) + done id=$(printf '%s\n' "$submission" | sed -n 's/^ *id: \([0-9a-f-]*\)$/\1/p' | head -n 1) - if ! printf '%s\n' "$submission" | grep -q '^ *status: Accepted$'; then - echo "apple-notarize: Apple did not accept the submission${id:+ $id}" >&2 - [ -z "$id" ] || xcrun notarytool log "$id" "${key[@]}" >&2 || true + [ -n "$id" ] || { echo "apple-notarize: notarytool submit returned no submission id" >&2; exit 1; } + # A "status:" line is the end of processing, whatever wait exits with; + # anything else is a wait cut short, resumed on the same id. + for attempt in 1 2 3 4 5; do + waited=$(xcrun notarytool wait "$id" "${key[@]}" 2>&1 | tee /dev/stderr) && break + printf '%s\n' "$waited" | grep -q '^ *status: ' && break + [ "$attempt" -lt 5 ] || { echo "apple-notarize: submission $id did not finish processing" >&2; exit 1; } + sleep $((attempt * 15)) + done + for attempt in 1 2 3; do + info=$(xcrun notarytool info "$id" "${key[@]}" 2>&1 | tee /dev/stderr) && break + [ "$attempt" -lt 3 ] || { echo "apple-notarize: the status of submission $id could not be read" >&2; exit 1; } + sleep $((attempt * 10)) + done + if ! printf '%s\n' "$info" | grep -q '^ *status: Accepted$'; then + echo "apple-notarize: Apple did not accept the submission $id" >&2 + xcrun notarytool log "$id" "${key[@]}" >&2 || true exit 1 fi - # staple validates what it writes; a second validate only asks the - # network again. - xcrun stapler staple "$bundle" - echo "apple-notarize: $bundle notarized (submission ${id:-?}), ticket stapled" + # staple fetches the ticket from Apple's ticket service and validates + # what it writes: a connection that drops on the runner fails it with the + # submission accepted, so it is tried five times, further apart each time, + # before the release stops. + for attempt in 1 2 3 4 5; do + xcrun stapler staple "$bundle" && break + [ "$attempt" -lt 5 ] || { echo "apple-notarize: the ticket for submission $id could not be stapled" >&2; exit 1; } + sleep $((attempt * 15)) + done + echo "apple-notarize: $bundle notarized (submission $id), ticket stapled" # ditto, not zip: the archiver that keeps a bundle's extended attributes and # code signature intact, so what a user unzips is what was signed. diff --git a/.limen/just/release.just b/.limen/just/release.just index ddc5db62..f8f68e15 100644 --- a/.limen/just/release.just +++ b/.limen/just/release.just @@ -218,3 +218,24 @@ release *args: fi ;; esac + +# goreleaser's sign command (.release-go.yaml `signs:`): one keyless +# signature over a release file, in CI. cosign gives up on Fulcio at the first +# dropped connection and retries Rekor once, so a reset on the runner fails +# the release with nothing wrong in it. Every attempt is a fresh key, a fresh +# certificate and a new log entry, so one that failed halfway cannot collide +# with the next; its partial bundle is removed first. +[doc("Sign a release file keyless with cosign into a Sigstore bundle (goreleaser's sign command)")] +[positional-arguments] +release-sign file bundle: + #!/usr/bin/env bash + set -euo pipefail + file="$1" bundle="$2" + for attempt in 1 2 3; do + rm -f "$bundle" + if cosign sign-blob --yes --bundle "$bundle" "$file" && [ -s "$bundle" ]; then + exit 0 + fi + [ "$attempt" -lt 3 ] || { echo "release-sign: $file could not be signed" >&2; exit 1; } + sleep $((attempt * 15)) + done