- Pin PostHog to 3.62.0 (vendored PLCrashReporter, drops external plcrashreporter dependency that fails with Xcode 26/Swift 6) - Update project.yml and pbxproj minimumVersion - Delete Package.resolved to force clean SPM resolution - Add -resolvePackageDependencies step in CI workflow - Add -skipPackagePluginValidation to build command - Fix docs/ci-cd-setup.md manual build command
6.5 KiB
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 installed and registered
brew(Homebrew) installedxcodegen—brew install xcodegen(also installed automatically by the workflow)
1. Register the macOS Runner
# On the Mac:
./act_runner register \
--instance https://gitea.1000co.fr \
--token <RUNNER_TOKEN> \
--name "macos-runner" \
--labels macos
# Start the runner
./act_runner daemon
Important: The runner must have the label
macosbecause the workflow usesruns-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 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 metadatawrite:issue— to post LGTM commentswrite:pull_request— to merge approved PRs
3. Xcode Signing
The workflow uses automatic code signing. Ensure:
-
The Mac runner is signed into an Apple Developer account in Xcode:
# Verify: xcrun security find-identity -v -p codesigning -
The Apple ID used must be part of the team
2MJF39L8VY(configured inExportOptions.plist). -
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 .gitea/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:
# 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
- Go to Firebase Console
- Click Add project (or select an existing one)
- Follow the wizard to create the project (Google Analytics is optional)
6.2 Enable App Distribution
- In the Firebase Console, open your project
- Navigate to App Distribution in the left sidebar
- Click Get started to enable the service
6.3 Get the App ID
- Go to Project Settings (gear icon) → General
- Scroll down to Your apps → find the iOS app
- Copy the App ID (looks like
1:123456789012:ios:abc123def456)
6.4 Create a Service Account
- Go to Project Settings → Service accounts
- Click Create service account (or use Firebase Admin SDK → Generate new private key)
- Give it a name like
github-actions-deploy - Assign the role: Firebase App Distribution Admin
- Click Generate new private key → download the JSON file
6.5 Encode the Service Account Key
# 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
- In Firebase Console, go to App Distribution → Testers & Groups
- Click Add group → name it
millian-test - Click Add testers → enter Millian's email
- Add the tester to the
millian-testgroup
6.7 Install the Firebase App Tester on the iPhone
- Send an invite to Millian's iPhone from the Firebase Console
- Millian accepts the invite and installs the Firebase App Tester app from the App Store
- Open the app and sign in with the invited Google account
- 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:
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:
- Open
tabatago-swift/project.yml - Find the
TabataGoWatchWidgettarget section - Ensure it has an explicit
settings:block with the team ID:target: TabataGoWatchWidget settings: base: DEVELOPMENT_TEAM: "2MJF39L8VY"
General Build Debugging
- Run
xcodegen generatebefore every build to ensure the project is in sync - Check
xcodebuildoutput for specific file/line errors - Verify SPM packages resolve:
xcodebuild -resolvePackageDependencies