#!/bin/bash
|
# Formal direct-download release guardrail for Aligner.
|
# This script is intentionally separate from package-app.sh, which remains the
|
# local QA package entry and may use ad-hoc or local-only signing.
|
|
set -euo pipefail
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
OUTPUT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
SOURCE_ROOT="$OUTPUT_ROOT/C1.source"
|
INFO_PLIST="$SOURCE_ROOT/Resources/Aligner-Info.plist"
|
|
fail() {
|
echo "release-app.sh failed: $*" >&2
|
exit 1
|
}
|
|
usage() {
|
cat <<'USAGE'
|
Usage:
|
03-O/C3.tools/release-app.sh --check-tools
|
03-O/C3.tools/release-app.sh --check-config
|
03-O/C3.tools/release-app.sh --check-notary-profile
|
|
Required environment for a real public release:
|
ALIGNER_DEVELOPER_IDENTITY="Developer ID Application: ..."
|
ALIGNER_NOTARY_PROFILE="<notarytool keychain profile>"
|
ALIGNER_RELEASE_GITHUB_REPOSITORY="<owner/repo>"
|
|
Phase 1 currently establishes release-chain guardrails only. It refuses to
|
produce a public release until Developer ID signing, notarization, stapling,
|
Gatekeeper validation, manifest generation, and upload policy are all wired.
|
USAGE
|
}
|
|
read_plist_value() {
|
/usr/libexec/PlistBuddy -c "Print :$1" "$INFO_PLIST" 2>/dev/null \
|
|| fail "unable to read $1 from $INFO_PLIST"
|
}
|
|
assert_tool() {
|
command -v "$1" >/dev/null 2>&1 || fail "missing required tool: $1"
|
}
|
|
assert_xcrun_tool() {
|
xcrun --find "$1" >/dev/null 2>&1 || fail "missing required xcrun tool: $1"
|
}
|
|
assert_tools() {
|
assert_tool codesign
|
assert_tool hdiutil
|
assert_tool shasum
|
assert_tool spctl
|
assert_tool xcrun
|
assert_xcrun_tool notarytool
|
assert_xcrun_tool stapler
|
|
echo "Release tools OK"
|
}
|
|
assert_config() {
|
local version
|
local build
|
local minimum_macos
|
|
assert_tools
|
|
version="$(read_plist_value CFBundleShortVersionString)"
|
build="$(read_plist_value CFBundleVersion)"
|
minimum_macos="$(read_plist_value LSMinimumSystemVersion)"
|
|
[[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] \
|
|| fail "CFBundleShortVersionString must be MAJOR.MINOR.PATCH, got: $version"
|
[[ "$build" =~ ^[0-9]{8}\.[0-9]{4}$ ]] \
|
|| fail "CFBundleVersion must be YYYYMMDD.HHMM, got: $build"
|
[[ "$minimum_macos" =~ ^[0-9]+(\.[0-9]+)?$ ]] \
|
|| fail "LSMinimumSystemVersion must be numeric, got: $minimum_macos"
|
[ "$minimum_macos" = "14.0" ] \
|
|| fail "LSMinimumSystemVersion must be 14.0 for Round01.5 macOS 14 compatibility, got: $minimum_macos"
|
|
if [ -z "${ALIGNER_DEVELOPER_IDENTITY:-}" ]; then
|
fail "missing ALIGNER_DEVELOPER_IDENTITY; formal releases must use Developer ID Application signing"
|
fi
|
if [[ "${ALIGNER_DEVELOPER_IDENTITY:-}" != Developer\ ID\ Application:* ]]; then
|
fail "ALIGNER_DEVELOPER_IDENTITY must start with 'Developer ID Application:'"
|
fi
|
if [ -z "${ALIGNER_NOTARY_PROFILE:-}" ]; then
|
fail "missing ALIGNER_NOTARY_PROFILE; formal releases must use notarytool"
|
fi
|
if [ -z "${ALIGNER_RELEASE_GITHUB_REPOSITORY:-}" ]; then
|
fail "missing ALIGNER_RELEASE_GITHUB_REPOSITORY; expected owner/repo for GitHub Releases"
|
fi
|
if [[ "${ALIGNER_RELEASE_GITHUB_REPOSITORY:-}" != */* ]]; then
|
fail "ALIGNER_RELEASE_GITHUB_REPOSITORY must use owner/repo format"
|
fi
|
|
echo "Release config OK for Aligner $version build $build, minimum macOS $minimum_macos"
|
}
|
|
assert_notary_profile() {
|
assert_config
|
|
xcrun notarytool history \
|
--keychain-profile "$ALIGNER_NOTARY_PROFILE" \
|
--output-format json >/dev/null 2>&1 \
|
|| fail "notarytool profile is not usable: $ALIGNER_NOTARY_PROFILE"
|
|
echo "Notary profile OK: $ALIGNER_NOTARY_PROFILE"
|
}
|
|
case "${1:-}" in
|
--check-tools)
|
assert_tools
|
;;
|
--check-config)
|
assert_config
|
;;
|
--check-notary-profile)
|
assert_notary_profile
|
;;
|
-h|--help)
|
usage
|
;;
|
"")
|
assert_config
|
fail "formal release packaging is not enabled in Phase 1 skeleton yet"
|
;;
|
*)
|
usage
|
fail "unknown argument: $1"
|
;;
|
esac
|