Skip to content

fix(release): ad-hoc self-sign the macOS bundle when no Apple certificate exists#5605

Merged
matthewevans merged 1 commit into
mainfrom
ship/macos-adhoc-sign
Jul 11, 2026
Merged

fix(release): ad-hoc self-sign the macOS bundle when no Apple certificate exists#5605
matthewevans merged 1 commit into
mainfrom
ship/macos-adhoc-sign

Conversation

@matthewevans

Copy link
Copy Markdown
Member

Build Tauri (macos) failed the v0.21.0 release with:

failed to bundle project failed codesign application:
failed to run command security import: failed to import keychain certificate

No APPLE_* secret is defined in this repo (verified: gh secret list has none).
That is precisely why it broke. Tauri selects its macOS signing path by the
PRESENCE of the env var, not its value -- tauri-bundler macos/sign.rs branches on
var_os("APPLE_CERTIFICATE") -- and a workflow env: key backed by an undefined
secret is still DEFINED, as "". So var_os returned Some(""), Tauri took the
import-certificate branch, and ran security import on an empty certificate.
The same trap applies to APPLE_SIGNING_IDENTITY (tauri-cli rust.rs resolves it as
Some("") and would hand "" to codesign -s) and to the notarization credentials.

b015a7e84f made this reachable: it removed the condition that used to skip the
macOS Tauri leg, but left the Apple secrets wired into the build step's env. Before
it, the leg no-op'd in ~17s and reported success; now it builds for real and dies on
the empty certificate.

The blast radius was larger than a missing .dmg. The release job tolerates a Tauri
failure for legacy v0.* tags (is_calver escape hatch), but deploy-production does
not carry that override, so it was SKIPPED -- v0.21.0 published while production
Cloudflare Pages silently stayed on the old build. Confirmed by A/B against v0.20.0,
whose macOS leg succeeded and whose production deploy ran.

Fix: stop listing the APPLE_* secrets on the build step (that block is what defines
them as ""), and export them from a preceding macOS-only step via $GITHUB_ENV, which
only defines what it is handed. With a certificate present, sign as before, forwarding
each optional var only when it carries a value. With none, ad-hoc self-sign: identity
"-" goes straight to codesign -s - and needs no keychain (tauri-macos-sign
Keychain::with_signing_identity stores the identifier without a keychain lookup).

…cate exists

Build Tauri (macos) failed the v0.21.0 release with:

  failed to bundle project failed codesign application:
  failed to run command security import: failed to import keychain certificate

No APPLE_* secret is defined in this repo (verified: `gh secret list` has none).
That is precisely why it broke. Tauri selects its macOS signing path by the
PRESENCE of the env var, not its value -- tauri-bundler macos/sign.rs branches on
`var_os("APPLE_CERTIFICATE")` -- and a workflow `env:` key backed by an undefined
secret is still DEFINED, as "". So `var_os` returned Some(""), Tauri took the
import-certificate branch, and ran `security import` on an empty certificate.
The same trap applies to APPLE_SIGNING_IDENTITY (tauri-cli rust.rs resolves it as
Some("") and would hand "" to `codesign -s`) and to the notarization credentials.

b015a7e84f made this reachable: it removed the condition that used to skip the
macOS Tauri leg, but left the Apple secrets wired into the build step's env. Before
it, the leg no-op'd in ~17s and reported success; now it builds for real and dies on
the empty certificate.

The blast radius was larger than a missing .dmg. The release job tolerates a Tauri
failure for legacy v0.* tags (is_calver escape hatch), but deploy-production does
not carry that override, so it was SKIPPED -- v0.21.0 published while production
Cloudflare Pages silently stayed on the old build. Confirmed by A/B against v0.20.0,
whose macOS leg succeeded and whose production deploy ran.

Fix: stop listing the APPLE_* secrets on the build step (that block is what defines
them as ""), and export them from a preceding macOS-only step via $GITHUB_ENV, which
only defines what it is handed. With a certificate present, sign as before, forwarding
each optional var only when it carries a value. With none, ad-hoc self-sign: identity
"-" goes straight to `codesign -s -` and needs no keychain (tauri-macos-sign
Keychain::with_signing_identity stores the identifier without a keychain lookup).
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@matthewevans
matthewevans enabled auto-merge July 11, 2026 19:36
@matthewevans
matthewevans disabled auto-merge July 11, 2026 19:39
@matthewevans
matthewevans merged commit 68a6e05 into main Jul 11, 2026
12 checks passed
@matthewevans
matthewevans deleted the ship/macos-adhoc-sign branch July 11, 2026 19:39
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