Add code signing, notarization, and DMG packaging scripts
Enables distributing Galaxy.app to end users without Gatekeeper warnings. Uses Samsung Developer ID Application certificate with hardened runtime. Pipeline: cargo bundle → sign.sh → notarize.sh → package.sh → Galaxy.dmg Entitlements: - network.client (AWS Bedrock API calls) - automation.apple-events (osascript for CLI install) - cs.allow-unsigned-executable-memory (Metal shader compilation) Orchestration scripts: - build-debug.sh: full pipeline with debug build - build-release.sh: full pipeline with release build Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
cee61e2af0
commit
c9492c90ea
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
|
||||||
|
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>com.apple.security.network.client</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.automation.apple-events</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
Executable
+14
@@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
|
echo "=== Galaxy Debug Build + Sign + Notarize + Package ==="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
cargo bundle --bin galaxy-oss --package galaxy
|
||||||
|
./sign.sh
|
||||||
|
./notarize.sh
|
||||||
|
./package.sh
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Done. Distributable DMG: target/debug/bundle/osx/Galaxy.dmg ==="
|
||||||
Executable
+14
@@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
|
echo "=== Galaxy Release Build + Sign + Notarize + Package ==="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
cargo bundle --release --bin galaxy-oss --package galaxy
|
||||||
|
./sign.sh --release
|
||||||
|
./notarize.sh --release
|
||||||
|
./package.sh --release
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Done. Distributable DMG: target/release/bundle/osx/Galaxy.dmg ==="
|
||||||
Executable
+49
@@ -0,0 +1,49 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
|
if [ "$1" = "--release" ]; then
|
||||||
|
APP_PATH="target/release/bundle/osx/Galaxy.app"
|
||||||
|
ZIP_PATH="target/release/bundle/osx/Galaxy.zip"
|
||||||
|
else
|
||||||
|
APP_PATH="target/debug/bundle/osx/Galaxy.app"
|
||||||
|
ZIP_PATH="target/debug/bundle/osx/Galaxy.zip"
|
||||||
|
fi
|
||||||
|
|
||||||
|
trap 'rm -f "$ZIP_PATH"' EXIT
|
||||||
|
|
||||||
|
if [ ! -d "$APP_PATH" ]; then
|
||||||
|
echo "Error: $APP_PATH not found."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Verifying app is signed before notarization..."
|
||||||
|
codesign --verify --strict "$APP_PATH" || {
|
||||||
|
echo "Error: App is not properly signed. Run ./sign.sh first."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Creating zip for notarization submission..."
|
||||||
|
rm -f "$ZIP_PATH"
|
||||||
|
ditto -c -k --keepParent "$APP_PATH" "$ZIP_PATH"
|
||||||
|
|
||||||
|
echo "Submitting to Apple notary service (this may take a few minutes)..."
|
||||||
|
RESULT=$(xcrun notarytool submit "$ZIP_PATH" \
|
||||||
|
--keychain-profile notarytool-profile \
|
||||||
|
--wait 2>&1)
|
||||||
|
echo "$RESULT"
|
||||||
|
|
||||||
|
if ! echo "$RESULT" | grep -q "status: Accepted"; then
|
||||||
|
echo ""
|
||||||
|
echo "Error: Notarization was not accepted. Check output above."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Stapling notarization ticket to app..."
|
||||||
|
xcrun stapler staple "$APP_PATH"
|
||||||
|
|
||||||
|
echo "Validating stapled ticket..."
|
||||||
|
xcrun stapler validate "$APP_PATH"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Done. Galaxy.app is notarized and stapled."
|
||||||
Executable
+69
@@ -0,0 +1,69 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
|
SIGNING_IDENTITY="Developer ID Application: SAMSUNG ELECTRONICS AMERICA, INC. (3JU72Z7Y3J)"
|
||||||
|
|
||||||
|
if [ "$1" = "--release" ]; then
|
||||||
|
APP_PATH="target/release/bundle/osx/Galaxy.app"
|
||||||
|
DMG_PATH="target/release/bundle/osx/Galaxy.dmg"
|
||||||
|
STAGING_DIR="target/release/bundle/osx/dmg-staging"
|
||||||
|
else
|
||||||
|
APP_PATH="target/debug/bundle/osx/Galaxy.app"
|
||||||
|
DMG_PATH="target/debug/bundle/osx/Galaxy.dmg"
|
||||||
|
STAGING_DIR="target/debug/bundle/osx/dmg-staging"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d "$APP_PATH" ]; then
|
||||||
|
echo "Error: $APP_PATH not found."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Verifying app is notarized..."
|
||||||
|
xcrun stapler validate "$APP_PATH" || {
|
||||||
|
echo "Error: App does not have a valid notarization ticket. Run ./sign.sh and ./notarize.sh first."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Preparing DMG staging directory..."
|
||||||
|
rm -rf "$STAGING_DIR"
|
||||||
|
mkdir -p "$STAGING_DIR"
|
||||||
|
cp -R "$APP_PATH" "$STAGING_DIR/"
|
||||||
|
ln -s /Applications "$STAGING_DIR/Applications"
|
||||||
|
|
||||||
|
echo "Creating DMG..."
|
||||||
|
hdiutil detach /Volumes/Galaxy -force 2>/dev/null || true
|
||||||
|
rm -f "$DMG_PATH"
|
||||||
|
hdiutil create -volname "Galaxy" \
|
||||||
|
-srcfolder "$STAGING_DIR" \
|
||||||
|
-ov -format UDZO \
|
||||||
|
"$DMG_PATH"
|
||||||
|
|
||||||
|
echo "Signing DMG..."
|
||||||
|
codesign --force --sign "$SIGNING_IDENTITY" --timestamp "$DMG_PATH"
|
||||||
|
|
||||||
|
echo "Submitting DMG to Apple notary service..."
|
||||||
|
RESULT=$(xcrun notarytool submit "$DMG_PATH" \
|
||||||
|
--keychain-profile notarytool-profile \
|
||||||
|
--wait 2>&1)
|
||||||
|
echo "$RESULT"
|
||||||
|
|
||||||
|
if ! echo "$RESULT" | grep -q "status: Accepted"; then
|
||||||
|
echo ""
|
||||||
|
echo "Error: DMG notarization was not accepted. Check output above."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Stapling notarization ticket to DMG..."
|
||||||
|
xcrun stapler staple "$DMG_PATH"
|
||||||
|
|
||||||
|
echo "Cleaning up staging directory..."
|
||||||
|
rm -rf "$STAGING_DIR"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Verifying final DMG..."
|
||||||
|
xcrun stapler validate "$DMG_PATH"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Done. Galaxy.dmg is ready for distribution at:"
|
||||||
|
echo " $DMG_PATH"
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
|
SIGNING_IDENTITY="Developer ID Application: SAMSUNG ELECTRONICS AMERICA, INC. (3JU72Z7Y3J)"
|
||||||
|
ENTITLEMENTS="BuildSupport/Galaxy.entitlements"
|
||||||
|
|
||||||
|
if [ "$1" = "--release" ]; then
|
||||||
|
APP_PATH="target/release/bundle/osx/Galaxy.app"
|
||||||
|
else
|
||||||
|
APP_PATH="target/debug/bundle/osx/Galaxy.app"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -d "$APP_PATH" ]; then
|
||||||
|
echo "Error: $APP_PATH not found."
|
||||||
|
echo "Run first: cargo bundle --bin galaxy-oss --package galaxy"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$ENTITLEMENTS" ]; then
|
||||||
|
echo "Error: $ENTITLEMENTS not found."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
JUNK=$(find "$APP_PATH" -maxdepth 1 -not -name "Contents" -not -path "$APP_PATH" 2>/dev/null || true)
|
||||||
|
if [ -n "$JUNK" ]; then
|
||||||
|
echo "Removing unsealed items from bundle root: $JUNK"
|
||||||
|
echo "$JUNK" | xargs rm -rf
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Removing .DS_Store files..."
|
||||||
|
find "$APP_PATH" -name '.DS_Store' -delete 2>/dev/null || true
|
||||||
|
|
||||||
|
echo "Stripping extended attributes..."
|
||||||
|
xattr -cr "$APP_PATH"
|
||||||
|
|
||||||
|
echo "Signing $APP_PATH..."
|
||||||
|
codesign --force --sign "$SIGNING_IDENTITY" \
|
||||||
|
--entitlements "$ENTITLEMENTS" \
|
||||||
|
--options runtime \
|
||||||
|
--timestamp \
|
||||||
|
"$APP_PATH/Contents/MacOS/galaxy-oss"
|
||||||
|
|
||||||
|
codesign --force --sign "$SIGNING_IDENTITY" \
|
||||||
|
--entitlements "$ENTITLEMENTS" \
|
||||||
|
--options runtime \
|
||||||
|
--timestamp \
|
||||||
|
"$APP_PATH"
|
||||||
|
|
||||||
|
echo "Verifying signature..."
|
||||||
|
codesign --verify --strict "$APP_PATH"
|
||||||
|
codesign -dvvv "$APP_PATH" 2>&1 | grep -E "Authority|TeamIdentifier|Runtime"
|
||||||
|
echo "Architecture: $(lipo -archs "$APP_PATH/Contents/MacOS/galaxy-oss")"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Done. Galaxy.app is signed and ready for notarization."
|
||||||
Reference in New Issue
Block a user