From e7b9ccb9ed2352f1ffaacb8a15d00db9cb2670db Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Sat, 3 Oct 2026 21:38:21 -0700 Subject: [PATCH 1/4] Add GitHub Actions CI: compile app and tests for iOS on every PR Builds the OpenVision scheme with build-for-testing for a generic iOS device with code signing disabled, on the free macos-26 runner, so a PR that doesn't compile is caught before review. Copies the example xcconfig into place, caches SwiftPM checkouts keyed on the project pins, pins Xcode 26.6 via DEVELOPER_DIR, and uploads xcactivitylogs when the build fails. Co-Authored-By: Claude Fable 5.1 --- .github/workflows/ci.yml | 75 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..d512053f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,75 @@ +name: CI + +# Compiles the app and its test target on every pull request and push to main, so a PR that +# doesn't build never reaches a reviewer. The build is for a generic iOS device with code +# signing off: that proves the code compiles against the SDK without needing certificates, +# and it matches how the app is actually run (on a phone; the simulator can't do Bluetooth +# or on-device MLX). +# +# Standard GitHub-hosted macOS runners are free for public repositories. Keep this on the +# plain `macos-*` labels — "larger" runners are billed even for public repos. + +on: + pull_request: + push: + branches: [main] + +concurrency: + group: ci-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +env: + # Pin the Xcode on the image so a runner image update can't change the SDK underneath a PR. + # Bump deliberately (and check the pinned mlx-swift-lm still compiles) when moving to a new + # Xcode. Xcode 27 is not on GitHub's images yet; see actions/runner-images. + DEVELOPER_DIR: /Applications/Xcode_26.6.app/Contents/Developer + +jobs: + build: + name: Build app + tests (iOS device, unsigned) + runs-on: macos-26 + timeout-minutes: 90 + steps: + - uses: actions/checkout@v4 + + - name: Provide Config.xcconfig + # The project refuses to build without it; the example's placeholder values are enough + # to compile. Real values only matter at runtime on a device. + run: cp Config.xcconfig.example Config.xcconfig + + - name: Cache Swift packages + # Package.resolved is gitignored (whole xcworkspace), so key on the files that hold + # the pins. The MLX, Kokoro and Meta DAT checkouts are the slow part of a cold build. + uses: actions/cache@v4 + with: + path: .spm + key: spm-${{ runner.os }}-${{ hashFiles('OpenVision.xcodeproj/project.pbxproj', 'project.yml') }} + restore-keys: spm-${{ runner.os }}- + + - name: Show toolchain + run: | + xcodebuild -version + xcrun --sdk iphoneos --show-sdk-version + + - name: Build for testing + run: | + set -o pipefail + xcodebuild build-for-testing \ + -project OpenVision.xcodeproj \ + -scheme OpenVision \ + -destination 'generic/platform=iOS' \ + -clonedSourcePackagesDirPath .spm \ + -derivedDataPath DerivedData \ + CODE_SIGNING_ALLOWED=NO \ + CODE_SIGNING_REQUIRED=NO \ + CODE_SIGN_IDENTITY= \ + DEVELOPMENT_TEAM= \ + | xcbeautify --renderer github-actions + + - name: Upload build log on failure + if: failure() + uses: actions/upload-artifact@v4 + with: + name: xcodebuild-logs + path: DerivedData/Logs/Build/*.xcactivitylog + if-no-files-found: ignore From a8504dab0b8781a68ec6239e1e5ac59c86bc4c61 Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Sat, 3 Oct 2026 21:41:50 -0700 Subject: [PATCH 2/4] CI: skip package plugin and macro validation The first run failed at "Validate plug-in CudaBuild in package mlx-swift": Xcode won't run third-party build plugins or macros unapproved, and CI has no one to approve them. Co-Authored-By: Claude Fable 5.1 --- .github/workflows/ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d512053f..0996214c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,6 +52,8 @@ jobs: xcrun --sdk iphoneos --show-sdk-version - name: Build for testing + # mlx-swift ships a build plugin (CudaBuild) and mlx-swift-lm uses Swift macros; Xcode + # refuses both until a human approves them, which is what the two -skip flags do here. run: | set -o pipefail xcodebuild build-for-testing \ @@ -60,6 +62,8 @@ jobs: -destination 'generic/platform=iOS' \ -clonedSourcePackagesDirPath .spm \ -derivedDataPath DerivedData \ + -skipPackagePluginValidation \ + -skipMacroValidation \ CODE_SIGNING_ALLOWED=NO \ CODE_SIGNING_REQUIRED=NO \ CODE_SIGN_IDENTITY= \ From 4418360374268fe344c1e435a97ee5cab9a86695 Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Sat, 3 Oct 2026 21:48:12 -0700 Subject: [PATCH 3/4] CI: also copy Config.swift.example into place Second run got through package resolution and the MLX targets and stopped only on the other gitignored file the README has contributors copy. Co-Authored-By: Claude Fable 5.1 --- .github/workflows/ci.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0996214c..28f32471 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,10 +32,13 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Provide Config.xcconfig - # The project refuses to build without it; the example's placeholder values are enough - # to compile. Real values only matter at runtime on a device. - run: cp Config.xcconfig.example Config.xcconfig + - name: Provide the gitignored config files + # Same two copies the README asks a new contributor to make. The project refuses to + # build without them; the examples' placeholder values are enough to compile, and the + # real values only matter at runtime on a device. + run: | + cp Config.xcconfig.example Config.xcconfig + cp OpenVision/Config/Config.swift.example OpenVision/Config/Config.swift - name: Cache Swift packages # Package.resolved is gitignored (whole xcworkspace), so key on the files that hold From 6e04f8368ef343fdd6c778bc364351c2e6b5083d Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Sat, 3 Oct 2026 21:57:31 -0700 Subject: [PATCH 4/4] README: add CI status badge Co-Authored-By: Claude Fable 5.1 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9a05dc73..fbd56f7a 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ [![Swift 5](https://img.shields.io/badge/Swift-5-orange.svg)](https://swift.org) [![iOS 18+](https://img.shields.io/badge/iOS-18+-blue.svg)](https://developer.apple.com/ios/) [![Latest release](https://img.shields.io/github/v/release/rayl15/OpenVision?color=2ea44f)](https://github.com/rayl15/OpenVision/releases) +[![CI](https://github.com/rayl15/OpenVision/actions/workflows/ci.yml/badge.svg)](https://github.com/rayl15/OpenVision/actions/workflows/ci.yml) [![Stars](https://img.shields.io/github/stars/rayl15/OpenVision?logo=github)](https://github.com/rayl15/OpenVision/stargazers) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/rayl15/OpenVision/blob/main/CONTRIBUTING.md) [![good first issues](https://img.shields.io/github/issues/rayl15/OpenVision/good%20first%20issue?color=7057ff&label=good%20first%20issues)](https://github.com/rayl15/OpenVision/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)