mirror of
https://github.com/yattee/yattee.git
synced 2026-07-19 05:42:04 +00:00
Add mac-release script for notarized Developer ID builds
This commit is contained in:
141
bin/mac-release
Executable file
141
bin/mac-release
Executable file
@@ -0,0 +1,141 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Build, sign (Developer ID), notarize and package the macOS app for
|
||||||
|
# distribution outside the App Store — produces a .zip and .dmg you can
|
||||||
|
# send to other Macs.
|
||||||
|
#
|
||||||
|
# Usage: bin/mac-release [--skip-build] [--skip-notarize]
|
||||||
|
# --skip-build reuse the existing archive from a previous run
|
||||||
|
# --skip-notarize stop after signing (app won't pass Gatekeeper on other Macs)
|
||||||
|
#
|
||||||
|
# Requirements:
|
||||||
|
# - "Developer ID Application" certificate in the login keychain
|
||||||
|
# - "match Direct stream.yattee.app macos" provisioning profile installed
|
||||||
|
# (run `fastlane match developer_id --platform macos --readonly` if missing)
|
||||||
|
# - fastlane/.env with DEVELOPER_KEY_ID / DEVELOPER_KEY_ISSUER_ID /
|
||||||
|
# DEVELOPER_KEY_CONTENT (base64-encoded .p8) for notarization
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
cd "$(dirname "$0")/.."
|
||||||
|
|
||||||
|
APP_NAME=Yattee
|
||||||
|
BUNDLE_ID=stream.yattee.app
|
||||||
|
TEAM_ID=78Z5H3M6RJ
|
||||||
|
PROFILE="match Direct ${BUNDLE_ID} macos"
|
||||||
|
|
||||||
|
SKIP_BUILD=0
|
||||||
|
SKIP_NOTARIZE=0
|
||||||
|
for arg in "$@"; do
|
||||||
|
case "$arg" in
|
||||||
|
--skip-build) SKIP_BUILD=1 ;;
|
||||||
|
--skip-notarize) SKIP_NOTARIZE=1 ;;
|
||||||
|
*) echo "Unknown option: $arg"; exit 1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Marketing version is a build setting (no Info.plist entry), so agvtool
|
||||||
|
# can't read it — take it from the pbxproj.
|
||||||
|
VERSION=$(sed -n 's/.*MARKETING_VERSION = \([^;]*\);.*/\1/p' "${APP_NAME}.xcodeproj/project.pbxproj" | head -1)
|
||||||
|
BUILD=$(xcrun agvtool what-version -terse)
|
||||||
|
[ -n "$VERSION" ] && [ -n "$BUILD" ] || { echo "Could not determine version/build"; exit 1; }
|
||||||
|
|
||||||
|
OUT_DIR="fastlane/builds/${VERSION}-${BUILD}/macOS"
|
||||||
|
ARCHIVE="${OUT_DIR}/${APP_NAME}.xcarchive"
|
||||||
|
APP="${OUT_DIR}/${APP_NAME}.app"
|
||||||
|
ZIP="${OUT_DIR}/${APP_NAME}-${VERSION}-macOS.zip"
|
||||||
|
DMG="${OUT_DIR}/${APP_NAME}-${VERSION}-macOS.dmg"
|
||||||
|
LOG="${OUT_DIR}/xcodebuild.log"
|
||||||
|
mkdir -p "$OUT_DIR"
|
||||||
|
|
||||||
|
TMP=$(mktemp -d)
|
||||||
|
trap 'rm -rf "$TMP"' EXIT
|
||||||
|
|
||||||
|
echo "==> ${APP_NAME} ${VERSION} (${BUILD}) → ${OUT_DIR}"
|
||||||
|
|
||||||
|
if [ "$SKIP_BUILD" = 1 ] && [ -d "$ARCHIVE" ]; then
|
||||||
|
echo "==> Skipping build, reusing ${ARCHIVE}"
|
||||||
|
else
|
||||||
|
echo "==> Archiving (Release-DeveloperID)… log: ${LOG}"
|
||||||
|
xcodebuild archive \
|
||||||
|
-project "${APP_NAME}.xcodeproj" \
|
||||||
|
-scheme "$APP_NAME" \
|
||||||
|
-configuration Release-DeveloperID \
|
||||||
|
-destination 'generic/platform=macOS' \
|
||||||
|
-archivePath "$ARCHIVE" \
|
||||||
|
CODE_SIGN_STYLE=Manual \
|
||||||
|
CODE_SIGN_IDENTITY="Developer ID Application" \
|
||||||
|
DEVELOPMENT_TEAM="$TEAM_ID" \
|
||||||
|
PROVISIONING_PROFILE_SPECIFIER="$PROFILE" \
|
||||||
|
> "$LOG" 2>&1 || { tail -50 "$LOG"; echo "Archive failed — full log: ${LOG}"; exit 1; }
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "==> Exporting with Developer ID…"
|
||||||
|
cat > "$TMP/export.plist" <<PLIST
|
||||||
|
<?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>method</key><string>developer-id</string>
|
||||||
|
<key>signingStyle</key><string>manual</string>
|
||||||
|
<key>teamID</key><string>${TEAM_ID}</string>
|
||||||
|
<key>provisioningProfiles</key>
|
||||||
|
<dict>
|
||||||
|
<key>${BUNDLE_ID}</key><string>${PROFILE}</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
|
PLIST
|
||||||
|
rm -rf "$APP"
|
||||||
|
xcodebuild -exportArchive \
|
||||||
|
-archivePath "$ARCHIVE" \
|
||||||
|
-exportPath "$OUT_DIR" \
|
||||||
|
-exportOptionsPlist "$TMP/export.plist" \
|
||||||
|
>> "$LOG" 2>&1 || { tail -50 "$LOG"; echo "Export failed — full log: ${LOG}"; exit 1; }
|
||||||
|
|
||||||
|
if [ "$SKIP_NOTARIZE" = 0 ]; then
|
||||||
|
# Notarization credentials come from the same ASC API key fastlane uses.
|
||||||
|
set -a; source fastlane/.env; set +a
|
||||||
|
: "${DEVELOPER_KEY_ID:?missing in fastlane/.env}"
|
||||||
|
: "${DEVELOPER_KEY_ISSUER_ID:?missing in fastlane/.env}"
|
||||||
|
: "${DEVELOPER_KEY_CONTENT:?missing in fastlane/.env}"
|
||||||
|
KEY_FILE="$TMP/AuthKey_${DEVELOPER_KEY_ID}.p8"
|
||||||
|
echo "$DEVELOPER_KEY_CONTENT" | base64 -d > "$KEY_FILE"
|
||||||
|
|
||||||
|
echo "==> Submitting for notarization (this can take a few minutes)…"
|
||||||
|
ditto -c -k --keepParent "$APP" "$TMP/notarize.zip"
|
||||||
|
NOTARY_OUT=$(xcrun notarytool submit "$TMP/notarize.zip" \
|
||||||
|
--key "$KEY_FILE" \
|
||||||
|
--key-id "$DEVELOPER_KEY_ID" \
|
||||||
|
--issuer "$DEVELOPER_KEY_ISSUER_ID" \
|
||||||
|
--wait --timeout 30m 2>&1 | tee /dev/stderr) || true
|
||||||
|
|
||||||
|
if ! grep -q "status: Accepted" <<< "$NOTARY_OUT"; then
|
||||||
|
SUBMISSION_ID=$(grep -m1 -o 'id: [0-9a-f-]*' <<< "$NOTARY_OUT" | head -1 | cut -d' ' -f2)
|
||||||
|
echo "Notarization failed."
|
||||||
|
if [ -n "$SUBMISSION_ID" ]; then
|
||||||
|
echo "==> Fetching notarization log for ${SUBMISSION_ID}…"
|
||||||
|
xcrun notarytool log "$SUBMISSION_ID" \
|
||||||
|
--key "$KEY_FILE" --key-id "$DEVELOPER_KEY_ID" --issuer "$DEVELOPER_KEY_ISSUER_ID"
|
||||||
|
fi
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "==> Stapling notarization ticket…"
|
||||||
|
xcrun stapler staple "$APP"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "==> Packaging…"
|
||||||
|
rm -f "$ZIP" "$DMG"
|
||||||
|
ditto -c -k --keepParent "$APP" "$ZIP"
|
||||||
|
hdiutil create -volname "${APP_NAME} ${VERSION}" -srcfolder "$APP" -ov -format UDZO "$DMG" > /dev/null
|
||||||
|
|
||||||
|
echo "==> Verifying…"
|
||||||
|
codesign --verify --deep --strict "$APP"
|
||||||
|
if [ "$SKIP_NOTARIZE" = 0 ]; then
|
||||||
|
xcrun stapler validate "$APP"
|
||||||
|
spctl --assess --type exec -vv "$APP" 2>&1 | tail -2
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Done:"
|
||||||
|
echo " ${ZIP}"
|
||||||
|
echo " ${DMG}"
|
||||||
Reference in New Issue
Block a user