44 target :
55 description : Rust compilation target triple (e.g. aarch64-apple-darwin).
66 required : true
7+ sign-binaries :
8+ description : Whether to sign and notarize the macOS binaries.
9+ required : false
10+ default : " true"
11+ sign-dmg :
12+ description : Whether to sign and notarize the macOS DMG.
13+ required : false
14+ default : " true"
15+ dmg-path :
16+ description : Path to the DMG to sign and notarize (defaults to codex-rs/target/<target>/release/codex-<target>.dmg).
17+ required : false
718 apple-certificate :
819 description : Base64-encoded Apple signing certificate (P12).
920 required : true
@@ -107,6 +118,7 @@ runs:
107118 echo "::add-mask::$APPLE_CODESIGN_IDENTITY"
108119
109120 - name : Sign macOS binaries
121+ if : ${{ inputs.sign-binaries == 'true' }}
110122 shell : bash
111123 run : |
112124 set -euo pipefail
@@ -127,6 +139,7 @@ runs:
127139 done
128140
129141 - name : Notarize macOS binaries
142+ if : ${{ inputs.sign-binaries == 'true' }}
130143 shell : bash
131144 env :
132145 APPLE_NOTARIZATION_KEY_P8 : ${{ inputs.apple-notarization-key-p8 }}
@@ -197,66 +210,88 @@ runs:
197210 notarize_submission "$binary" "$archive_path"
198211 }
199212
200- build_dmg() {
201- local target="${{ inputs.target }} "
202- local release_dir="codex-rs/target/${target}/release"
203- local dmg_root="${RUNNER_TEMP}/codex-dmg-root"
204- local volname="Codex (${target})"
205- local dmg_path="${release_dir}/codex-${target}.dmg"
206-
207- rm -rf "$dmg_root"
208- mkdir -p "$dmg_root"
209-
210- for binary in codex codex-responses-api-proxy; do
211- local bin_path="${release_dir}/${binary}"
212- if [[ ! -f "$bin_path" ]]; then
213- echo "Binary $bin_path not found"
214- exit 1
215- fi
216- ditto "$bin_path" "${dmg_root}/${binary}"
217- done
218-
219- rm -f "$dmg_path"
220- hdiutil create \
221- -volname "$volname" \
222- -srcfolder "$dmg_root" \
223- -format UDZO \
224- -ov \
225- "$dmg_path "
226-
227- export CODEX_DMG_PATH="$dmg_path"
228- echo "CODEX_DMG_PATH=$dmg_path" >> "$GITHUB_ENV "
213+ notarize_binary "codex"
214+ notarize_binary "codex-responses-api-proxy "
215+
216+ - name : Sign and notarize macOS DMG
217+ if : ${{ inputs.sign-dmg == 'true' }}
218+ shell : bash
219+ env :
220+ APPLE_NOTARIZATION_KEY_P8 : ${{ inputs.apple-notarization-key-p8 }}
221+ APPLE_NOTARIZATION_KEY_ID : ${{ inputs.apple-notarization-key-id }}
222+ APPLE_NOTARIZATION_ISSUER_ID : ${{ inputs.apple-notarization-issuer-id }}
223+ run : |
224+ set -euo pipefail
225+
226+ if [[ -z "${APPLE_CODESIGN_IDENTITY:-}" ]]; then
227+ echo "APPLE_CODESIGN_IDENTITY is required for macOS signing"
228+ exit 1
229+ fi
230+
231+ for var in APPLE_NOTARIZATION_KEY_P8 APPLE_NOTARIZATION_KEY_ID APPLE_NOTARIZATION_ISSUER_ID; do
232+ if [[ -z "${!var:-}" ]]; then
233+ echo "$var is required for notarization"
234+ exit 1
235+ fi
236+ done
237+
238+ notary_key_path="${RUNNER_TEMP}/notarytool.key.p8 "
239+ echo "$APPLE_NOTARIZATION_KEY_P8" | base64 -d > "$notary_key_path"
240+ cleanup_notary() {
241+ rm -f "$notary_key_path "
229242 }
243+ trap cleanup_notary EXIT
230244
231- sign_dmg() {
232- local dmg_path="$1"
245+ notarize_submission() {
246+ local label="$1"
247+ local path="$2"
233248
234- if [[ -z "${APPLE_CODESIGN_IDENTITY:-} " ]]; then
235- echo "APPLE_CODESIGN_IDENTITY is required for macOS signing "
249+ if [[ ! -f "$path " ]]; then
250+ echo "Notarization payload $path not found "
236251 exit 1
237252 fi
238253
239- keychain_args=()
240- if [[ -n "${APPLE_CODESIGN_KEYCHAIN:-}" && -f "${APPLE_CODESIGN_KEYCHAIN}" ]]; then
241- keychain_args+=(--keychain "${APPLE_CODESIGN_KEYCHAIN}")
254+ submission_json=$(xcrun notarytool submit "$path" \
255+ --key "$notary_key_path" \
256+ --key-id "$APPLE_NOTARIZATION_KEY_ID" \
257+ --issuer "$APPLE_NOTARIZATION_ISSUER_ID" \
258+ --output-format json \
259+ --wait)
260+
261+ status=$(printf '%s\n' "$submission_json" | jq -r '.status // "Unknown"')
262+ submission_id=$(printf '%s\n' "$submission_json" | jq -r '.id // ""')
263+
264+ if [[ -z "$submission_id" ]]; then
265+ echo "Failed to retrieve submission ID for $label"
266+ exit 1
242267 fi
243268
244- codesign --force --timestamp --sign "$APPLE_CODESIGN_IDENTITY" "${keychain_args[@]}" "$dmg_path"
245- }
269+ echo "::notice title=Notarization::$label submission ${submission_id} completed with status ${status}"
246270
247- notarize_binary "codex"
248- notarize_binary "codex-responses-api-proxy"
271+ if [[ "$status" != "Accepted" ]]; then
272+ echo "Notarization failed for ${label} (submission ${submission_id}, status ${status})"
273+ exit 1
274+ fi
275+ }
249276
250- build_dmg
277+ dmg_path="${{ inputs.dmg-path }}"
278+ if [[ -z "$dmg_path" ]]; then
279+ dmg_path="codex-rs/target/${{ inputs.target }}/release/codex-${{ inputs.target }}.dmg"
280+ fi
251281
252- if [[ -z "${CODEX_DMG_PATH:-} " ]]; then
253- echo "CODEX_DMG_PATH not set after building DMG "
282+ if [[ ! -f "$dmg_path " ]]; then
283+ echo "DMG $dmg_path not found "
254284 exit 1
255285 fi
256286
257- sign_dmg "$CODEX_DMG_PATH"
258- notarize_submission "codex-${{ inputs.target }}.dmg" "$CODEX_DMG_PATH"
259- xcrun stapler staple "$CODEX_DMG_PATH"
287+ keychain_args=()
288+ if [[ -n "${APPLE_CODESIGN_KEYCHAIN:-}" && -f "${APPLE_CODESIGN_KEYCHAIN}" ]]; then
289+ keychain_args+=(--keychain "${APPLE_CODESIGN_KEYCHAIN}")
290+ fi
291+
292+ codesign --force --timestamp --sign "$APPLE_CODESIGN_IDENTITY" "${keychain_args[@]}" "$dmg_path"
293+ notarize_submission "codex-${{ inputs.target }}.dmg" "$dmg_path"
294+ xcrun stapler staple "$dmg_path"
260295
261296 - name : Remove signing keychain
262297 if : ${{ always() }}
0 commit comments