Revert "fix: improve iOS CI workflow with pipefail, fix Python indentation, add setup docs"
This reverts commit c1cbc02826.
This commit is contained in:
@@ -55,15 +55,14 @@ jobs:
|
||||
cd tabatago-swift
|
||||
xcodegen generate
|
||||
|
||||
- name: Build for iPhone
|
||||
- name: Build & Install on iPhone
|
||||
env:
|
||||
IPHONE_UDID: ${{ secrets.IPHONE_UDID }}
|
||||
run: |
|
||||
cd tabatago-swift
|
||||
|
||||
# Build for device (build only — installation requires USB/OTA tooling)
|
||||
# Use tee to capture full log while showing last 40 lines on stdout
|
||||
set -o pipefail
|
||||
# Use tee to capture full output while still streaming to stdout
|
||||
xcodebuild build \
|
||||
-scheme TabataGo \
|
||||
-sdk iphoneos \
|
||||
@@ -75,7 +74,7 @@ jobs:
|
||||
CODE_SIGN_STYLE=Automatic \
|
||||
2>&1 | tee ../build/xcodebuild.log | tail -40
|
||||
|
||||
BUILD_EXIT=$?
|
||||
BUILD_EXIT=${PIPESTATUS[0]}
|
||||
if [ $BUILD_EXIT -ne 0 ]; then
|
||||
echo ""
|
||||
echo "❌ Build FAILED (exit code: $BUILD_EXIT)"
|
||||
@@ -96,7 +95,7 @@ jobs:
|
||||
REPO="${{ github.repository }}"
|
||||
|
||||
RESP=$(curl -sk -w "\n%{http_code}" -X POST \
|
||||
-H "Authorization: token $GITEA_TOKEN \
|
||||
-H "Authorization: token $GITEA_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"body":"## 📱 Prêt à tester !\n\nL'"'"'app a été buildée pour ton iPhone.\n\n- Teste les changements\n- Reply **LGTM** pour merger\n- Reply **KO** pour bloquer"}' \
|
||||
"${GITEA_HOST}/api/v1/repos/${REPO}/issues/${PR}/comments")
|
||||
@@ -137,7 +136,7 @@ jobs:
|
||||
|
||||
# Récupérer le dernier ID de commentaire existant comme point de départ
|
||||
LAST_ID=$(curl -sk \
|
||||
-H "Authorization: token $GITEA_TOKEN \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
"${API}/issues/${PR_NUMBER}/comments" | \
|
||||
python3 -c "import json,sys; cs=json.load(sys.stdin); print(cs[-1]['id'] if isinstance(cs,list) and cs else 0)" 2>/dev/null || echo 0)
|
||||
|
||||
@@ -151,7 +150,7 @@ jobs:
|
||||
|
||||
# Récupérer tous les commentaires
|
||||
COMMENTS=$(curl -sk \
|
||||
-H "Authorization: token $GITEA_TOKEN \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
"${API}/issues/${PR_NUMBER}/comments" 2>/dev/null)
|
||||
|
||||
if [ -z "$COMMENTS" ]; then
|
||||
@@ -160,12 +159,12 @@ jobs:
|
||||
|
||||
# Vérifier les nouveaux commentaires (ID > LAST_ID)
|
||||
NEW_COMMENTS=$(echo "$COMMENTS" | python3 -c "
|
||||
import json, sys
|
||||
last_id = $LAST_ID
|
||||
cs = json.load(sys.stdin)
|
||||
new = [c for c in cs if isinstance(c, dict) and c.get('id', 0) > last_id]
|
||||
print(json.dumps(new))
|
||||
" 2>/dev/null)
|
||||
import json, sys
|
||||
last_id = $LAST_ID
|
||||
cs = json.load(sys.stdin)
|
||||
new = [c for c in cs if isinstance(c, dict) and c.get('id', 0) > last_id]
|
||||
print(json.dumps(new))
|
||||
" 2>/dev/null)
|
||||
|
||||
if [ -z "$NEW_COMMENTS" ] || [ "$NEW_COMMENTS" = "[]" ]; then
|
||||
# Petit heartbeat toutes les 2 min
|
||||
@@ -177,28 +176,28 @@ jobs:
|
||||
|
||||
# Mettre à jour LAST_ID au plus récent
|
||||
LAST_ID=$(echo "$COMMENTS" | python3 -c "
|
||||
import json, sys
|
||||
cs = json.load(sys.stdin)
|
||||
ids = [c['id'] for c in cs if isinstance(c, dict)]
|
||||
print(max(ids) if ids else 0)
|
||||
" 2>/dev/null || echo "$LAST_ID")
|
||||
import json, sys
|
||||
cs = json.load(sys.stdin)
|
||||
ids = [c['id'] for c in cs if isinstance(c, dict)]
|
||||
print(max(ids) if ids else 0)
|
||||
" 2>/dev/null || echo "$LAST_ID")
|
||||
|
||||
# Vérifier LGTM (insensible à la casse, dans le texte du commentaire)
|
||||
if echo "$NEW_COMMENTS" | python3 -c "
|
||||
import json, sys
|
||||
cs = json.load(sys.stdin)
|
||||
for c in cs:
|
||||
body = c.get('body', '')
|
||||
if 'lgtm' in body.strip().lower():
|
||||
print('MATCH')
|
||||
break
|
||||
" 2>/dev/null | grep -q MATCH; then
|
||||
import json, sys
|
||||
cs = json.load(sys.stdin)
|
||||
for c in cs:
|
||||
body = c.get('body', '')
|
||||
if 'lgtm' in body.strip().lower():
|
||||
print('MATCH')
|
||||
break
|
||||
" 2>/dev/null | grep -q MATCH; then
|
||||
echo ""
|
||||
echo "✅ LGTM reçu ! Merge de la PR..."
|
||||
MERGE_RESP=$(curl -sk -w "\n%{http_code}" -X POST \
|
||||
-H "Authorization: token $GITEA_TOKEN \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"Do\":\"merge\"}" \
|
||||
-d "{\"Do\":\"merge\",\"MergeTitle\":\"${{ github.event.pull_request.title }}\"}" \
|
||||
"${API}/pulls/${PR_NUMBER}/merge")
|
||||
|
||||
MERGE_HTTP=$(echo "$MERGE_RESP" | tail -1)
|
||||
@@ -215,14 +214,14 @@ jobs:
|
||||
|
||||
# Vérifier KO (insensible à la casse)
|
||||
if echo "$NEW_COMMENTS" | python3 -c "
|
||||
import json, sys
|
||||
cs = json.load(sys.stdin)
|
||||
for c in cs:
|
||||
body = c.get('body', '')
|
||||
if body.strip().lower() == 'ko':
|
||||
print('MATCH')
|
||||
break
|
||||
" 2>/dev/null | grep -q MATCH; then
|
||||
import json, sys
|
||||
cs = json.load(sys.stdin)
|
||||
for c in cs:
|
||||
body = c.get('body', '')
|
||||
if body.strip().lower() == 'ko':
|
||||
print('MATCH')
|
||||
break
|
||||
" 2>/dev/null | grep -q MATCH; then
|
||||
echo ""
|
||||
echo "❌ KO reçu. PR bloquée."
|
||||
exit 1
|
||||
|
||||
@@ -1,294 +0,0 @@
|
||||
# TabataGo CI/CD Setup Guide
|
||||
|
||||
> How to set up the Mac self-hosted runner and configure secrets for the
|
||||
> **PR → iPhone → LGTM** workflow.
|
||||
|
||||
## Overview
|
||||
|
||||
The `pr-iphone-deploy.yml` workflow (`.gitea/workflows/`) automates the
|
||||
test-and-merge cycle for every PR targeting `main`:
|
||||
|
||||
1. **Build** — Checks out the PR, generates the Xcode project via XcodeGen,
|
||||
and builds the TabataGo app for Millian's iPhone (device build).
|
||||
2. **Comment** — Posts a "Ready to test" comment on the PR.
|
||||
3. **Wait for LGTM** — Polls PR comments for up to **2 hours** waiting for
|
||||
Millian to reply `LGTM` (merge) or `KO` (block).
|
||||
4. **Auto-merge** — Merges the PR automatically when `LGTM` is received.
|
||||
|
||||
```
|
||||
┌────────────┐ ┌──────────────┐ ┌──────────────┐
|
||||
│ PR opened │ ──► │ Build iPhone │ ──► │ Wait LGTM/KO │
|
||||
│ / updated │ │ (macOS CI) │ │ (poll 2h) │
|
||||
└────────────┘ └──────────────┘ └──┬────────┬──┘
|
||||
│ │
|
||||
LGTM │ │ KO
|
||||
▼ ▼
|
||||
┌────────┐ ┌────────┐
|
||||
│ Merge │ │ Block │
|
||||
│ PR │ │ PR │
|
||||
└────────┘ └────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 1. Set Up the Mac Runner
|
||||
|
||||
You need a **macOS machine** (macOS 15+, Xcode 26+) registered as a
|
||||
self-hosted Gitea Actions runner.
|
||||
|
||||
### 1.1 Prerequisites on the Mac
|
||||
|
||||
```bash
|
||||
# Xcode 26+ (from App Store or Apple Developer)
|
||||
sudo xcode-select -s /Applications/Xcode.app
|
||||
|
||||
# XcodeGen (project generator)
|
||||
brew install xcodegen
|
||||
|
||||
# Python 3 (pre-installed on macOS, used by poll script)
|
||||
python3 --version # should be 3.x
|
||||
|
||||
# Xcode must be signed into an Apple Developer account for automatic signing
|
||||
# Open Xcode → Settings → Accounts → Add your Apple ID
|
||||
```
|
||||
|
||||
### 1.2 Register the Runner in Gitea
|
||||
|
||||
1. Go to your Gitea repo: **Settings → Actions → Runners**
|
||||
2. Click **Create new runner**
|
||||
3. Follow the instructions to download and configure the runner binary.
|
||||
Use the label **`macos`** (this must match `runs-on: macos` in the workflow):
|
||||
|
||||
```bash
|
||||
# On the Mac, after downloading the runner:
|
||||
./act_runner register \
|
||||
--instance https://gitea.1000co.fr \
|
||||
--token <RUNNER_TOKEN_FROM_GITEA> \
|
||||
--name mac-runner \
|
||||
--labels macos
|
||||
```
|
||||
|
||||
4. Start the runner (as a background service):
|
||||
|
||||
```bash
|
||||
./act_runner daemon
|
||||
```
|
||||
|
||||
For persistence across reboots, create a LaunchAgent:
|
||||
|
||||
```xml
|
||||
<!-- ~/Library/LaunchAgents/com.tabatago.runner.plist -->
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
|
||||
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>com.tabatago.runner</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/path/to/act_runner</string>
|
||||
<string>daemon</string>
|
||||
</array>
|
||||
<key>WorkingDirectory</key>
|
||||
<string>/path/to/runner</string>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
```
|
||||
|
||||
Then load it:
|
||||
```bash
|
||||
launchctl load ~/Library/LaunchAgents/com.tabatago.runner.plist
|
||||
```
|
||||
|
||||
### 1.3 Verify the Runner
|
||||
|
||||
Check that the runner appears as **Idle** in:
|
||||
**Gitea → Settings → Actions → Runners**
|
||||
|
||||
---
|
||||
|
||||
## 2. Configure Required Secrets
|
||||
|
||||
Go to **Gitea → Settings → Actions → Secrets** and add:
|
||||
|
||||
### 2.1 `IPHONE_UDID`
|
||||
|
||||
The UDID (Unique Device Identifier) of Millian's iPhone.
|
||||
This tells Xcode which physical device to build for.
|
||||
|
||||
```bash
|
||||
# Find the UDID on the Mac when the iPhone is connected via USB:
|
||||
xcrun xctrace list devices
|
||||
# Look for the iPhone line, e.g.:
|
||||
# Millian's iPhone (26.0) (00008110-XXXXXXXXXXXX)
|
||||
|
||||
# Or in Finder: select the iPhone in the sidebar → click the serial number
|
||||
# line until it switches to UDID
|
||||
```
|
||||
|
||||
| Secret Name | Value Example |
|
||||
|----------------|------------------------------------|
|
||||
| `IPHONE_UDID` | `00008110-00123456789ABC01` |
|
||||
|
||||
### 2.2 `GITEA_TOKEN`
|
||||
|
||||
A Gitea personal access token with **read/write** permissions on the repo.
|
||||
|
||||
Create it at: **Gitea → Settings → Applications → Generate Token**
|
||||
|
||||
Required permissions:
|
||||
- `read:repository` — read PR info, comments
|
||||
- `write:issue` — post comments on PRs
|
||||
- `write:pull_request` — merge PRs
|
||||
|
||||
| Secret Name | Value Example |
|
||||
|-----------------|----------------------------------------|
|
||||
| `GITEA_TOKEN` | `e20fd3de2f79b324afde5049e7bafd60a...` |
|
||||
|
||||
---
|
||||
|
||||
## 3. Code Signing Setup
|
||||
|
||||
The workflow uses **automatic code signing** (`CODE_SIGN_STYLE=Automatic`
|
||||
with `-allowProvisioningUpdates`). This requires:
|
||||
|
||||
1. **Apple ID signed into Xcode** on the Mac runner
|
||||
2. **The iPhone UDID registered** in the Apple Developer account
|
||||
3. **A valid provisioning profile** for `com.tabatago` (Debug)
|
||||
|
||||
To set up:
|
||||
```bash
|
||||
# On the Mac runner, open Xcode and sign in:
|
||||
# Xcode → Settings → Accounts → + → Apple ID
|
||||
|
||||
# Verify the team is available:
|
||||
cd tabatago-swift
|
||||
xcodegen generate
|
||||
xcodebuild -showBuildSettings -scheme TabataGo -sdk iphoneos | grep DEVELOPMENT_TEAM
|
||||
```
|
||||
|
||||
If automatic signing doesn't work (first-time setup), you may need to open
|
||||
the project in Xcode once manually to let it create the provisioning profile.
|
||||
|
||||
---
|
||||
|
||||
## 4. How the Workflow Works
|
||||
|
||||
### Trigger
|
||||
|
||||
The workflow runs on:
|
||||
- `pull_request` events on `main`
|
||||
- Types: `opened`, `synchronize` (new commits pushed), `reopened`
|
||||
|
||||
### Build Job (`build-deploy`)
|
||||
|
||||
| Step | What it does |
|
||||
|------|-------------|
|
||||
| Checkout | Clones the PR branch |
|
||||
| Setup Xcode | Selects Xcode.app, prints version |
|
||||
| Install XcodeGen | `brew install xcodegen` if not present |
|
||||
| Generate project | `xcodegen generate` in `tabatago-swift/` |
|
||||
| Build for iPhone | `xcodebuild build` for device UDID from secret |
|
||||
| Post comment | Posts a "Ready to test" message on the PR |
|
||||
|
||||
The build runs with `set -o pipefail` so that any compilation error causes
|
||||
the job to fail. The last 40 lines of build output are shown; the full log
|
||||
is saved to `build/xcodebuild.log`.
|
||||
|
||||
### Approval Job (`wait-approval`)
|
||||
|
||||
- Polls the Gitea API every **30 seconds** for new PR comments
|
||||
- **Timeout**: 120 minutes (240 iterations × 30s)
|
||||
- **LGTM detection**: Case-insensitive match for `lgtm` anywhere in the comment body
|
||||
- **KO detection**: Exact case-insensitive match for a standalone `ko` comment
|
||||
- On `LGTM` → merges the PR via Gitea API
|
||||
- On `KO` → fails the workflow (exit code 1)
|
||||
- On timeout → fails the workflow (exit code 1)
|
||||
|
||||
### Comment Format
|
||||
|
||||
Reply on the PR with just:
|
||||
- **`LGTM`** — approve and auto-merge
|
||||
- **`KO`** — block the PR
|
||||
|
||||
---
|
||||
|
||||
## 5. Troubleshooting
|
||||
|
||||
### Runner doesn't pick up jobs
|
||||
|
||||
- Check the runner label: must be `macos` exactly
|
||||
- Check **Settings → Actions → Runners** — runner must be **Idle**, not **Offline**
|
||||
- Run `./act_runner daemon` in a terminal to see logs
|
||||
|
||||
### Build fails with signing error
|
||||
|
||||
```
|
||||
error: No profiles for 'com.tabatago' were found
|
||||
```
|
||||
|
||||
- Open Xcode on the Mac runner, sign into your Apple ID
|
||||
- Build once in Xcode to generate the provisioning profile
|
||||
- Verify the iPhone UDID is correct
|
||||
|
||||
### Build fails with "device not found"
|
||||
|
||||
```
|
||||
error: Unable to find a device matching the provided destination specifier
|
||||
```
|
||||
|
||||
- Check that `IPHONE_UDID` secret matches the actual device UDID
|
||||
- The device must be registered in your Apple Developer account
|
||||
|
||||
### Comment not posted / LGTM not detected
|
||||
|
||||
- Verify `GITEA_TOKEN` has the required permissions (read/write issues + PRs)
|
||||
- Check the Gitea instance URL: `https://gitea.1000co.fr`
|
||||
- Ensure the token hasn't expired
|
||||
|
||||
### Workflow runs on every PR push, canceling previous runs
|
||||
|
||||
This is intentional — the `concurrency` setting cancels in-progress runs
|
||||
for the same PR when new commits are pushed. This prevents queue buildup.
|
||||
|
||||
---
|
||||
|
||||
## 6. File Locations
|
||||
|
||||
```
|
||||
tabatago/
|
||||
├── .gitea/
|
||||
│ └── workflows/
|
||||
│ └── pr-iphone-deploy.yml ← iPhone build + LGTM workflow
|
||||
├── .github/
|
||||
│ └── workflows/
|
||||
│ └── ci.yml ← Admin web + YouTube worker CI
|
||||
└── docs/
|
||||
└── ci-cd-setup.md ← This document
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Required Tools on the Mac Runner
|
||||
|
||||
| Tool | Version | Install |
|
||||
|-----------|----------|----------------------------------|
|
||||
| macOS | 15+ | — |
|
||||
| Xcode | 26.0+ | App Store or Apple Developer |
|
||||
| XcodeGen | latest | `brew install xcodegen` |
|
||||
| Python 3 | 3.x | Pre-installed on macOS |
|
||||
| curl | any | Pre-installed on macOS |
|
||||
| git | any | Pre-installed on macOS |
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [Gitea Actions Documentation](https://docs.gitea.com/usage/actions/overview)
|
||||
- [Gitea API — Merge a Pull Request](https://docs.gitea.com/api/1.22/#tag/pull-request/operation/repoMergePullRequest)
|
||||
- [Xcode Build Settings Reference](https://developer.apple.com/documentation/xcode/build-settings-reference)
|
||||
Reference in New Issue
Block a user