Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
#!/usr/bin/env bash

# Submits a signed standalone macOS binary to Apple notarization through
# rcodesign. Standalone binaries cannot carry a stapled ticket, so the binary
# is submitted in a ZIP and the successful notarization log is retained.
# Notarize a standalone binary and retain its diagnostic report.

set -euo pipefail

usage() {
cat >&2 <<'EOF'
Usage: notarize_macos_binary_with_rcodesign.sh --binary PATH [--report-dir PATH] [--max-wait-seconds SECONDS]
Usage: notarize_macos_binary_with_akv.sh --binary PATH [--report-dir PATH] [--max-wait-seconds SECONDS]

Options:
--binary PATH Signed standalone macOS binary to notarize.
--report-dir PATH Directory for notarization logs.
--max-wait-seconds SECONDS Maximum rcodesign notarization wait time.
--max-wait-seconds SECONDS Maximum Apple notarization wait time.
EOF
}

Expand Down Expand Up @@ -63,7 +61,7 @@ if [[ ! "$max_wait_seconds" =~ ^[0-9]+$ ]]; then
exit 2
fi

for command_name in rcodesign zip; do
for command_name in python3 zip; do
if ! command -v "$command_name" >/dev/null 2>&1; then
echo "$command_name was not found on PATH." >&2
exit 1
Expand All @@ -73,11 +71,11 @@ done
missing_environment=0
for variable_name in \
APPLE_NOTARIZATION_ISSUER_ID \
APPLE_NOTARIZATION_KEY_ID \
APPLE_NOTARIZATION_KEY_P8
APPLE_NOTARIZATION_AKV_KEY_NAME \
AZURE_KEYVAULT_NAME
do
if [[ -z "${!variable_name:-}" ]]; then
echo "$variable_name must be set from CI secrets before notarizing a binary." >&2
echo "$variable_name must be configured before notarizing a binary." >&2
missing_environment=1
fi
done
Expand All @@ -91,23 +89,6 @@ mkdir -p "$report_dir"
notarization_temp_dir="$(mktemp -d)"
trap 'rm -rf "$notarization_temp_dir" >/dev/null' EXIT

private_key_path="$notarization_temp_dir/AuthKey_${APPLE_NOTARIZATION_KEY_ID}.p8"
if ! printf '%s' "$APPLE_NOTARIZATION_KEY_P8" | base64 --decode >"$private_key_path" 2>/dev/null; then
if ! printf '%s' "$APPLE_NOTARIZATION_KEY_P8" | base64 -D >"$private_key_path" 2>/dev/null; then
echo "APPLE_NOTARIZATION_KEY_P8 must be a base64-encoded .p8 private key." >&2
exit 2
fi
fi
chmod 600 "$private_key_path"

api_key_path="$notarization_temp_dir/app-store-connect-api-key.json"
rcodesign encode-app-store-connect-api-key \
--output-path "$api_key_path" \
"$APPLE_NOTARIZATION_ISSUER_ID" \
"$APPLE_NOTARIZATION_KEY_ID" \
"$private_key_path" \
>"$report_dir/encode-app-store-connect-api-key.log" 2>&1

binary_name="$(basename "$binary_path")"
archive_path="$notarization_temp_dir/${binary_name}.zip"
(
Expand All @@ -116,16 +97,15 @@ archive_path="$notarization_temp_dir/${binary_name}.zip"
)

notarization_log="$report_dir/${binary_name}-notarization.log"
rcodesign notarize \
--api-key-file "$api_key_path" \
python3 "$(dirname "$0")/notarize_with_akv.py" \
--file "$archive_path" \
--report-log "$report_dir/${binary_name}-notarization-developer-log.json" \
--max-wait-seconds "$max_wait_seconds" \
--wait \
"$archive_path" \
2>&1 | tee "$notarization_log"

{
echo "binary_name=$binary_name"
echo "max_wait_seconds=$max_wait_seconds"
echo "binary_sha256=$(shasum -a 256 "$binary_path" | awk '{ print $1 }')"
echo "rcodesign_notarize=completed"
echo "notarization=completed"
} >"$report_dir/${binary_name}-notarization-summary.txt"
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
#!/usr/bin/env bash

# Notarizes and staples a signed macOS DMG through rcodesign.
#
# This is the Linux-compatible notarization path for the AKV/PKCS#11 signing
# flow. It records notarization inputs and logs so workflow artifacts can be
# audited without exposing the App Store Connect private key.
# Notarize a signed disk image and staple its ticket.

set -euo pipefail

usage() {
cat >&2 <<'EOF'
Usage: notarize_macos_dmg_with_rcodesign.sh --dmg PATH [--report-dir PATH] [--max-wait-seconds SECONDS]
Usage: notarize_macos_dmg_with_akv.sh --dmg PATH [--report-dir PATH] [--max-wait-seconds SECONDS]

Options:
--dmg PATH Signed DMG to submit to Apple notarization.
--report-dir PATH Directory for notarization logs.
--max-wait-seconds SECONDS Maximum rcodesign notarization wait time.
--max-wait-seconds SECONDS Maximum Apple notarization wait time.
EOF
}

Expand Down Expand Up @@ -73,11 +69,11 @@ fi
missing_environment=0
for variable_name in \
APPLE_NOTARIZATION_ISSUER_ID \
APPLE_NOTARIZATION_KEY_ID \
APPLE_NOTARIZATION_KEY_P8
APPLE_NOTARIZATION_AKV_KEY_NAME \
AZURE_KEYVAULT_NAME
do
if [[ -z "${!variable_name:-}" ]]; then
echo "$variable_name must be set from CI secrets before notarizing a DMG." >&2
echo "$variable_name must be configured before notarizing a DMG." >&2
missing_environment=1
fi
done
Expand All @@ -88,37 +84,18 @@ fi

mkdir -p "$report_dir"

notarization_temp_dir="$(mktemp -d)"
trap 'rm -rf "$notarization_temp_dir" > /dev/null' EXIT

private_key_path="$notarization_temp_dir/AuthKey_${APPLE_NOTARIZATION_KEY_ID}.p8"
if ! printf '%s' "$APPLE_NOTARIZATION_KEY_P8" | base64 --decode > "$private_key_path" 2> /dev/null; then
if ! printf '%s' "$APPLE_NOTARIZATION_KEY_P8" | base64 -D > "$private_key_path" 2> /dev/null; then
echo "APPLE_NOTARIZATION_KEY_P8 must be a base64-encoded .p8 private key." >&2
exit 2
fi
fi
chmod 600 "$private_key_path"

api_key_path="$notarization_temp_dir/app-store-connect-api-key.json"
rcodesign encode-app-store-connect-api-key \
--output-path "$api_key_path" \
"$APPLE_NOTARIZATION_ISSUER_ID" \
"$APPLE_NOTARIZATION_KEY_ID" \
"$private_key_path" \
> "$report_dir/encode-app-store-connect-api-key.log" 2>&1

notarization_log="$report_dir/dmg-notarization.log"
rcodesign notarize \
--api-key-file "$api_key_path" \
python3 "$(dirname "$0")/notarize_with_akv.py" \
--file "$dmg_path" \
--report-log "$report_dir/dmg-notarization-developer-log.json" \
--max-wait-seconds "$max_wait_seconds" \
--staple \
"$dmg_path" \
2>&1 | tee "$notarization_log"

rcodesign staple "$dmg_path" 2>&1 | tee -a "$notarization_log"

{
echo "dmg_path=$dmg_path"
echo "max_wait_seconds=$max_wait_seconds"
echo "dmg_sha256=$(shasum -a 256 "$dmg_path" | awk '{ print $1 }')"
echo "rcodesign_notarize_staple=completed"
echo "notarization_staple=completed"
} > "$report_dir/dmg-notarization-summary.txt"
Loading
Loading