@@ -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