Skip to content

Build macOS

Build macOS #6

Workflow file for this run

name: Build macOS
on:
workflow_dispatch:
inputs:
version:
description: 'Version number (e.g., 0.2.0)'
required: true
type: string
deps_tag:
description: 'Deps release tag (e.g., deps-v1.0.0)'
required: true
type: string
arch:
description: 'Architecture'
required: false
type: choice
options:
- arm64
default: arm64
jobs:
build:
runs-on: macos-14 # M1 runner for arm64 support
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
channel: 'stable'
cache: true
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: aarch64-apple-darwin,x86_64-apple-darwin
- name: Cache Rust dependencies
uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
worker/target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-
- name: Download macOS dependencies
run: |
DEPS_VERSION="${{ inputs.deps_tag }}"
DEPS_VERSION="${DEPS_VERSION#deps-v}"
mkdir -p deps/macos-arm64 deps/macos-x64
# Download arm64 deps (zip contains flat structure, no wrapper folder)
if [[ "${{ inputs.arch }}" == "arm64" || "${{ inputs.arch }}" == "both" ]]; then
DEPS_URL="https://github.com/${{ github.repository }}/releases/download/${{ inputs.deps_tag }}/VapourBox-deps-${DEPS_VERSION}-macos-arm64.zip"
echo "Downloading arm64 deps from: $DEPS_URL"
curl -L -o deps-arm64.zip "$DEPS_URL"
unzip -o deps-arm64.zip -d deps/macos-arm64
rm -f deps-arm64.zip
fi
# Download x64 deps (zip contains flat structure, no wrapper folder)
if [[ "${{ inputs.arch }}" == "x64" || "${{ inputs.arch }}" == "both" ]]; then
DEPS_URL="https://github.com/${{ github.repository }}/releases/download/${{ inputs.deps_tag }}/VapourBox-deps-${DEPS_VERSION}-macos-x64.zip"
echo "Downloading x64 deps from: $DEPS_URL"
curl -L -o deps-x64.zip "$DEPS_URL"
unzip -o deps-x64.zip -d deps/macos-x64
rm -f deps-x64.zip
fi
echo "Dependencies extracted:"
ls -la deps/
- name: Setup CocoaPods
run: |
gem install cocoapods
- name: Update version numbers
run: |
VERSION="${{ inputs.version }}"
DEPS_TAG="${{ inputs.deps_tag }}"
DEPS_VERSION="${DEPS_TAG#deps-v}"
# Update pubspec.yaml
sed -i '' "s/^version: .*/version: ${VERSION}+1/" app/pubspec.yaml
# Update deps-version.json
sed -i '' "s/\"version\": \"[^\"]*\"/\"version\": \"${DEPS_VERSION}\"/" app/assets/deps-version.json
sed -i '' "s/\"releaseTag\": \"[^\"]*\"/\"releaseTag\": \"${DEPS_TAG}\"/" app/assets/deps-version.json
# Update macOS Info.plist
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $VERSION" app/macos/Runner/Info.plist
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $VERSION" app/macos/Runner/Info.plist
# Update Cargo.toml
sed -i '' "s/^version = \".*\"/version = \"${VERSION}\"/" worker/Cargo.toml
- name: Build Rust worker (arm64)
if: ${{ inputs.arch == 'arm64' || inputs.arch == 'both' }}
run: |
cd worker
cargo build --release --target aarch64-apple-darwin
- name: Build Rust worker (x64)
if: ${{ inputs.arch == 'x64' || inputs.arch == 'both' }}
run: |
cd worker
cargo build --release --target x86_64-apple-darwin
- name: Build Flutter app
run: |
cd app
flutter pub get
dart run build_runner build --delete-conflicting-outputs
# Try flutter build first — it generates ephemeral files needed by xcodebuild.
# It may fail with module dependency errors, which is OK.
flutter build macos --release || true
# Two-step xcodebuild — handles module dependency errors that flutter build can't
cd macos
rm -rf Pods Podfile.lock
pod install
# Build Pods-Runner scheme first (all CocoaPods dependencies)
xcodebuild -workspace Runner.xcworkspace -scheme Pods-Runner \
-configuration Release build ONLY_ACTIVE_ARCH=NO \
-quiet
# Build Runner for arm64 only (must match Podfile ARCHS setting)
xcodebuild -workspace Runner.xcworkspace -scheme Runner \
-configuration Release build ARCHS=arm64 ONLY_ACTIVE_ARCH=YES \
-quiet
# Copy to Flutter build location
DERIVED_APP=$(find ~/Library/Developer/Xcode/DerivedData/Runner-*/Build/Products/Release/vapourbox.app -maxdepth 0 2>/dev/null | head -1)
if [ -z "$DERIVED_APP" ]; then
echo "ERROR: Could not find built app in DerivedData"
exit 1
fi
mkdir -p ../build/macos/Build/Products/Release
cp -R "$DERIVED_APP" ../build/macos/Build/Products/Release/
- name: Package release (arm64)
if: ${{ inputs.arch == 'arm64' || inputs.arch == 'both' }}
run: |
./Scripts/package-macos.sh --version "${{ inputs.version }}" --arch arm64 --skip-build --no-sign
- name: Package release (x64)
if: ${{ inputs.arch == 'x64' || inputs.arch == 'both' }}
run: |
./Scripts/package-macos.sh --version "${{ inputs.version }}" --arch x64 --skip-build --no-sign
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: VapourBox-${{ inputs.version }}-macos
path: dist/VapourBox-${{ inputs.version }}-macos-*.dmg