The .rpm we attach to GitHub releases cannot be installed because its header carries no GPG signature. rpm/dnf reject it with:
package header is not signed
Recent RPM (4.20+, Fedora 41 and newer, and RHEL/openSUSE equivalents) enforce header signatures on local package installs by default, so an unsigned package that used to install with a warning now fails outright.
Where it comes from
.github/workflows/prepare-release.yml builds the package and attaches it, with no signing step anywhere in between:
- L212-217:
./gradlew :desktop:packageReleaseRpm (Compose Desktop / jpackage, which does not sign)
- L219-234: renamed to
hammer.rpm
- L252: uploaded as a release artifact
desktop/build.gradle.kts L118-123 sets rpmLicenseType but there is no signing configuration, and Compose's nativeDistributions block does not expose one.
Fix
- Generate a Darkrock Studios RPM signing key (RSA 4096, no expiry or a long one).
- Store the ASCII-armoured private key and its passphrase as repository secrets.
- Add a step after "Rename RPM Artifact" that imports the key and runs
rpmsign --addsign (or rpm --addsign) with %_gpg_name set, then verifies with rpm -K hammer.rpm.
- Publish the public key so users can
rpm --import it, and add the import line to the Linux install docs.
- Consider signing the
.deb the same way while we are in there, since it has the same gap.
The key handling is the part that needs a decision: whether it lives only in GitHub secrets, and who else holds a copy.
Workaround until then
sudo dnf install --nogpgcheck ./hammer.rpm
We should document this on the release page rather than leave users guessing.
Acceptance criteria
rpm -K hammer.rpm on a release artifact reports a good signature.
sudo dnf install ./hammer.rpm succeeds on Fedora (current stable) without --nogpgcheck.
- Public key and the
rpm --import step are documented.
The
.rpmwe attach to GitHub releases cannot be installed because its header carries no GPG signature.rpm/dnfreject it with:Recent RPM (4.20+, Fedora 41 and newer, and RHEL/openSUSE equivalents) enforce header signatures on local package installs by default, so an unsigned package that used to install with a warning now fails outright.
Where it comes from
.github/workflows/prepare-release.ymlbuilds the package and attaches it, with no signing step anywhere in between:./gradlew :desktop:packageReleaseRpm(Compose Desktop / jpackage, which does not sign)hammer.rpmdesktop/build.gradle.ktsL118-123 setsrpmLicenseTypebut there is no signing configuration, and Compose'snativeDistributionsblock does not expose one.Fix
rpmsign --addsign(orrpm --addsign) with%_gpg_nameset, then verifies withrpm -K hammer.rpm.rpm --importit, and add the import line to the Linux install docs..debthe same way while we are in there, since it has the same gap.The key handling is the part that needs a decision: whether it lives only in GitHub secrets, and who else holds a copy.
Workaround until then
We should document this on the release page rather than leave users guessing.
Acceptance criteria
rpm -K hammer.rpmon a release artifact reports a good signature.sudo dnf install ./hammer.rpmsucceeds on Fedora (current stable) without--nogpgcheck.rpm --importstep are documented.