Ariver
2026-07-13 14a1efc86d0295be3a0d3fe1ebe7b8080266da2d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/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