Files
orca/.github/workflows/release-mac-build.yml
T
Jinwoo Hong a5f7da4928 revert(daemon): ship official Node in the macOS terminal host again, keep stall telemetry (#33688)
Reverts #29133 except its daemon async-I/O stall telemetry, so we can measure how often stalls happen on official Node before committing to a patched runtime. The macOS terminal host goes back to the official Node 24.22.1 download and the daemon protocol back to v51; no release or hourly build published v52.
2026-10-25 20:07:30 -04:00

264 lines
11 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: Release macOS Build
run-name: Mac release build ${{ inputs.tag }} (${{ inputs.release_run_id }})
on:
workflow_dispatch:
inputs:
tag:
description: Release tag whose draft should receive macOS artifacts
required: true
type: string
release_run_id:
description: release-cut workflow run that requested this build
required: true
type: string
qualification_only:
description: Sign and notarize both architectures without publishing a release
required: false
default: false
type: boolean
javascript_source_sha:
description: Commit of the shared JavaScript artifact; empty keeps the legacy build
required: false
default: ''
type: string
permissions:
# actions: read downloads the orcad template the parent release-cut run built.
actions: read
contents: write
concurrency:
# Why: a qualification run that reuses a live tag must never queue behind or replace its release build.
group: release-mac-build-${{ inputs.tag }}${{ inputs.qualification_only && '-qualification' || '' }}
cancel-in-progress: false
jobs:
qualification-template:
if: inputs.qualification_only
permissions:
contents: read
actions: read
uses: ./.github/workflows/qualified-orcad-template.yml
with:
ref: ${{ github.sha }}
build-mac:
needs: qualification-template
if: ${{ !cancelled() && (!inputs.qualification_only || needs.qualification-template.result == 'success') && github.repository == 'stablyai/orca' }}
# Keep Blacksmith mac notarization outside SignPath’s GitHub-hosted Windows provenance.
runs-on: blacksmith-6vcpu-macos-15
timeout-minutes: 60
# actions: read fetches the release-cut run's artifacts.
permissions:
actions: read
contents: write
env:
ORCA_BACKGROUND_LAUNCH: '1'
NODE_OPTIONS: --max-old-space-size=4096
steps:
- name: Checkout
uses: actions/checkout@v6
with:
ref: ${{ inputs.qualification_only && github.sha || format('refs/tags/{0}', inputs.tag) }}
# Why: a relay-era ref (before #27215) needs the Windows relay addon this build no longer compiles.
- name: Refuse a ref that still ships the SSH relay
shell: bash
run: |
if [[ -e config/tsconfig.relay.json ]]; then
echo "::error::This ref predates #27215 and still ships the SSH relay; build a commit at or after 2b4b60a87e."
exit 1
fi
- name: Restore draft-publish scripts from the workflow ref
env:
WORKFLOW_SHA: ${{ github.workflow_sha }}
run: |
set -euo pipefail
git fetch --no-tags --depth=1 origin "$WORKFLOW_SHA"
git checkout "$WORKFLOW_SHA" -- config/scripts/assert-github-release-is-draft.mjs
- name: Setup pnpm
uses: pnpm/setup@v2
with:
install: false
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version-file: package.json
check-latest: true
cache: pnpm
cache-dependency-path: |
pnpm-lock.yaml
mobile/pnpm-lock.yaml
# Cache bundled host Node by exact pin, without restore keys.
- name: Locate the pinned Node runtime cache
shell: bash
run: echo "ORCA_NODE_RUNTIME_CACHE_DIR=$HOME/Library/Caches/orca-node-runtime" >>"$GITHUB_ENV"
- name: Cache the pinned Node runtime
uses: actions/cache@v5
with:
path: ~/Library/Caches/orca-node-runtime
key: orca-node-runtime-mac-${{ hashFiles('src/shared/node-runtime-pin.ts') }}
# Cache Electron/builder tool downloads to save ~30–90s.
- name: Cache electron-builder downloads
uses: actions/cache@v5
with:
path: |
~/Library/Caches/electron
~/Library/Caches/electron-builder
key: electron-builder-mac-${{ hashFiles('pnpm-lock.yaml') }}
restore-keys: |
electron-builder-mac-
# Retry transient Electron CDN 504s; install both x64/arm64 optional natives for dual macOS packages.
- name: Install dependencies
uses: nick-fields/retry@v4
with:
timeout_minutes: 10
max_attempts: 3
retry_wait_seconds: 30
command: pnpm install --frozen-lockfile --cpu=current,x64,arm64
# Build required out/mobile-web using mobile’s React Native/Expo install.
- uses: ./.github/actions/install-mobile-dependencies
- name: Verify macOS signing environment
run: node config/scripts/verify-macos-release-env.mjs
env:
CSC_LINK: ${{ secrets.MAC_CERTS }}
CSC_KEY_PASSWORD: ${{ secrets.MAC_CERTS_PASSWORD }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
# Check duplicate entitlements before build: plutil lint accepts duplicates but codesign rejects them.
- name: Verify macOS entitlements
run: pnpm verify:macos-entitlements
# Set literal stable/rc telemetry identity through Vite define.
- name: Classify release tag for telemetry build identity
id: tag-classify
shell: bash
env:
TAG: ${{ inputs.tag }}
run: |
set -euo pipefail
# Suffixed vX.Y.Z-rc.N.perf builds keep the same rc-channel telemetry identity.
if [[ "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+(\.[0-9A-Za-z]+)?$ ]]; then
identity=rc
elif [[ "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
identity=stable
else
echo "::error::Tag $TAG does not match stable or rc pattern; refusing to build official artifact"
exit 1
fi
echo "identity=$identity" >>"$GITHUB_OUTPUT"
echo "Classified $TAG as $identity"
- name: Download release JavaScript from the release run
if: inputs.javascript_source_sha != ''
uses: actions/download-artifact@v8
with:
name: release-javascript
path: .build/release-javascript
run-id: ${{ inputs.release_run_id }}
github-token: ${{ github.token }}
- name: Build app
run: |
if [ -n "$ORCA_RELEASE_JAVASCRIPT_SOURCE_SHA" ]; then
node config/scripts/release-javascript-artifact.mjs restore
pnpm run build:release:host
else
pnpm run build:release
fi
env:
# Why: Vite's web build crossed Node's default old-space ceiling on
# the macOS release runner, leaving v1.4.2-rc.8 as an incomplete draft.
NODE_OPTIONS: --max-old-space-size=4096
ORCA_BUILD_IDENTITY: ${{ steps.tag-classify.outputs.identity }}
ORCA_RELEASE_JAVASCRIPT_SOURCE_SHA: ${{ inputs.javascript_source_sha }}
ORCA_DIAGNOSTICS_TOKEN_URL: https://www.onorca.dev/diagnostics/token
ORCA_POSTHOG_WRITE_KEY: ${{ secrets.ORCA_POSTHOG_WRITE_KEY }}
# Design D2: the parent release-cut run merged it from every node-server lane at this tag.
- name: Download the orcad deployment template from the release run
# Why: release-cut skips the template for a tag that predates it.
if: hashFiles('config/scripts/packaged-orcad-template.cjs') != ''
uses: actions/download-artifact@v8
with:
name: orcad-template
path: out/orcad-template
run-id: ${{ inputs.qualification_only && github.run_id || inputs.release_run_id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Gate runtime file-watcher process isolation
run: |
# #8212: require Node and the exact Electron runtime to survive native SIGSEGV before packaging.
node config/scripts/runtime-file-watcher-fault-harness.mjs
ELECTRON_RUN_AS_NODE=1 pnpm exec electron config/scripts/runtime-file-watcher-fault-harness.mjs
- name: Abort if the parent release-cut run was cancelled
if: ${{ !inputs.qualification_only }}
# Watch parent cancellation: separately dispatched mac upload otherwise continues (v1.4.206 went public with partial assets).
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PARENT_RUN: ${{ inputs.release_run_id }}
run: |
set -euo pipefail
conclusion="$(gh api "repos/$GITHUB_REPOSITORY/actions/runs/$PARENT_RUN" --jq '.conclusion // empty')"
if [[ "$conclusion" == "cancelled" || "$conclusion" == "failure" || "$conclusion" == "timed_out" ]]; then
echo "::error::Parent release-cut run $PARENT_RUN is $conclusion; refusing to publish mac artifacts."
exit 1
fi
- name: Publish release artifacts (macOS)
uses: nick-fields/retry@v4
with:
timeout_minutes: 45
max_attempts: 3
retry_wait_seconds: 30
command: node --disable-warning=MODULE_TYPELESS_PACKAGE_JSON config/scripts/pinned-node-downloads.mjs darwin-arm64 darwin-x64 && node config/scripts/ensure-native-runtime.mjs --runtime=electron && if [ -f config/scripts/build-mac-notarization-overlap.mjs ]; then ORCA_MAC_RELEASE=1 node config/scripts/build-mac-notarization-overlap.mjs --publish "$ORCA_MAC_PUBLISH" --draft; else ORCA_MAC_RELEASE=1 pnpm exec electron-builder --config config/electron-builder.config.cjs --mac --publish "$ORCA_MAC_PUBLISH" -c.publish.releaseType=draft; fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ORCA_REQUIRE_ORCAD_TEMPLATE: '1'
ORCA_MAC_PUBLISH: ${{ inputs.qualification_only && 'never' || 'always' }}
CSC_LINK: ${{ secrets.MAC_CERTS }}
CSC_KEY_PASSWORD: ${{ secrets.MAC_CERTS_PASSWORD }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
- name: Verify release remains draft after artifact upload
if: ${{ !inputs.qualification_only }}
# Re-draft premature builder publication before failing; latest must not keep an incomplete Windows release.
shell: bash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ inputs.tag }}
run: node config/scripts/assert-github-release-is-draft.mjs "${{ inputs.tag }}"
# Check after publish because builder’s single pack/upload invocation has no cheap interposition point.
- name: Verify telemetry constants present in app.asar
run: node config/scripts/verify-telemetry-constants.mjs
- name: Upload qualification artifacts
if: inputs.qualification_only
uses: actions/upload-artifact@v7
with:
name: mac-notarization-qualification
path: |
dist/*.dmg
dist/*.zip
dist/*.blockmap
dist/*.yml
if-no-files-found: error
retention-days: 7