Co-authored-by: Alex Cheema <[email protected]>
This commit is contained in:
Sami Khan
2025-08-01 19:14:27 -07:00
committed by GitHub
co-authored by Alex Cheema
parent 71bafabc63
commit a46f8c3cd1
16 changed files with 1500 additions and 0 deletions
+198
View File
@@ -0,0 +1,198 @@
name: Build and Release Exo macOS App
on:
push:
tags:
- 'v*' # Trigger only on version tags
branches:
- main # Also build on main branch for testing
- app-staging # Add app-staging for testing
pull_request:
branches:
- main # Test builds on PRs
jobs:
build-exov2-macos:
runs-on: macos-15
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Rust (nightly)
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: nightly
components: rustfmt, clippy
default: true
- name: Set Rust toolchain override
run: |
rustup default nightly
cd rust && rustup override set nightly
- name: Install Go
uses: actions/setup-go@v5
with:
go-version: '1.21'
- name: Install Just
run: |
brew install just
- name: Install UV
uses: astral-sh/setup-uv@v6
with:
enable-cache: true
cache-dependency-glob: uv.lock
- name: Setup Python Environment
run: |
uv python install
uv sync --locked --all-extras
- name: Build Rust Components
env:
RUSTFLAGS: "-A unused-imports -A dead-code -A unreachable-code"
run: |
just build-all
- name: Install Python Bindings
run: |
uv pip install dist/exo_pyo3_bindings-*.whl
- name: Verify Python Environment
run: |
uv run python -c "import exo_pyo3_bindings; print('Python bindings installed successfully')"
uv run python -c "import master.main; print('Master module available')"
uv run python -c "import worker.main; print('Worker module available')"
- name: Prepare Code Signing Keychain
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
env:
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
PROVISIONING_PROFILE: ${{ secrets.PROVISIONING_PROFILE }}
run: |
security create-keychain -p "$MACOS_CERTIFICATE_PASSWORD" exov2.keychain
security default-keychain -s exov2.keychain
security unlock-keychain -p "$MACOS_CERTIFICATE_PASSWORD" exov2.keychain
echo "$MACOS_CERTIFICATE" | base64 --decode > /tmp/exov2-certificate.p12
security import /tmp/exov2-certificate.p12 -k exov2.keychain -P "$MACOS_CERTIFICATE_PASSWORD" -T /usr/bin/codesign
rm /tmp/exov2-certificate.p12
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CERTIFICATE_PASSWORD" exov2.keychain
PROFILES_HOME="$HOME/Library/Developer/Xcode/UserData/Provisioning Profiles"
mkdir -p "$PROFILES_HOME"
PROFILE_PATH="$(mktemp "$PROFILES_HOME"/EXOV2_PP.provisionprofile)"
echo "$PROVISIONING_PROFILE" | base64 --decode > "$PROFILE_PATH"
- name: Build Exo Swift App
env:
MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
run: |
cd app/exov2
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
if [[ "${{ github.event_name }}" == "push" && "${{ github.ref }}" == refs/tags/v* ]]; then
# Release build with code signing
security unlock-keychain -p "$MACOS_CERTIFICATE_PASSWORD" exov2.keychain
SIGNING_IDENTITY=$(security find-identity -v -p codesigning | awk -F '"' '{print $2}')
xcodebuild clean build \
-project exov2.xcodeproj \
-scheme exov2 \
-configuration Release \
-derivedDataPath build \
CODE_SIGNING_IDENTITY="$SIGNING_IDENTITY" \
PROVISIONING_PROFILE_SPECIFIER="Exo Provisioning Profile" \
CODE_SIGN_INJECT_BASE_ENTITLEMENTS=YES \
OTHER_CODE_SIGN_FLAGS="--timestamp"
else
# Debug build without code signing for testing
xcodebuild clean build \
-project exov2.xcodeproj \
-scheme exov2 \
-configuration Debug \
-derivedDataPath build \
CODE_SIGN_IDENTITY="" \
CODE_SIGNING_REQUIRED=NO
fi
mv build/Build/Products/*/exov2.app ../../
- name: Sign and Create DMG (Release only)
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
env:
APPLE_NOTARIZATION_USERNAME: ${{ secrets.APPLE_NOTARIZATION_USERNAME }}
APPLE_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_NOTARIZATION_PASSWORD }}
APPLE_NOTARIZATION_TEAM: ${{ secrets.APPLE_NOTARIZATION_TEAM }}
MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
run: |
security unlock-keychain -p "$MACOS_CERTIFICATE_PASSWORD" exov2.keychain
SIGNING_IDENTITY=$(security find-identity -v -p codesigning | awk -F '"' '{print $2}')
# Sign the app
/usr/bin/codesign --deep --force --timestamp --options runtime \
--sign "$SIGNING_IDENTITY" exov2.app
# Verify the signing
codesign -dvv exov2.app
# Create DMG
mkdir -p tmp/dmg-contents
cp -r ./exov2.app tmp/dmg-contents/
ln -s /Applications tmp/dmg-contents/Applications
VERSION=$(git describe --tags --abbrev=0 | sed 's/^v//')
# Create and sign DMG
hdiutil create -volname "Exo" -srcfolder tmp/dmg-contents -ov -format UDZO exov2-${VERSION}.dmg
/usr/bin/codesign --deep --force --timestamp --options runtime \
--sign "$SIGNING_IDENTITY" exov2-${VERSION}.dmg
# Setup notarization credentials (optional - comment out if no notarization secrets)
if [[ -n "$APPLE_NOTARIZATION_USERNAME" ]]; then
xcrun notarytool store-credentials notary_pass \
--apple-id "$APPLE_NOTARIZATION_USERNAME" \
--password "$APPLE_NOTARIZATION_PASSWORD" \
--team-id "$APPLE_NOTARIZATION_TEAM"
# Submit for notarization
xcrun notarytool submit --wait \
--team-id "$APPLE_NOTARIZATION_TEAM" \
--keychain-profile notary_pass \
exov2-${VERSION}.dmg
# Staple the notarization
xcrun stapler staple exov2-${VERSION}.dmg
fi
- name: Create DMG (Debug builds)
if: github.event_name != 'push' || !startsWith(github.ref, 'refs/tags/v')
run: |
mkdir -p tmp/dmg-contents
cp -r ./exov2.app tmp/dmg-contents/
ln -s /Applications tmp/dmg-contents/Applications
VERSION=$(git rev-parse --short HEAD)
hdiutil create -volname "Exo Debug" -srcfolder tmp/dmg-contents -ov -format UDZO exov2-debug-${VERSION}.dmg
- name: Cleanup Keychain
if: always() && github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
run: |
security default-keychain -s login.keychain
security delete-keychain exov2.keychain
- name: Upload DMG file
uses: actions/upload-artifact@v4
with:
name: exov2-dmg
path: exov2*.dmg
- name: Upload App Bundle
uses: actions/upload-artifact@v4
with:
name: exov2-app
path: exov2.app/