Skip to content

Commit 15949f2

Browse files
cscheidclaude
andauthored
fix(release): sign archives in the release job (bd-c6l13j79) (#281)
v0.1.0 dry-run iteration 3 (run 27450999322): the linux gnu legs built the workspace end-to-end (vendored openssl + aws-lc compiled; verify gate and packaging green) and then died on 'apt-get install minisign' — ubuntu-22.04 (jammy) has no minisign package; ubuntu-latest (noble) does, which is why test-suite.yml never hit this. Move signing from the build matrix into the release job: minisign is apt-installable there, the secret key is handled by exactly one job, and signatures cover the exact bytes being published after their artifact round-trip. Build jobs now upload archive + sha256 only; the release job signs every tar.gz (trusted comment = filename) and self-verifies against the install.sh pinned key before publishing. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent 6080bd7 commit 15949f2

1 file changed

Lines changed: 36 additions & 40 deletions

File tree

.github/workflows/release.yml

Lines changed: 36 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -371,48 +371,18 @@ jobs:
371371
$hash = (Get-FileHash -Algorithm SHA256 $archive).Hash.ToLower()
372372
[System.IO.File]::WriteAllText((Join-Path (Get-Location) "$archive.sha256"), "$hash $archive`n")
373373
374-
- name: Install minisign
375-
if: runner.os != 'Windows'
376-
shell: bash
377-
run: |
378-
case "$RUNNER_OS" in
379-
macOS) brew install minisign ;;
380-
Linux) sudo apt-get update && sudo apt-get install -y minisign ;;
381-
esac
382-
383-
# Trusted comment = archive filename: it is part of the signed
384-
# payload, and install.sh compares it against the file they asked
385-
# for, so a signature cannot be replayed from another artifact.
386-
# Skipped for Windows: install.ps1 does not verify signatures
387-
# (SHA-256 only), so the .zip has no .minisig consumer today.
388-
- name: Sign archive (minisign, Ed25519)
389-
if: runner.os != 'Windows'
390-
shell: bash
391-
env:
392-
MINISIGN_SECRET_KEY: ${{ secrets.MINISIGN_SECRET_KEY }}
393-
run: |
394-
ARCHIVE="q2-${{ needs.preflight.outputs.version }}-${{ matrix.platform }}.${{ matrix.ext }}"
395-
key="$(mktemp)"
396-
trap 'rm -f "$key"' EXIT
397-
chmod 600 "$key"
398-
printf '%s\n' "$MINISIGN_SECRET_KEY" > "$key"
399-
minisign -Sm "$ARCHIVE" -s "$key" -t "$ARCHIVE"
400-
# Verify with the public key pinned in install.sh: a mismatch
401-
# between the repo secret and the pinned key fails the release
402-
# here instead of shipping artifacts no installer can verify.
403-
PUBKEY="$(sed -n 's/^MINISIGN_PUBKEY="\(.*\)"$/\1/p' install.sh)"
404-
test -n "$PUBKEY"
405-
minisign -Vm "$ARCHIVE" -P "$PUBKEY"
406-
407-
# Unix archives include a .minisig; the Windows zip does not (no consumer).
374+
# Signing happens in the release job, NOT here: ubuntu-22.04
375+
# (jammy) has no minisign apt package (v0.1.0 dry-run iteration 3,
376+
# run 27450999322), and centralizing the signature step means the
377+
# secret key is touched by exactly one job and signs the exact
378+
# bytes being published, after their artifact round-trip.
408379
- uses: actions/upload-artifact@v7
409380
if: matrix.ext == 'tar.gz'
410381
with:
411382
name: q2-${{ matrix.platform }}
412383
path: |
413384
q2-${{ needs.preflight.outputs.version }}-${{ matrix.platform }}.tar.gz
414385
q2-${{ needs.preflight.outputs.version }}-${{ matrix.platform }}.tar.gz.sha256
415-
q2-${{ needs.preflight.outputs.version }}-${{ matrix.platform }}.tar.gz.minisig
416386
retention-days: 7
417387
if-no-files-found: error
418388

@@ -449,15 +419,12 @@ jobs:
449419
VERSION="${{ needs.preflight.outputs.version }}"
450420
MISSING=()
451421
# "<platform>:<ext>" — Windows ships .zip, the rest .tar.gz.
452-
# The .zip has no .minisig: install.ps1 does not verify signatures.
453422
for entry in linux_amd64:tar.gz linux_arm64:tar.gz \
454423
darwin_amd64:tar.gz darwin_arm64:tar.gz \
455424
windows_amd64:zip; do
456425
platform="${entry%%:*}"; ext="${entry##*:}"
457-
required=("q2-${VERSION}-${platform}.${ext}" \
458-
"q2-${VERSION}-${platform}.${ext}.sha256")
459-
[ "$ext" != "zip" ] && required+=("q2-${VERSION}-${platform}.${ext}.minisig")
460-
for f in "${required[@]}"; do
426+
for f in "q2-${VERSION}-${platform}.${ext}" \
427+
"q2-${VERSION}-${platform}.${ext}.sha256"; do
461428
[ -f "$f" ] || MISSING+=("$f")
462429
done
463430
done
@@ -469,6 +436,35 @@ jobs:
469436
sha256sum -c checksums.sha256
470437
cat checksums.sha256
471438
439+
# Trusted comment = archive filename: it is part of the signed
440+
# payload, and install.sh compares it against the file they asked
441+
# for, so a signature cannot be replayed from another artifact.
442+
# The Windows .zip is not signed: install.ps1 does not verify
443+
# signatures (SHA-256 only), so it has no .minisig consumer today.
444+
# Signing lives here (not in the build matrix) so the secret key
445+
# is handled by one job and signs the exact bytes being published;
446+
# ubuntu-22.04 build runners also have no minisign apt package.
447+
- name: Sign tar.gz archives (minisign, Ed25519)
448+
env:
449+
MINISIGN_SECRET_KEY: ${{ secrets.MINISIGN_SECRET_KEY }}
450+
run: |
451+
sudo apt-get update && sudo apt-get install -y minisign
452+
key="$(mktemp)"
453+
trap 'rm -f "$key"' EXIT
454+
chmod 600 "$key"
455+
printf '%s\n' "$MINISIGN_SECRET_KEY" > "$key"
456+
# Verify with the public key pinned in install.sh: a mismatch
457+
# between the repo secret and the pinned key fails the release
458+
# here instead of shipping artifacts no installer can verify.
459+
PUBKEY="$(sed -n 's/^MINISIGN_PUBKEY="\(.*\)"$/\1/p' install.sh)"
460+
test -n "$PUBKEY"
461+
for ARCHIVE in artifacts/q2-*.tar.gz; do
462+
NAME="$(basename "$ARCHIVE")"
463+
minisign -Sm "$ARCHIVE" -s "$key" -t "$NAME"
464+
minisign -Vm "$ARCHIVE" -P "$PUBKEY"
465+
done
466+
ls -l artifacts/*.minisig
467+
472468
- name: Generate release notes
473469
env:
474470
TAG: ${{ needs.preflight.outputs.tag }}

0 commit comments

Comments
 (0)