235 lines
8.7 KiB
YAML
235 lines
8.7 KiB
YAML
name: Alpha Channel (macOS arm64)
|
|
|
|
# Every app-related push to `dev` publishes a fresh macOS arm64 build to the
|
|
# single rolling `alpha-macos-latest` release. Each run appends
|
|
# uniquely-versioned dmg, zip, and blockmap assets, then re-uploads
|
|
# `latest-mac.yml` last so the manifest never references missing assets.
|
|
#
|
|
# Assets older than the retention window are pruned. Per-run GitHub releases
|
|
# are no longer created.
|
|
#
|
|
# See .github/workflows/release-macos-aarch64.yml for the stable channel.
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- dev
|
|
paths:
|
|
- apps/app/**
|
|
- apps/desktop/**
|
|
- apps/server/**
|
|
- packages/docs/**
|
|
- packages/enterprise-mcp-client/**
|
|
- packages/handsfree/**
|
|
- packages/install-config/**
|
|
- packages/paths/**
|
|
- packages/types/**
|
|
- packages/ui/**
|
|
- patches/**
|
|
- scripts/release/**
|
|
- constants.json
|
|
- package.json
|
|
- pnpm-lock.yaml
|
|
- pnpm-workspace.yaml
|
|
- .github/workflows/alpha-macos-aarch64.yml
|
|
workflow_dispatch:
|
|
inputs:
|
|
publish:
|
|
description: "Publish the packaged build to the alpha channel release (leave off for build-only validation)"
|
|
required: false
|
|
type: boolean
|
|
default: false
|
|
channel_tag:
|
|
description: "Channel release tag to publish to (override for staging validation)"
|
|
required: false
|
|
type: string
|
|
default: "alpha-macos-latest"
|
|
|
|
permissions:
|
|
contents: write
|
|
|
|
concurrency:
|
|
group: alpha-macos-aarch64-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
publish-alpha-macos-aarch64:
|
|
name: Build + Publish alpha (aarch64-apple-darwin)
|
|
runs-on: macos-14
|
|
timeout-minutes: 180
|
|
|
|
env:
|
|
ALPHA_RELEASE_NAME: OpenWork Alpha (macOS arm64)
|
|
# Apple signing + notarization are required so alpha bundles install
|
|
# and launch without Gatekeeper friction. Alpha builds are served
|
|
# from GitHub Releases like stable, just from a different tag.
|
|
MACOS_NOTARIZE: ${{ vars.MACOS_NOTARIZE || 'true' }}
|
|
OPENWORK_DESKTOP_SENTRY_DSN: ${{ secrets.OPENWORK_DESKTOP_SENTRY_DSN || vars.OPENWORK_DESKTOP_SENTRY_DSN }}
|
|
OPENWORK_DESKTOP_SENTRY_TRACES_SAMPLE_RATE: ${{ vars.OPENWORK_DESKTOP_SENTRY_TRACES_SAMPLE_RATE || '0.01' }}
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
|
|
with:
|
|
ref: ${{ github.sha }}
|
|
# Alpha versions are computed from the latest stable v* tag
|
|
# (package.json holds a permanent 0.0.0-dev placeholder).
|
|
fetch-depth: 0
|
|
|
|
- name: Setup Node
|
|
uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6
|
|
with:
|
|
node-version: 24
|
|
|
|
- name: Setup pnpm
|
|
uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4
|
|
with:
|
|
version: 11.4.0
|
|
|
|
- name: Setup Bun
|
|
uses: oven-sh/setup-bun@f4d14e03ff726c06358e5557344e1da148b56cf7 # v1
|
|
with:
|
|
bun-version: "1.3.6"
|
|
|
|
- name: Get pnpm store path
|
|
id: pnpm-store
|
|
shell: bash
|
|
run: echo "path=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Cache pnpm store
|
|
uses: actions/cache@caa296126883cff596d87d8935842f9db880ef25 # v5
|
|
continue-on-error: true
|
|
with:
|
|
path: ${{ steps.pnpm-store.outputs.path }}
|
|
key: macos-pnpm-${{ hashFiles('pnpm-lock.yaml') }}
|
|
restore-keys: |
|
|
macos-pnpm-
|
|
|
|
- name: Install dependencies
|
|
run: pnpm install --frozen-lockfile --prefer-offline
|
|
|
|
- name: Resolve alpha version
|
|
id: alpha-version
|
|
shell: bash
|
|
env:
|
|
GITHUB_RUN_NUMBER: ${{ github.run_number }}
|
|
GITHUB_SHA: ${{ github.sha }}
|
|
run: |
|
|
set -euo pipefail
|
|
# Alpha builds advertise the *next* patch after the latest stable
|
|
# tag so semver comparison makes the alpha newer than the current
|
|
# stable (e.g. stable 0.11.207 < alpha 0.11.208-alpha.<run>). Once
|
|
# stable 0.11.208 ships, its semver beats the alpha prerelease tag
|
|
# and alpha users cleanly migrate forward. Tags are the version
|
|
# source of truth — package.json is a permanent placeholder.
|
|
base="$(node scripts/release/versions.mjs next --bump patch)"
|
|
run="${GITHUB_RUN_NUMBER:-0}"
|
|
sha="$(printf '%.7s' "${GITHUB_SHA:-local}")"
|
|
echo "alpha_version=${base}-alpha.${run}+${sha}" >> "$GITHUB_OUTPUT"
|
|
echo "base_version=${base}" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Write alpha Electron package version
|
|
shell: bash
|
|
env:
|
|
ALPHA_VERSION: ${{ steps.alpha-version.outputs.alpha_version }}
|
|
run: node scripts/release/stamp-version.mjs --version "$ALPHA_VERSION"
|
|
|
|
- name: Write notary API key
|
|
if: env.MACOS_NOTARIZE == 'true'
|
|
env:
|
|
APPLE_NOTARY_API_KEY_P8_BASE64: ${{ secrets.APPLE_NOTARY_API_KEY_P8_BASE64 }}
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
NOTARY_KEY_PATH="$RUNNER_TEMP/AuthKey.p8"
|
|
printf '%s' "$APPLE_NOTARY_API_KEY_P8_BASE64" | base64 --decode > "$NOTARY_KEY_PATH"
|
|
chmod 600 "$NOTARY_KEY_PATH"
|
|
|
|
echo "NOTARY_KEY_PATH=$NOTARY_KEY_PATH" >> "$GITHUB_ENV"
|
|
|
|
- name: Reject unsigned Electron alpha release
|
|
if: env.MACOS_NOTARIZE != 'true'
|
|
shell: bash
|
|
run: |
|
|
echo "Electron alpha artifacts must be signed and notarized. Set MACOS_NOTARIZE=true and provide Apple signing secrets." >&2
|
|
exit 1
|
|
|
|
- name: Build Electron alpha app
|
|
if: env.MACOS_NOTARIZE == 'true'
|
|
shell: bash
|
|
env:
|
|
TARGET: aarch64-apple-darwin
|
|
run: pnpm --filter @openwork/desktop build:electron
|
|
|
|
- name: Package Electron alpha (macOS, signed + notarized)
|
|
if: env.MACOS_NOTARIZE == 'true'
|
|
env:
|
|
CSC_LINK: ${{ secrets.APPLE_CODESIGN_CERT_P12_BASE64 }}
|
|
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CODESIGN_CERT_PASSWORD }}
|
|
MACOS_NOTARIZE: true
|
|
APPLE_API_KEY: ${{ secrets.APPLE_NOTARY_API_KEY_ID }}
|
|
APPLE_API_ISSUER: ${{ secrets.APPLE_NOTARY_API_ISSUER_ID }}
|
|
APPLE_API_KEY_PATH: ${{ env.NOTARY_KEY_PATH }}
|
|
run: |
|
|
set -euo pipefail
|
|
pnpm --dir apps/desktop exec electron-builder \
|
|
--config electron-builder.yml \
|
|
--mac \
|
|
--arm64 \
|
|
--publish never
|
|
|
|
- name: Publish alpha build to rolling release
|
|
if: env.MACOS_NOTARIZE == 'true' && (github.event_name == 'push' || inputs.publish == true)
|
|
shell: bash
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
CHANNEL_TAG: ${{ inputs.channel_tag || 'alpha-macos-latest' }}
|
|
run: |
|
|
set -euo pipefail
|
|
# Alpha assets may only ever land on alpha channel releases. This
|
|
# guard makes it impossible to clobber a stable release (and its
|
|
# latest-mac.yml) via a mistyped channel_tag dispatch input.
|
|
case "$CHANNEL_TAG" in
|
|
alpha-macos-*) ;;
|
|
*)
|
|
echo "Refusing to publish alpha assets to non-alpha tag: $CHANNEL_TAG" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
if ! gh release view "$CHANNEL_TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
|
|
gh release create "$CHANNEL_TAG" \
|
|
--repo "$GITHUB_REPOSITORY" \
|
|
--title "$ALPHA_RELEASE_NAME" \
|
|
--notes "Rolling alpha channel for OpenWork macOS arm64 builds. Each publish adds versioned updater assets and advances the channel manifest." \
|
|
--target "$GITHUB_SHA" \
|
|
--prerelease
|
|
fi
|
|
|
|
shopt -s nullglob
|
|
assets=(
|
|
apps/desktop/dist-electron/*.dmg
|
|
apps/desktop/dist-electron/*.zip
|
|
apps/desktop/dist-electron/*.blockmap
|
|
)
|
|
if [ ${#assets[@]} -eq 0 ]; then
|
|
echo "No Electron alpha assets found in apps/desktop/dist-electron" >&2
|
|
exit 1
|
|
fi
|
|
gh release upload "$CHANNEL_TAG" "${assets[@]}" \
|
|
--repo "$GITHUB_REPOSITORY" \
|
|
--clobber
|
|
|
|
# Publish the manifest last so an interrupted upload never points at missing assets.
|
|
gh release upload "$CHANNEL_TAG" apps/desktop/dist-electron/latest-mac.yml \
|
|
--repo "$GITHUB_REPOSITORY" \
|
|
--clobber
|
|
|
|
- name: Prune alpha assets beyond retention window
|
|
if: env.MACOS_NOTARIZE == 'true' && (github.event_name == 'push' || inputs.publish == true)
|
|
shell: bash
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
CHANNEL_TAG: ${{ inputs.channel_tag || 'alpha-macos-latest' }}
|
|
run: node scripts/release/prune-alpha-assets.mjs --repo "$GITHUB_REPOSITORY" --tag "$CHANNEL_TAG" --keep 100
|