Skip to content

fix(release): Generate and include Sparkle EdDSA signatures in appcast#109

Merged
eyelock merged 1 commit into
mainfrom
worktree-fix-sparkle-signing
Apr 12, 2026
Merged

fix(release): Generate and include Sparkle EdDSA signatures in appcast#109
eyelock merged 1 commit into
mainfrom
worktree-fix-sparkle-signing

Conversation

@eyelock
Copy link
Copy Markdown
Owner

@eyelock eyelock commented Apr 12, 2026

Summary

  • Adds a "Sign zip for Sparkle" step to release.yml that runs sign_update with the SPARKLE_PRIVATE_KEY secret and uploads TermQ-{VERSION}.zip.sig as a release asset
  • Updates generate-appcast.sh to fetch the .zip.sig asset from the GitHub release and include sparkle:edSignature in each appcast <enclosure> element

Root cause

The app has SUPublicEDKey configured in Info.plist, so Sparkle requires a valid EdDSA signature on every update. The release workflow was signing the app bundle with Apple codesign but never generating a Sparkle EdDSA signature for the ZIP. The appcast had no sparkle:edSignature attribute, causing Sparkle to show "The update is improperly signed and could not be validated."

How it works after this fix

  1. release.yml builds the zip, then: echo "$SPARKLE_PRIVATE_KEY" | sign_update --ed-key-file - -p TermQ-{VERSION}.zip > TermQ-{VERSION}.zip.sig
  2. The .zip.sig file is uploaded as a release asset alongside the DMG and ZIP
  3. generate-appcast.sh finds the .zip.sig asset via the GitHub API, fetches it, and writes sparkle:edSignature="..." into the appcast enclosure

Test plan

  • Next release: TermQ-{VERSION}.zip.sig appears in GitHub release assets
  • Appcast entry has sparkle:edSignature populated
  • Sparkle update succeeds without signing error
  • CI passes

🤖 Generated with Claude Code

The release workflow signed the app with Apple codesign but never generated
a Sparkle EdDSA signature for the update ZIP. The app has SUPublicEDKey
configured, so Sparkle requires a valid signature and rejects updates with
"improperly signed and could not be validated".

- release.yml: after zip creation, runs sign_update with SPARKLE_PRIVATE_KEY
  secret and uploads the signature as TermQ-{VERSION}.zip.sig release asset
- generate-appcast.sh: fetches the .zip.sig asset from GitHub releases and
  includes sparkle:edSignature in each appcast enclosure element

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@eyelock eyelock merged commit 3add1b7 into main Apr 12, 2026
8 checks passed
@eyelock eyelock deleted the worktree-fix-sparkle-signing branch April 12, 2026 11:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant