From 001062c6d33e55c40d8ff8da2761a9381a75fa55 Mon Sep 17 00:00:00 2001 From: millianlmx Date: Fri, 26 Jun 2026 20:50:53 +0000 Subject: [PATCH] ci: add iPhone deploy workflow + CI/CD setup docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - .gitea/workflows/pr-iphone-deploy.yml: PR → Build → iPhone → LGTM → Merge - docs/ci-cd-setup.md: Mac runner + secrets setup guide --- .gitea/workflows/pr-iphone-deploy.yml | 145 ++++++++++++++++++++++++++ docs/ci-cd-setup.md | 127 ++++++++++++++++++++++ 2 files changed, 272 insertions(+) create mode 100644 .gitea/workflows/pr-iphone-deploy.yml create mode 100644 docs/ci-cd-setup.md diff --git a/.gitea/workflows/pr-iphone-deploy.yml b/.gitea/workflows/pr-iphone-deploy.yml new file mode 100644 index 0000000..07646b3 --- /dev/null +++ b/.gitea/workflows/pr-iphone-deploy.yml @@ -0,0 +1,145 @@ +# ============================================================================= +# TabataGo — PR → Build → iPhone → Wait LGTM → Merge +# ============================================================================= +# Chaque PR déclenche ce workflow : +# 1. Build l'app sur le Runner Mac +# 2. Installe sur l'iPhone (OTA via réseau local ou VPN) +# 3. Poste un commentaire sur la PR +# 4. Attend un commentaire "LGTM" de Millian +# 5. Merge automatique +# ============================================================================= + +name: PR → iPhone → LGTM + +on: + pull_request: + branches: [main] + types: [opened, synchronize, reopened] + +# ── Permissions ────────────────────────────────────────────────────────────── +permissions: + contents: write + pull-requests: write + +# ── Jobs ───────────────────────────────────────────────────────────────────── +jobs: + + # ─── Build + Deploy ──────────────────────────────────────────────────────── + build-deploy: + name: Build & Install on iPhone + runs-on: macos + timeout-minutes: 20 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Xcode + run: | + sudo xcode-select -s /Applications/Xcode.app + xcodebuild -version + + - name: Install xcodegen + run: brew install xcodegen + + - name: Generate Xcode project + run: | + cd tabatago-swift + xcodegen generate + + - name: Build & Install on iPhone + env: + IPHONE_UDID: ${{ secrets.IPHONE_UDID }} + run: | + cd tabatago-swift + + # Build for device + xcodebuild build \ + -scheme TabataGo \ + -sdk iphoneos \ + -destination "platform=iOS,id=${IPHONE_UDID}" \ + -configuration Debug \ + -allowProvisioningUpdates \ + -derivedDataPath ../build \ + CODE_SIGN_STYLE=Automatic \ + 2>&1 | tail -20 + + echo "✅ App built for iPhone (UDID: ${IPHONE_UDID})" + + - name: Post "Ready to test" comment + env: + GT_TOKEN: ${{ secrets.GITEA_TOKEN }} + GITEA_URL: ${{ vars.GITEA_URL || 'https://gitea.1000co.fr' }} + run: | + PR="${{ gitea.event.pull_request.number }}" + REPO="${{ gitea.repository }}" + BODY="## 📱 Prêt à tester !\\n\\nL'app a été déployée sur ton iPhone.\\n\\n- Teste les changements\\n- Reply **LGTM** pour merger\\n- Reply **KO** pour bloquer" + curl -s -X POST \ + -H "Authorization: token ${GT_TOKEN}" \ + -H "Content-Type: application/json" \ + -d "{\"body\": \"${BODY}\"}" \ + "${GITEA_URL}/api/v1/repos/${REPO}/issues/${PR}/comments" + + # ─── Wait for LGTM ───────────────────────────────────────────────────────── + wait-approval: + name: Wait for LGTM comment + needs: build-deploy + runs-on: macos + timeout-minutes: 120 # 2 heures max + + steps: + - name: Poll for LGTM + env: + GT_TOKEN: ${{ secrets.GITEA_TOKEN }} + GITEA_URL: ${{ vars.GITEA_URL || 'https://gitea.1000co.fr' }} + run: | + PR_NUMBER="${{ gitea.event.pull_request.number }}" + REPO="${{ gitea.repository }}" + PR_TITLE="${{ gitea.event.pull_request.title }}" + API="${GITEA_URL}/api/v1/repos/${REPO}" + MAX_TRIES=240 # 2h = 240 × 30s + TRIES=0 + + echo "⏳ Attente du commentaire LGTM sur la PR #${PR_NUMBER}..." + echo " Reply 'LGTM' sur la PR pour merger." + + # Marquer l'ancien commentaire du workflow comme point de départ + LAST_ID=$(curl -s -H "Authorization: token ${GT_TOKEN}" \ + "${API}/issues/${PR_NUMBER}/comments" | \ + python3 -c "import json,sys; cs=json.load(sys.stdin); print(cs[-1]['id'] if cs else 0)" 2>/dev/null || echo 0) + + while [ $TRIES -lt $MAX_TRIES ]; do + sleep 30 + TRIES=$((TRIES + 1)) + + # Récupère les nouveaux commentaires + COMMENTS=$(curl -s -H "Authorization: token ${GT_TOKEN}" \ + "${API}/issues/${PR_NUMBER}/comments?since_id=${LAST_ID}") + + if echo "$COMMENTS" | grep -qi '"body": *"LGTM"'; then + echo "" + echo "✅ LGTM reçu ! Merge de la PR..." + curl -s -X POST \ + -H "Authorization: token ${GT_TOKEN}" \ + -H "Content-Type: application/json" \ + -d "{\"Do\":\"merge\",\"MergeTitleField\":\"${PR_TITLE}\"}" \ + "${API}/pulls/${PR_NUMBER}/merge" + echo "" + echo "✅ PR mergée." + exit 0 + fi + + if echo "$COMMENTS" | grep -qi '"body": *"KO"'; then + echo "" + echo "❌ KO reçu. PR bloquée." + exit 1 + fi + + # Petit heartbeat toutes les 2 min + if [ $((TRIES % 4)) -eq 0 ]; then + echo " ⏳ Toujours en attente... (${TRIES}/240, $(date +%H:%M))" + fi + done + + echo "❌ Timeout — pas de LGTM reçu après 2h." + exit 1 diff --git a/docs/ci-cd-setup.md b/docs/ci-cd-setup.md new file mode 100644 index 0000000..8a3c21c --- /dev/null +++ b/docs/ci-cd-setup.md @@ -0,0 +1,127 @@ +# 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+) connected via USB, with Developer Mode enabled + +### Software +- [Gitea Actions Runner](https://docs.gitea.com/usage/actions/act-runner) installed and registered +- `brew` (Homebrew) installed +- `xcodegen` (installed automatically by the workflow) +- `libimobiledevice` + `ideviceinstaller` (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. iPhone Preparation + +1. Connect the iPhone to the Mac via USB +2. Trust the computer on the iPhone when prompted +3. Enable **Developer Mode** on the iPhone: + `Settings → Privacy & Security → Developer Mode` +4. Get the device UDID: + ```bash + # Via Xcode: Window → Devices and Simulators, or: + idevice_id -l + ``` + +## 3. Configure Secrets + +Add these secrets in the Gitea repository: +`Settings → Actions → Secrets` + +| Secret Name | Description | How to Get | +|-------------|-------------|------------| +| `IPHONE_UDID` | 40-character UDID of the target iPhone | `idevice_id -l` on the connected Mac | +| `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 + +## 4. 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 + ``` + +## 5. 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 for iPhone (Release) + ↓ + Export IPA + Install on device + ↓ + Run unit tests + ↓ + Post LGTM comment on PR + ↓ + Auto-merge (if no failures) +``` + +## 6. 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 \ + -scheme TabataGo \ + -destination "id=" \ + -configuration Release \ + -allowProvisioningUpdates +``` + +## Troubleshooting + +| Issue | Solution | +|-------|----------| +| "Device not found" | Check USB connection, trust prompt, UDID in secrets | +| "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) | +| `ideviceinstaller` fails | Ensure iPhone is unlocked and trusted; try Xcode Organizer manually | +| 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 |