fix(release): ad-hoc self-sign the macOS bundle when no Apple certificate exists#5605
Merged
Conversation
…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).
Contributor
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
matthewevans
enabled auto-merge
July 11, 2026 19:36
matthewevans
disabled auto-merge
July 11, 2026 19:39
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 listhas 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 workflowenv:key backed by an undefinedsecret is still DEFINED, as "". So
var_osreturned Some(""), Tauri took theimport-certificate branch, and ran
security importon 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-signKeychain::with_signing_identity stores the identifier without a keychain lookup).