Skip to content

ci(release): pre-notarize entitlements gate#60

Merged
matthewod11-stack merged 1 commit intomainfrom
fix/53-pre-notarize-gate
Apr 27, 2026
Merged

ci(release): pre-notarize entitlements gate#60
matthewod11-stack merged 1 commit intomainfrom
fix/53-pre-notarize-gate

Conversation

@matthewod11-stack
Copy link
Copy Markdown
Owner

Summary

  • Adds a fail-fast validation step to release.yml that runs before tauri-action (so no macOS-runner minutes are spent on signing/notarization when the build is already broken at config time).
  • Forbids com.apple.security.app-sandbox (the v0.2.0/v0.2.1 foot-gun that silently broke the auto-updater).
  • Requires the 3 hardened-runtime carve-outs (cs.allow-jit, cs.allow-unsigned-executable-memory, cs.disable-library-validation) — any missing one is a fail.

Mirrors the existing inline-bash precedent already in release.yml (Verify version alignment / Verify latest.json asset URLs).

Test plan

Local verification ran the same logic as the new step against four cases — all four matched expectations:

Workflow-level positive verification will land naturally on the next real release tag.

Why now

The v0.2.0 → v0.2.3 saga (closed #18 on 2026-04-27) lost ~30 minutes of diagnosis time and burned three tagged releases. A 23-line CI step would have caught the root cause in ~5 seconds.

Closes #53

🤖 Generated with Claude Code

Insert validation step between version-alignment check and tauri-action
build. Fails fast — before any macOS-runner minutes are spent on signing
or notarization — when:

- com.apple.security.app-sandbox is present (the v0.2.0/v0.2.1 foot-gun)
- any of the 3 required hardened-runtime carve-outs is missing
  (cs.allow-jit, cs.allow-unsigned-executable-memory,
  cs.disable-library-validation)

Verified locally against real plist (pass) and against 3 mutations
(sandbox added, cs.allow-jit removed, file missing) — all fail with
the expected ::error:: annotation.

Closes #53

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 27, 2026 17:57
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a CI “pre-notarize” validation gate to the release workflow to catch macOS entitlements misconfigurations (notably the App Sandbox regression) before running the Tauri release/signing step.

Changes:

  • Add a Validate entitlements step that fails if com.apple.security.app-sandbox is present.
  • Require the three hardened-runtime carve-outs (cs.allow-jit, cs.allow-unsigned-executable-memory, cs.disable-library-validation) to be present in src-tauri/Entitlements.plist.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +70 to +75
if grep -q 'com.apple.security.app-sandbox' "$PLIST"; then
echo "::error::App Sandbox must not be enabled for Developer ID distribution — it breaks the auto-updater. See #18/#41."
exit 1
fi
for KEY in cs.allow-jit cs.allow-unsigned-executable-memory cs.disable-library-validation; do
if ! grep -q "com.apple.security.$KEY" "$PLIST"; then
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

grep patterns here are treated as regular expressions, so the . characters match any character. That means a malformed key like comXappleXsecurityXapp-sandbox would still be matched and fail the job even though the exact entitlement key isn't present. Use fixed-string matching (e.g., grep -Fq) or escape the dots so the check only triggers on the exact entitlement key string.

Suggested change
if grep -q 'com.apple.security.app-sandbox' "$PLIST"; then
echo "::error::App Sandbox must not be enabled for Developer ID distribution — it breaks the auto-updater. See #18/#41."
exit 1
fi
for KEY in cs.allow-jit cs.allow-unsigned-executable-memory cs.disable-library-validation; do
if ! grep -q "com.apple.security.$KEY" "$PLIST"; then
if grep -Fq 'com.apple.security.app-sandbox' "$PLIST"; then
echo "::error::App Sandbox must not be enabled for Developer ID distribution — it breaks the auto-updater. See #18/#41."
exit 1
fi
for KEY in cs.allow-jit cs.allow-unsigned-executable-memory cs.disable-library-validation; do
if ! grep -Fq "com.apple.security.$KEY" "$PLIST"; then

Copilot uses AI. Check for mistakes.
exit 1
fi
for KEY in cs.allow-jit cs.allow-unsigned-executable-memory cs.disable-library-validation; do
if ! grep -q "com.apple.security.$KEY" "$PLIST"; then
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The required-key check also uses regex grep, so the . characters in com.apple.security.$KEY match any character. This can produce false positives and allow a typo’d entitlement key to pass validation. Prefer fixed-string matching (e.g., grep -Fq "com.apple.security.$KEY") so the gate reliably enforces the exact entitlement keys.

Suggested change
if ! grep -q "com.apple.security.$KEY" "$PLIST"; then
if ! grep -Fq "com.apple.security.$KEY" "$PLIST"; then

Copilot uses AI. Check for mistakes.
Comment on lines +59 to +64
- name: Validate entitlements
shell: bash
run: |
# Pre-notarize gate. Catches release-blocker plist misconfigs BEFORE
# burning macOS-runner minutes on signing + notarization.
# Origin: v0.2.0/v0.2.1 sandbox incident (#18, #41).
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This step runs inside publish-tauri, which is configured to runs-on: macos-latest. It will still consume macOS runner minutes even when failing fast. If the goal is to avoid spending macOS minutes on misconfigurations, consider moving version/entitlements validation into a separate ubuntu-latest job and gating the macOS matrix job with needs:.

Copilot uses AI. Check for mistakes.
@matthewod11-stack matthewod11-stack merged commit 262d513 into main Apr 27, 2026
7 checks passed
@matthewod11-stack matthewod11-stack deleted the fix/53-pre-notarize-gate branch April 27, 2026 18:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants