# CI/CD Setup — iPhone Deploy Workflow This guide covers setting up a **Gitea Actions** macOS runner to automatically build, test, and deploy **TabataGo** to a physical iPhone on every PR to `main`. ## Prerequisites ### Hardware - **Mac** running macOS 15 (Sequoia) or later - **Xcode 26+** installed (required for iOS 26.0 / watchOS 11.0 targets) - **iPhone** (iOS 26+) with the Firebase App Tester app installed ### Software - [Gitea Actions Runner](https://docs.gitea.com/usage/actions/act-runner) installed and registered - `brew` (Homebrew) installed - `xcodegen` — `brew install xcodegen` (also installed automatically by the workflow) ## 1. Register the macOS Runner ```bash # On the Mac: ./act_runner register \ --instance https://gitea.1000co.fr \ --token \ --name "macos-runner" \ --labels macos # Start the runner ./act_runner daemon ``` > **Important:** The runner must have the label `macos` because the workflow uses `runs-on: macos`. ## 2. Configure Secrets Add these secrets in the Gitea repository: `Settings → Actions → Secrets` | Secret Name | Description | How to Get | |-------------|-------------|------------| | `FIREBASE_APP_ID` | Firebase App ID (iOS app) | Firebase Console → Project Settings → General → App ID | | `FIREBASE_SERVICE_ACCOUNT` | Base64-encoded Firebase service account JSON key | See [Firebase Setup](#6-firebase-app-distribution-setup) below | | `GITEA_TOKEN` | Gitea API token with repo + pull request scope | `Gitea → Settings → Applications → Generate Token` | ### Gitea Token Permissions The token needs: - `read:repository` — to read PR metadata - `write:issue` — to post LGTM comments - `write:pull_request` — to merge approved PRs ## 3. Xcode Signing The workflow uses **automatic code signing**. Ensure: 1. The Mac runner is signed into an Apple Developer account in Xcode: ```bash # Verify: xcrun security find-identity -v -p codesigning ``` 2. The Apple ID used must be part of the team `2MJF39L8VY` (configured in `ExportOptions.plist`). 3. For first-time setup, open Xcode on the runner Mac and sign in: ``` Xcode → Settings → Accounts → Add Apple ID ``` ## 4. Workflow Overview The workflow at `.github/workflows/pr-iphone-deploy.yml` triggers on PRs to `main`: ``` PR Opened / Updated ↓ Checkout + XcodeGen generate ↓ Resolve SPM packages ↓ Build + Archive IPA ↓ Upload to Firebase App Distribution ↓ Post "Ready to test" comment on PR ↓ Wait for LGTM → Auto-merge ``` ## 5. Manual Test Run To test the workflow locally on the runner Mac: ```bash # Simulate the build: cd tabatago-swift xcodegen generate xcodebuild build \ -project TabataGo.xcodeproj \ -target TabataGo \ -sdk iphoneos \ -destination "generic/platform=iOS" \ -configuration Release \ -allowProvisioningUpdates \ -skipPackagePluginValidation \ CODE_SIGN_STYLE=Automatic ``` ## 6. Firebase App Distribution Setup ### 6.1 Create a Firebase Project 1. Go to [Firebase Console](https://console.firebase.google.com) 2. Click **Add project** (or select an existing one) 3. Follow the wizard to create the project (Google Analytics is optional) ### 6.2 Enable App Distribution 1. In the Firebase Console, open your project 2. Navigate to **App Distribution** in the left sidebar 3. Click **Get started** to enable the service ### 6.3 Get the App ID 1. Go to **Project Settings** (gear icon) → **General** 2. Scroll down to **Your apps** → find the iOS app 3. Copy the **App ID** (looks like `1:123456789012:ios:abc123def456`) ### 6.4 Create a Service Account 1. Go to **Project Settings** → **Service accounts** 2. Click **Create service account** (or use Firebase Admin SDK → Generate new private key) 3. Give it a name like `github-actions-deploy` 4. Assign the role: **Firebase App Distribution Admin** 5. Click **Generate new private key** → download the JSON file ### 6.5 Encode the Service Account Key ```bash # Convert the JSON key to a base64 string (single line, no wrapping) base64 -i firebase-key.json | tr -d '\n' ``` Copy the output — this is your `FIREBASE_SERVICE_ACCOUNT` secret value. ### 6.6 Add Testers and Groups 1. In Firebase Console, go to **App Distribution** → **Testers & Groups** 2. Click **Add group** → name it `millian-test` 3. Click **Add testers** → enter Millian's email 4. Add the tester to the `millian-test` group ### 6.7 Install the Firebase App Tester on the iPhone 1. Send an invite to Millian's iPhone from the Firebase Console 2. Millian accepts the invite and installs the **Firebase App Tester** app from the App Store 3. Open the app and sign in with the invited Google account 4. The app will now receive builds pushed from the CI workflow ## Troubleshooting | Issue | Solution | |-------|----------| | "Code signing failed" | Sign into Xcode on the runner Mac, verify team membership | | "No provisioning profile" | Run `-allowProvisioningUpdates` or open project in Xcode once | | `xcodegen: command not found` | `brew install xcodegen` (workflow handles this) | | Runner doesn't pick up job | Verify runner label is `macos` and runner is connected | | Token permission errors | Ensure `GITEA_TOKEN` has `write:issue` and `write:pull_request` scopes | | Firebase upload fails | Verify `FIREBASE_APP_ID` and `FIREBASE_SERVICE_ACCOUNT` secrets are set correctly | | "App not found" in Firebase | Check that the iOS app is registered in Firebase with the correct bundle ID | | Testers don't receive build | Verify tester is in the `millian-test` group and has accepted the invite | ## Compilation Error Troubleshooting ### xcodegen Clearing Signing Team After running `xcodegen generate`, the `.xcodeproj` may have a cleared signing team. Always re-check your team settings: ```bash cd tabatago-swift xcodegen generate # Then check that project.yml has the correct team ID in settings ``` ### Complication Targets Missing Team ID Targets like **TabataGoWatchWidget** (watchOS complications) require an explicit team ID in `project.yml` settings. If you see signing errors for the widget target: 1. Open `tabatago-swift/project.yml` 2. Find the `TabataGoWatchWidget` target section 3. Ensure it has an explicit `settings:` block with the team ID: ```yaml target: TabataGoWatchWidget settings: base: DEVELOPMENT_TEAM: "2MJF39L8VY" ``` ### General Build Debugging - Run `xcodegen generate` before every build to ensure the project is in sync - Check `xcodebuild` output for specific file/line errors - Verify SPM packages resolve: `xcodebuild -resolvePackageDependencies`