From 3eff81e18ddab3ddbc6f4bc492ddb04e967228e8 Mon Sep 17 00:00:00 2001 From: 2ro <17595647+2ro@users.noreply.github.com> Date: Mon, 15 Jun 2026 20:18:41 -0400 Subject: [PATCH] macOS: package as Goblin.app bundle, not a bare binary The macOS CI job lipo'd the universal binary and zipped it raw, so users got a naked 'goblin' executable instead of a double-clickable app. Assemble the universal binary into the existing macos/Goblin.app bundle (Info.plist + icon), ad-hoc codesign it (required for the arm64 slice to run on Apple Silicon after lipo strips the per-arch signature), and ditto-zip the bundle. Remove the stale tracked _CodeSignature that would otherwise make the app read as 'damaged'. --- .github/workflows/release.yml | 18 ++- .../Contents/_CodeSignature/CodeResources | 128 ------------------ 2 files changed, 16 insertions(+), 130 deletions(-) delete mode 100644 macos/Goblin.app/Contents/_CodeSignature/CodeResources diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3cb8a82..611b51b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -93,12 +93,26 @@ jobs: rustup target add aarch64-apple-darwin x86_64-apple-darwin cargo build --release --target aarch64-apple-darwin cargo build --release --target x86_64-apple-darwin - - name: Universal binary + package + - name: Universal binary into Goblin.app bundle run: | + # Combine both arches into one universal Mach-O and drop it into the + # app bundle's executable slot (CFBundleExecutable=goblin). lipo -create -output goblin \ target/aarch64-apple-darwin/release/goblin \ target/x86_64-apple-darwin/release/goblin - zip "goblin-$TAG-macos-universal.zip" goblin + cp goblin macos/Goblin.app/Contents/MacOS/goblin + chmod +x macos/Goblin.app/Contents/MacOS/goblin + # Drop the placeholder that kept the empty dir tracked in git. + rm -f macos/Goblin.app/Contents/MacOS/.gitignore + # Ad-hoc sign (no Apple cert in CI). REQUIRED on Apple Silicon: lipo + # strips the per-arch signatures cargo/ld add, and an unsigned arm64 + # Mach-O is killed by the OS. Ad-hoc gives a valid (if unidentified) + # signature; users still right-click → Open past Gatekeeper. + codesign --force --sign - macos/Goblin.app/Contents/MacOS/goblin + codesign --force --sign - macos/Goblin.app + # ditto is the macOS-correct way to zip an .app (preserves the bundle + # layout, symlinks and permissions; plain `zip` mangles bundles). + ditto -c -k --keepParent macos/Goblin.app "goblin-$TAG-macos-universal.zip" shasum -a 256 "goblin-$TAG-macos-universal.zip" > "goblin-$TAG-macos-universal-sha256sum.txt" - uses: softprops/action-gh-release@v2 with: diff --git a/macos/Goblin.app/Contents/_CodeSignature/CodeResources b/macos/Goblin.app/Contents/_CodeSignature/CodeResources deleted file mode 100644 index 09a207a..0000000 --- a/macos/Goblin.app/Contents/_CodeSignature/CodeResources +++ /dev/null @@ -1,128 +0,0 @@ - - - - - files - - Resources/AppIcon.icns - - F0XBdu5xI+eXrj78HQf2Qr9SKio= - - - files2 - - Resources/AppIcon.icns - - hash2 - - ZjAn1LaNzSeTeUtKbWKWE7W2ELzhYyrHjKYOXUkQvcI= - - - - rules - - ^Resources/ - - ^Resources/.*\.lproj/ - - optional - - weight - 1000 - - ^Resources/.*\.lproj/locversion.plist$ - - omit - - weight - 1100 - - ^Resources/Base\.lproj/ - - weight - 1010 - - ^version.plist$ - - - rules2 - - .*\.dSYM($|/) - - weight - 11 - - ^(.*/)?\.DS_Store$ - - omit - - weight - 2000 - - ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ - - nested - - weight - 10 - - ^.* - - ^Info\.plist$ - - omit - - weight - 20 - - ^PkgInfo$ - - omit - - weight - 20 - - ^Resources/ - - weight - 20 - - ^Resources/.*\.lproj/ - - optional - - weight - 1000 - - ^Resources/.*\.lproj/locversion.plist$ - - omit - - weight - 1100 - - ^Resources/Base\.lproj/ - - weight - 1010 - - ^[^/]+$ - - nested - - weight - 10 - - ^embedded\.provisionprofile$ - - weight - 20 - - ^version\.plist$ - - weight - 20 - - - -