Skip to content
Draft
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
15 changes: 11 additions & 4 deletions .github/actions/macos-code-sign/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ inputs:
binaries:
description: Space-delimited binary basenames to sign and notarize.
default: "codex codex-responses-api-proxy"
codesign-identifier:
description: Optional explicit code signing identifier to embed in signed binaries.
required: false
default: ""
sign-binaries:
description: Whether to sign and notarize the macOS binaries.
required: false
Expand Down Expand Up @@ -56,6 +60,7 @@ runs:
echo "$APPLE_CERTIFICATE" | base64 -d > "$cert_path"

keychain_path="${RUNNER_TEMP}/codex-signing.keychain-db"
echo "APPLE_CODESIGN_KEYCHAIN=$keychain_path" >> "$GITHUB_ENV"
security create-keychain -p "$KEYCHAIN_PASSWORD" "$keychain_path"
security set-keychain-settings -lut 21600 "$keychain_path"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$keychain_path"
Expand Down Expand Up @@ -114,7 +119,6 @@ runs:
rm -f "$cert_path"

echo "APPLE_CODESIGN_IDENTITY=$APPLE_CODESIGN_IDENTITY" >> "$GITHUB_ENV"
echo "APPLE_CODESIGN_KEYCHAIN=$keychain_path" >> "$GITHUB_ENV"
echo "::add-mask::$APPLE_CODESIGN_IDENTITY"

- name: Sign macOS binaries
Expand All @@ -123,6 +127,7 @@ runs:
env:
TARGET: ${{ inputs.target }}
BINARIES: ${{ inputs.binaries }}
CODESIGN_IDENTIFIER: ${{ inputs.codesign-identifier }}
run: |
set -euo pipefail

Expand All @@ -137,10 +142,14 @@ runs:
fi

entitlements_path="$GITHUB_ACTION_PATH/codex.entitlements.plist"
identifier_args=()
if [[ -n "${CODESIGN_IDENTIFIER:-}" ]]; then
identifier_args+=(--identifier "$CODESIGN_IDENTIFIER")
fi

for binary in ${BINARIES}; do
path="codex-rs/target/${TARGET}/release/${binary}"
codesign --force --options runtime --timestamp --entitlements "$entitlements_path" --sign "$APPLE_CODESIGN_IDENTITY" "${keychain_args[@]}" "$path"
codesign --force --options runtime --timestamp --entitlements "$entitlements_path" --sign "$APPLE_CODESIGN_IDENTITY" "${keychain_args[@]}" "${identifier_args[@]}" "$path"
done

- name: Notarize macOS binaries
Expand Down Expand Up @@ -238,8 +247,6 @@ runs:
- name: Remove signing keychain
if: ${{ always() }}
shell: bash
env:
APPLE_CODESIGN_KEYCHAIN: ${{ env.APPLE_CODESIGN_KEYCHAIN }}
run: |
set -euo pipefail
if [[ -n "${APPLE_CODESIGN_KEYCHAIN:-}" ]]; then
Expand Down
18 changes: 18 additions & 0 deletions .github/workflows/fork-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ concurrency:

jobs:
compute-release:
if: ${{ github.ref_name == 'stable' }}
runs-on: ubuntu-latest
outputs:
base_version: ${{ steps.compute.outputs.base_version }}
Expand All @@ -33,6 +34,7 @@ jobs:
python3 scripts/compute_fork_release.py --write-github-output

build:
if: ${{ github.ref_name == 'stable' }}
needs: compute-release
name: Build - ${{ matrix.target }}
runs-on: macos-15
Expand Down Expand Up @@ -194,6 +196,20 @@ jobs:
log_progress "[60%] Cargo build completed in ${duration_min}m (${duration_sec}s)"
append_summary "- [60%] Cargo build completed in ${duration_min}m (${duration_sec}s)"

- name: "[62%] Sign and notarize release binary"
uses: ./.github/actions/macos-code-sign
with:
target: ${{ matrix.target }}
binaries: codex
codesign-identifier: com.rickgetz.codex
sign-binaries: "true"
sign-dmg: "false"
apple-certificate: ${{ secrets.APPLE_CERTIFICATE_P12 }}
apple-certificate-password: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
apple-notarization-key-p8: ${{ secrets.APPLE_NOTARIZATION_KEY_P8 }}
apple-notarization-key-id: ${{ secrets.APPLE_NOTARIZATION_KEY_ID }}
apple-notarization-issuer-id: ${{ secrets.APPLE_NOTARIZATION_ISSUER_ID }}

- name: "[65%] Stage artifacts"
shell: bash
run: |
Expand All @@ -211,6 +227,7 @@ jobs:
path: dist/${{ matrix.target }}/*

release:
if: ${{ github.ref_name == 'stable' }}
needs:
- compute-release
- build
Expand Down Expand Up @@ -303,6 +320,7 @@ jobs:
dist/**/*.zst

publish-npm:
if: ${{ github.ref_name == 'stable' }}
needs: release
runs-on: ubuntu-latest
permissions:
Expand Down
36 changes: 32 additions & 4 deletions docs/fork-release.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,28 @@ fails if they contain secret-like paths such as `.npmrc`, `.env*`, `.ssh/`,
`.aws/`, or key/certificate files. The publish step also redacts auth-shaped
output before writing logs.

## One-time Apple signing setup

The fork release workflow signs and notarizes the Apple Silicon `codex` binary
before it is packaged for npm. The signed binary uses the code signing identifier
`com.rickgetz.codex`, which gives macOS Keychain a stable code identity across
npm upgrades.

Configure these GitHub Actions secrets before relying on the release workflow:

- `APPLE_CERTIFICATE_P12`: base64-encoded Developer ID Application certificate
exported as a `.p12`.
- `APPLE_CERTIFICATE_PASSWORD`: password for the exported `.p12`.
- `APPLE_NOTARIZATION_KEY_P8`: base64-encoded App Store Connect API key.
- `APPLE_NOTARIZATION_KEY_ID`: key ID for the notarization API key.
- `APPLE_NOTARIZATION_ISSUER_ID`: issuer ID for the notarization API key.

The workflow imports the certificate into a temporary keychain, signs with the
hardened runtime enabled, notarizes the binary, and deletes the temporary
keychain before the build job exits. The certificate and notarization key are
not added to any npm tarball; the publish job still audits tarball contents
before publishing.

## Automatic counter behavior

The workflow derives the upstream base version from `codex-rs/Cargo.toml` and
Expand All @@ -62,11 +84,17 @@ Merge or push to `stable` and the workflow will:
1. Read the base version from `codex-rs/Cargo.toml`.
2. Compute the next fork counter for that base release line.
3. Build the macOS release binaries with the derived display version.
4. Create the matching `rick-v<base>-rick.<n>` tag on the merge commit.
5. Generate GitHub release notes that separate fork changes from mainline
4. Sign and notarize the Apple Silicon `codex` binary with
`com.rickgetz.codex`.
5. Create the matching `rick-v<base>-rick.<n>` tag on the merge commit.
6. Generate GitHub release notes that separate fork changes from mainline
Codex refreshes.
6. Create a GitHub release.
7. Publish the npm package.
7. Create a GitHub release.
8. Publish the npm package.

Manual `workflow_dispatch` runs are guarded to `stable` as well. Dispatching the
workflow from another branch skips the release jobs so Apple signing secrets are
only exposed to the maintained release branch.

## Release notes

Expand Down
Loading