Repository navigation
Improve package signing verification in CI workflows - #304
Conversation
Every Dependabot PR touching build-ubuntu.yaml has failed build-package at "Import GPG keys" (all 29 such runs since 2025-09; most recently run 40638632117 for #303): echo '' | gpg --import gpg: no valid OpenPGP data found. GitHub withholds Actions secrets from Dependabot-triggered runs, as it does for fork PRs. The step was guarded only against forks (head.repo.fork == false), and Dependabot's branches are in this repository, so the step ran with an empty key. Decide on signing from whether a PR actually has the key rather than from where its branch lives, and use that one decision both for importing the keys and for the -uc -us of the binary build. The unsigned path is the one fork PRs already take: no ~/.gnupg is created, so dpkg-buildpackage does not try to sign the source package either. Non-PR events (schedule, workflow_dispatch) still always sign, so a missing or empty key keeps failing them loudly. Edited the template and regenerated with `make -C .github/workflows/template`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PvaGRY7auLbAfwNGj21YXd
The previous commit had non-PR events always import the key, so a missing key failed them only through `gpg --import` of an empty string, and nothing checked that the packages actually came out signed. "Decide whether to sign" now makes the decision explicitly: - with the key, always sign; - a PR without it (fork, Dependabot) builds unsigned, as before; - any other build without it fails with an error naming the secret, unless the repository is a fork (asked of the API, as schedule payloads need not carry it; an unclear answer counts as not a fork). When signing, "Import GPG keys" checks that the secret key for DEB_SIGN_KEYID is there, and a new "Check that the packages are signed" step requires a good signature by DEB_SIGN_KEYID on the .dsc and on the source and binary .buildinfo and .changes, since dpkg-buildpackage can skip signing without failing (e.g. when ~/.gnupg is missing). Tested locally with dpkg-buildpackage 1.22.6 and a throwaway key: an unsigned, wrong-key, partially signed, tampered, or missing file fails the check, and a fully signed build passes. The comment on the decision is cut down to two lines. Edited the template and regenerated with `make -C .github/workflows/template`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PvaGRY7auLbAfwNGj21YXd
|
It started with upstream git-annex switching MagicMime from the Haskell
There is no fix for this in the repo yet. It will need either Haskell What this run does confirm for this PR: "Decide whether to sign" chose to sign, "Import GPG keys" imported the secret key and found Generated by Claude Code |
…e-ew7ny7 Brings in #305 (libmagic in the buildenv image) so that this PR's CI runs again now that the image with it is published.
|
With the new buildenv image (#305),
This isn't caused by this PR, which only changes signing steps in No fix exists in this repo beyond #302's mitigation; the real fix is upstream (relaxing the exact comparison, as #294 describes). Update after the one re-run: it failed again, this time in different places, all from the same race: two
#294 measured Generated by Claude Code |
|
No fix for these exists in this repo. Update: Generated by Claude Code |
Summary
This PR refactors the package signing logic in the Ubuntu build workflows to be more explicit and adds verification that built packages are properly signed.
Key Changes
Extracted signing decision logic: Created a new "Decide whether to sign" step that centralizes the logic for determining whether packages should be signed. This replaces inline conditional expressions and makes the decision process more maintainable.
Updated GPG key import step: Changed the conditional from a complex GitHub expression to use the new
steps.signing.outputs.signoutput, making it clearer when GPG keys are imported. Also added verification that the secret key was successfully imported.Updated package build step: Simplified the signing flag logic to use the centralized decision output instead of duplicating the conditional logic.
Added package signature verification: Introduced a new step that verifies all built packages (.dsc, .buildinfo, and .changes files) are signed with the correct key when signing is enabled. This ensures the build process actually produced signed artifacts as expected.
Implementation Details
gpg --verifywith status output parsing to confirm the correct key ID signed each packagehttps://claude.ai/code/session_01PvaGRY7auLbAfwNGj21YXd