Skip to content

Fix release signing pipeline and stop advertising the app as unsigned - #28

Open
royalbhati wants to merge 2 commits into
mainfrom
fix/release-signing-and-install-docs
Open

royalbhati wants to merge 2 commits into
mainfrom
fix/release-signing-and-install-docs

Conversation

@royalbhati

Copy link
Copy Markdown
Owner

Why

Two problems found while auditing why installs are low.

1. The release workflow could ship an unsigned build.

release.yml built with CODE_SIGN_IDENTITY="-" (ad-hoc) and published the result on any v* tag push. Shipped 1.4.0 is properly notarized, so something outside CI produced it — but the workflow remains a live trap: the next scripts/release.sh run pushes a tag, CI builds ad-hoc, and release.sh then points the Homebrew cask at whatever CI produced.

2. The README told every visitor the app was unsigned.

Verified against the shipped 1.4.0 binary:

Authority=Developer ID Application: ZFUNDS DISTRIBUTION PRIVATE LIMITED (GP4Y23ZTR6)
spctl: accepted — source=Notarized Developer ID
stapler validate: The validate action worked!

The README still said "HopTab is ad-hoc signed (not notarized)" and gave two xattr commands to bypass Gatekeeper — the scariest possible framing immediately before asking for Accessibility permission. The notarization work was done and the trust penalty was still being paid.

What changed

Release pipeline

  • Fails fast if signing secrets are missing, instead of silently falling back to ad-hoc
  • Imports the Developer ID cert into a throwaway keychain, cleaned up on exit
  • Builds with hardened runtime + secure timestamp
  • Notarizes via notarytool and staples the ticket
  • Gates publishing on spctl reporting source=Notarized Developer ID

CI

  • build.yml now runs the 100 HopTabPro tests, which CI never executed
  • Also runs on pushes to main, not just PRs

Docs

  • README: both xattr commands and the not-notarized note removed
  • release.yml release-notes template: same fix, plus the Homebrew one-liner
  • hoptab.rb: stale root copy synced 1.2.0 → 1.4.0 to match the real tap
  • .gitignore: internal strategy docs and local demo recordings

Before merging

The release job needs these secrets, or every release will now fail (deliberately — that's the point):

Secret What
MACOS_CERT_P12_BASE64 Developer ID Application cert, .p12, base64
MACOS_CERT_PASSWORD password for that .p12
APPLE_ID Apple ID for notarization
APPLE_APP_SPECIFIC_PASSWORD app-specific password, not the account password

Team ID GP4Y23ZTR6 is set inline in the workflow.

Worth reconciling how 1.4.0 actually got signed before cutting 1.5 — if it was a manual Xcode archive, this workflow replaces that step.

The release workflow built with CODE_SIGN_IDENTITY="-" (ad-hoc) and
published the result, so any tag push could ship an unsigned build that
trips Gatekeeper. Releases now:

- fail fast if signing secrets are absent, rather than silently going ad-hoc
- import the Developer ID cert into a throwaway keychain
- build with hardened runtime and a secure timestamp
- notarize via notarytool and staple the ticket
- gate publishing on spctl reporting "Notarized Developer ID"

Requires secrets: MACOS_CERT_P12_BASE64, MACOS_CERT_PASSWORD, APPLE_ID,
APPLE_APP_SPECIFIC_PASSWORD.

build.yml also runs the 100 HopTabPro tests, which CI never executed, and
now runs on pushes to main rather than pull requests only.
HopTab has been Developer ID signed and notarized since 1.4.0, but the
README still said "ad-hoc signed (not notarized)" and instructed people
to run xattr to bypass Gatekeeper — the scariest possible framing right
before asking for Accessibility permission.

- README: drop both xattr commands and the not-notarized note
- release.yml: same fix in the release-notes template
- hoptab.rb: sync the stale root copy (1.2.0) to match the real tap (1.4.0)
- gitignore internal strategy docs and local demo recordings

(scripts/release.sh carries the same stale text and has been fixed
locally, but scripts/ is gitignored so it is not part of this commit.)
@royalbhati
royalbhati force-pushed the fix/release-signing-and-install-docs branch from c1e312c to 448b93c Compare August 30, 2026 03:46

This branch has not been deployed

No deployments
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