Build macOS #6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 | |