#!/bin/bash
set -euo pipefail
IDENTITY="${ATOMCODE_SIGN_IDENTITY:-Developer ID Application: Chongqing Kaiyuan Gongchuang Technology Co., Ltd. (T949H383MF)}"
NOTARY_PROFILE="${ATOMCODE_NOTARY_PROFILE:-atomcode-notary}"
SKIP_NOTARIZE="${ATOMCODE_SKIP_NOTARIZE:-0}"
usage() {
cat <<EOF
Usage: $0 <binary-path | dist-directory>
Examples:
$0 target/release/atomcode
$0 dist/v2.5.0
Env:
ATOMCODE_SIGN_IDENTITY override signing identity
ATOMCODE_NOTARY_PROFILE override notarytool keychain profile (default: atomcode-notary)
ATOMCODE_SKIP_NOTARIZE=1 codesign only, skip notarization
EOF
exit 1
}
[ $# -eq 1 ] || usage
TARGET="$1"
if ! security find-identity -v -p codesigning | grep -q "$IDENTITY"; then
echo "Error: signing identity not found in keychain:"
echo " $IDENTITY"
echo ""
echo "Available identities:"
security find-identity -v -p codesigning
exit 1
fi
if [ "$SKIP_NOTARIZE" != "1" ]; then
if ! xcrun notarytool history --keychain-profile "$NOTARY_PROFILE" >/dev/null 2>&1; then
cat <<EOF
Error: notarytool keychain profile "$NOTARY_PROFILE" not found or invalid.
Create it once with:
xcrun notarytool store-credentials $NOTARY_PROFILE \\
--apple-id "YOUR_APPLE_ID" \\
--team-id T949H383MF \\
--password "APP_SPECIFIC_PASSWORD"
Or skip notarization: ATOMCODE_SKIP_NOTARIZE=1 $0 $1
EOF
exit 1
fi
fi
sign_one() {
local bin="$1"
echo "[sign] $(basename "$bin")"
codesign \
--force \
--timestamp \
--options=runtime \
--sign "$IDENTITY" \
"$bin"
codesign --verify --strict "$bin"
}
notarize_one() {
local bin="$1"
local tmpzip
tmpzip=$(mktemp -d)/"$(basename "$bin").zip"
/usr/bin/ditto -c -k --keepParent "$bin" "$tmpzip"
echo "[notarize] submitting $(basename "$bin")..."
xcrun notarytool submit "$tmpzip" \
--keychain-profile "$NOTARY_PROFILE" \
--wait
rm -f "$tmpzip"
}
is_macho_atomcode_bin() {
local path="$1"
local base
base=$(basename "$path")
case "$base" in
atomcode-daemon*) return 1 ;;
atomcode|atomcode-*-darwin-*) ;;
*) return 1 ;;
esac
[ -f "$path" ] || return 1
case "$base" in
*.tar.gz|*.zip|*.sig|*.txt) return 1 ;;
esac
file "$path" 2>/dev/null | grep -q "Mach-O"
}
process_one() {
local bin="$1"
sign_one "$bin"
if [ "$SKIP_NOTARIZE" != "1" ]; then
notarize_one "$bin"
fi
}
if [ -f "$TARGET" ]; then
if is_macho_atomcode_bin "$TARGET"; then
process_one "$TARGET"
else
echo "Error: $TARGET is not a macOS atomcode binary."
exit 1
fi
elif [ -d "$TARGET" ]; then
found=0
for bin in "$TARGET"/atomcode*; do
[ -e "$bin" ] || continue
if is_macho_atomcode_bin "$bin"; then
process_one "$bin"
found=$((found + 1))
fi
done
if [ $found -eq 0 ]; then
echo "No signable atomcode binaries found in $TARGET"
exit 1
fi
echo ""
echo "Signed $found binary(ies)."
else
echo "Error: $TARGET not found"
exit 1
fi