Skip to content

fix(release): strip x86_64 slice from Sparkle's Autoupdate before signing (fixes #309) - #312

Open
praxstack wants to merge 1 commit into
JerryZLiu:mainfrom
praxstack:pr3-fix-sparkle-intel-warning
Open

fix(release): strip x86_64 slice from Sparkle's Autoupdate before signing (fixes #309)#312
praxstack wants to merge 1 commit into
JerryZLiu:mainfrom
praxstack:pr3-fix-sparkle-intel-warning

Conversation

@praxstack

@praxstack praxstack commented Jul 7, 2026

Copy link
Copy Markdown

fixes #309

what

adds a lipo -thin arm64 step for Sparkle's Autoupdate binary in scripts/release_dmg.sh, right before it gets re-signed.

why

Sparkle ships Autoupdate as a universal (arm64+x86_64) binary in every release, including the latest (2.9.4) — confirmed by downloading and checking it directly. Dayflow itself is arm64-only, so that leftover Intel slice serves no purpose and is what triggers the "Support Ending for Intel-based Apps" warning on Apple Silicon, even though the app is fully native.

verification

this machine has no Developer ID cert, so I verified with ad-hoc signing — same codesign mechanism the script already uses, just a different signing identity. built a real Release config, confirmed the bug, applied the fix in the exact order the script already signs things (strip → re-sign each Sparkle component → re-sign the framework container → sign the whole app last):

$ lipo -info Autoupdate          # before
Architectures in the fat file: ... are: x86_64 arm64

$ lipo -thin arm64 Autoupdate -output Autoupdate   # the fix
$ codesign ... (script's existing re-sign steps, ad-hoc identity)

$ codesign --verify --deep --strict --verbose=2 Dayflow.app
Dayflow.app: valid on disk
Dayflow.app: satisfies its Designated Requirement

$ lipo -info Autoupdate          # after
Non-fat file: ... arm64

the strip is gated on actually finding an x86_64 slice (grep -q x86_64), so it's a safe no-op if a future Sparkle release ever ships arm64-only.

Follow-up hardening pass (2026-07-08)

Ran an internal hardening pass (independent code review + verification) on this branch — no additional issues found; no changes made (PR head remains baa5624).

What was checked:

  • Diff scope: exactly one file (scripts/release_dmg.sh, +7/-0), no stray touches.
  • Mechanism re-verified against real binaries: lipo -info guard matches a universal (x86_64 arm64) Autoupdate; in-place lipo -thin arm64 produces a non-fat arm64 binary; the strip runs before codesign of Autoupdate, the framework container, and the whole app, so no signature seal is broken.
  • Repo health: full Debug xcodebuild ... buildBUILD SUCCEEDED on this branch.
  • DayflowTests (hosted XCTest) were intentionally not run for this pass: they launch a full app instance sharing local state with a live production install on the verification machine, and this change has no Swift surface reachable from XCTest.

Follow-up hardening pass (2026-07-08)

Re-verified the release-script change: shellcheck (0.11.0, -S warning) passes clean on the whole script; confirmed lipo -thin arm64 <f> -output <f> (same input/output path) is byte-identical to extracting to a separate file (sha256 match on the real fat Autoupdate binary), so the in-place strip carries no corruption risk. End-to-end run against a real Release build still verifies: strip -> re-sign -> codesign --verify --deep --strict passes, final binary is arm64-only. No code change needed.

…ning (fixes JerryZLiu#309)

Sparkle ships Autoupdate as a universal (arm64+x86_64) binary in every
release, including the latest (2.9.4). Dayflow itself is arm64-only, so
this leftover Intel slice serves no purpose and triggers macOS's "Support
Ending for Intel-based Apps" deprecation warning on Apple Silicon Macs —
even though the app is fully native.

Verified end-to-end against a real Release build (this machine has no
Developer ID cert, so verification uses ad-hoc signing, but the mechanism
is identical to the script's own codesign calls):

1. Built Release config, confirmed the bug reproduces:
   lipo -info Autoupdate -> "x86_64 arm64"
2. Applied the fix in the script's actual signing order (strip, then
   re-sign each Sparkle component, then the framework container, then
   the whole app last, matching release_dmg.sh's existing sequence).
3. codesign --verify --deep --strict --verbose=2 on the result:
   "valid on disk" / "satisfies its Designated Requirement"
4. Final lipo check: Autoupdate is arm64-only in the fully-signed app.

The strip is gated on actually finding an x86_64 slice, so this is a
no-op (and harmless) if a future Sparkle release ships arm64-only.
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.

Sparkle's Autoupdate helper still carries an x86_64 slice, triggers "Support Ending for Intel-based Apps" on Apple Silicon

1 participant