Skip to content

fix(macos): pin intel runtime llvm version #61

fix(macos): pin intel runtime llvm version

fix(macos): pin intel runtime llvm version #61

name: macOS Latest Release
on:
push:
branches:
- main
workflow_dispatch:
inputs:
allow_unsigned:
description: "Allow ad-hoc signed macOS artifacts when Apple signing secrets are unavailable"
required: false
default: "false"
type: choice
options:
- "true"
- "false"
permissions:
contents: write
concurrency:
group: macos-latest-release
cancel-in-progress: true
jobs:
build-macos:
name: Build macOS ${{ matrix.target }}
runs-on: ${{ matrix.runner }}
outputs:
signing_mode: ${{ steps.prepare-signing.outputs.signing_mode }}
strategy:
fail-fast: false
matrix:
include:
- target: aarch64-apple-darwin
runner: macos-15
- target: x86_64-apple-darwin
runner: macos-15-intel
env:
ALLOW_UNSIGNED: ${{ github.event_name == 'workflow_dispatch' && inputs.allow_unsigned || 'false' }}
MACOS_BUNDLE_RUNTIME: "1"
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Setup uv
uses: astral-sh/setup-uv@v5
with:
enable-cache: true
cache-dependency-glob: |
pyproject.toml
uv.lock
- name: Setup LLVM for Intel runtime build
if: ${{ matrix.target == 'x86_64-apple-darwin' }}
shell: bash
run: |
set -euo pipefail
brew install llvm@20
llvm_prefix="$(brew --prefix llvm@20)"
echo "${llvm_prefix}/bin" >> "$GITHUB_PATH"
echo "LLVM_DIR=${llvm_prefix}/lib/cmake/llvm" >> "$GITHUB_ENV"
echo "CMAKE_PREFIX_PATH=${llvm_prefix}:${CMAKE_PREFIX_PATH:-}" >> "$GITHUB_ENV"
echo "LDFLAGS=-L${llvm_prefix}/lib ${LDFLAGS:-}" >> "$GITHUB_ENV"
echo "CPPFLAGS=-I${llvm_prefix}/include ${CPPFLAGS:-}" >> "$GITHUB_ENV"
- name: Cache macOS runtime payloads
uses: actions/cache@v4
with:
path: ~/Library/Caches/ElephantAgent/macos-runtime/${{ matrix.target }}
key: macos-runtime-${{ matrix.target }}-${{ hashFiles('pyproject.toml', 'uv.lock', 'apps/macos/Scripts/build-app.sh', 'apps/macos/Scripts/package-runtime.sh') }}
restore-keys: |
macos-runtime-${{ matrix.target }}-
- name: Prepare Apple signing
id: prepare-signing
shell: bash
env:
APPLE_CERTIFICATE_BASE64: ${{ secrets.APPLE_CERTIFICATE_BASE64 }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
APPLE_PASSWORD_FALLBACK: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
run: |
set -euo pipefail
notary_password="${APPLE_APP_SPECIFIC_PASSWORD:-${APPLE_PASSWORD_FALLBACK:-}}"
missing=()
for var in APPLE_CERTIFICATE_BASE64 APPLE_CERTIFICATE_PASSWORD APPLE_SIGNING_IDENTITY APPLE_ID APPLE_TEAM_ID; do
if [ -z "${!var:-}" ]; then
missing+=("$var")
fi
done
if [ -z "${notary_password}" ]; then
missing+=("APPLE_APP_SPECIFIC_PASSWORD or APPLE_PASSWORD")
fi
if [ "${#missing[@]}" -gt 0 ]; then
if [ "${ALLOW_UNSIGNED}" = "true" ]; then
echo "::warning::Apple signing secrets are missing; publishing ad-hoc signed artifacts. These are useful for CI artifacts but are not Gatekeeper-smooth for general users."
printf 'Missing: %s\n' "${missing[*]}"
echo "MACOS_SIGNING_IDENTITY=-" >> "$GITHUB_ENV"
echo "MACOS_NOTARIZE=0" >> "$GITHUB_ENV"
echo "MACOS_RELEASE_SIGNING_MODE=ad-hoc" >> "$GITHUB_ENV"
echo "signing_mode=ad-hoc" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "::error::Apple signing/notarization secrets are required for automatic latest releases."
printf 'Missing: %s\n' "${missing[*]}"
exit 1
fi
echo "::add-mask::${notary_password}"
keychain_path="${RUNNER_TEMP}/elephant-signing.keychain-db"
keychain_password="$(openssl rand -base64 32)"
certificate_path="${RUNNER_TEMP}/apple-signing.p12"
echo "::add-mask::${keychain_password}"
echo "${APPLE_CERTIFICATE_BASE64}" | base64 --decode > "${certificate_path}"
security create-keychain -p "${keychain_password}" "${keychain_path}"
security set-keychain-settings -lut 21600 "${keychain_path}"
security unlock-keychain -p "${keychain_password}" "${keychain_path}"
security import "${certificate_path}" \
-k "${keychain_path}" \
-P "${APPLE_CERTIFICATE_PASSWORD}" \
-T /usr/bin/codesign \
-T /usr/bin/security
security set-key-partition-list -S apple-tool:,apple: -s -k "${keychain_password}" "${keychain_path}"
security list-keychains -d user -s "${keychain_path}" $(security list-keychains -d user | tr -d '"')
echo "Available codesigning identities:"
security find-identity -v -p codesigning "${keychain_path}"
resolved_identity="$(
security find-identity -v -p codesigning "${keychain_path}" \
| awk '/Developer ID Application|Mac Developer ID Application/ { print $2; exit }'
)"
if [ -z "${resolved_identity}" ]; then
echo "::error::No Developer ID Application identity is available after importing the p12 certificate."
exit 1
fi
echo "MACOS_SIGNING_IDENTITY=${resolved_identity}" >> "$GITHUB_ENV"
echo "MACOS_NOTARIZE=1" >> "$GITHUB_ENV"
echo "MACOS_RELEASE_SIGNING_MODE=developer-id-notarized" >> "$GITHUB_ENV"
echo "signing_mode=developer-id-notarized" >> "$GITHUB_OUTPUT"
echo "APPLE_ID=${APPLE_ID}" >> "$GITHUB_ENV"
echo "APPLE_PASSWORD=${notary_password}" >> "$GITHUB_ENV"
echo "APPLE_TEAM_ID=${APPLE_TEAM_ID}" >> "$GITHUB_ENV"
- name: Build macOS artifact
shell: bash
env:
MACOS_APP_BUILD_NUMBER: ${{ github.run_number }}
run: |
make macos-build MACOS_TARGET="${{ matrix.target }}" MACOS_BUNDLE_RUNTIME="${MACOS_BUNDLE_RUNTIME}"
- name: Verify self-contained runtime
shell: bash
run: |
set -euo pipefail
app="apps/macos/.build/release/${{ matrix.target }}/Elephant Agent.app"
runtime="${app}/Contents/Resources/Runtime"
test -x "${runtime}/python/bin/python3.12"
test -d "${runtime}/site-packages"
test -d "${runtime}/ms-playwright"
test -f "${runtime}/manifest.json"
du -sh "${app}" "${runtime}"
- name: Verify signing and notarization
shell: bash
run: |
set -euo pipefail
app="apps/macos/.build/release/${{ matrix.target }}/Elephant Agent.app"
dmg="$(find "apps/macos/.build/artifacts/${{ matrix.target }}" -maxdepth 1 -name 'ElephantAgent_*_${{ matrix.target }}.dmg' -print -quit)"
test -n "${dmg}"
codesign --verify --deep --strict --verbose=2 "${app}"
codesign --verify --verbose=2 "${dmg}"
if [ "${MACOS_SIGNING_IDENTITY}" != "-" ]; then
xcrun stapler validate "${app}"
xcrun stapler validate "${dmg}"
spctl -a -vvv -t exec "${app}"
spctl -a -vvv -t open --context context:primary-signature "${dmg}"
fi
- name: Upload macOS artifact
uses: actions/upload-artifact@v4
with:
name: macos-${{ matrix.target }}
path: apps/macos/.build/artifacts/${{ matrix.target }}/*
if-no-files-found: error
retention-days: 14
publish-latest:
name: Publish latest release
runs-on: ubuntu-latest
needs:
- build-macos
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download macOS artifacts
uses: actions/download-artifact@v4
with:
pattern: macos-*
path: release-assets
merge-multiple: true
- name: Replace latest release
shell: bash
env:
GH_TOKEN: ${{ github.token }}
GITHUB_TOKEN: ${{ github.token }}
MACOS_ASSET_DIR: ${{ github.workspace }}/release-assets
MACOS_RELEASE_TAG: latest
MACOS_RELEASE_TITLE: Elephant Agent latest
MACOS_RELEASE_SIGNING_MODE: ${{ needs.build-macos.outputs.signing_mode || 'unknown' }}
run: |
bash apps/macos/Scripts/release-latest.sh