4 Commits

Author SHA1 Message Date
Millian Lamiaux
244270488a fix(ci): only run pr-iphone-deploy when tabatago-swift or the workflow changes
Some checks failed
CI / Detect Changes (pull_request) Successful in 3s
CI / YouTube Worker (pull_request) Has been skipped
CI / Deploy (pull_request) Has been skipped
PR → Build → WiFi/USB Deploy → LGTM / Build & Deploy to iPhone (WiFi/USB) (pull_request) Failing after 14s
PR → Build → WiFi/USB Deploy → LGTM / Wait for LGTM comment (pull_request) Has been skipped
Add a paths: filter to the pull_request trigger so the iOS build+deploy
only fires when the PR actually touches:
  - tabatago-swift/**   (the iOS/watchOS app source)
  - .github/workflows/pr-iphone-deploy.yml  (this workflow itself)

PRs touching only AGENTS.md, admin-web/, youtube-worker/, supabase/,
docs/, or root config no longer spin up the macOS runner — no point
rebuilding and deploying an unchanged .app.

Including the workflow file itself in paths: ensures a PR that only
edits the workflow logic still triggers it (so this branch's own PR
will run to validate the changes).
2026-07-19 18:44:28 +02:00
Millian Lamiaux
756b1a405c docs(agents): align CI docs (§5/§7/§8) with real workflow behavior
Rewrite AGENTS.md to match the corrected pr-iphone-deploy.yml:

§5 Workflow:
- Clean step: 'GARDE build/spm-cache' (not ../build/spm-cache), explicit
  warning never to 'rm -rf build/', note that Xcode global cache is spared.
- New step 5: write Secrets.xcconfig from Gitea secrets before xcodegen.
- Scheme lists 4 targets (TabataGo, TabataGoWidget, TabataGoWatch,
  TabataGoWatchWidget) — clarify TabataGoWidget is iOS, not watchOS.
- wait-approval: re-fetches all comments each cycle, regex \bLGTM\b/\bKO\b
  anywhere in body, squash-merge.
- Document concurrency block and timeouts.

§5 Secrets table:
- Replace false 'Injectés via Config/Secrets.xcconfig → Info.plist' with
  the real flow (CI writes file from secrets, Info.plist reads $(VAR)).
- Add historical-exposure warning: Secrets.xcconfig was committed before
  the gitignore rule; key rotation recommended.

§5 Pitfalls + §8 anti-patterns:
- 'rm -rf build/' (not just 'rm -rf cache SPM').
- Don't nuke ~/Library/Caches/com.apple.dt.Xcode.
- permissions: block is intentionally absent (no-op under Gitea API).
- Don't remove concurrency block.
- Don't anchor LGTM grep to body start.
- {"Do":"squash"} not {"Do":"merge"}.
- Scheme must list all 4 targets.

§7 rule #9: expanded with the CI-writes-file flow.
2026-07-19 16:51:02 +02:00
Millian Lamiaux
0b476f5871 fix(project.yml): build watch targets in TabataGo scheme
The TabataGo scheme only listed TabataGo + TabataGoWidget (iOS), so
xcodebuild -scheme TabataGo never compiled the watchOS app in CI. Add
TabataGoWatch + TabataGoWatchWidget to the build targets so watch-side
breakage is caught before deploy.

Note: TabataGoWidget is a real iOS widget target (defined at project.yml
line 165, app-extension/iOS), NOT a phantom — the prior review was wrong
on that point. The real gap was the missing watch targets.

Embed deps were already correct (TabataGo embeds TabataGoWatch, which
embeds TabataGoWatchWidget). Verified locally with xcodegen 2.45.4:
the generated xcscheme now lists all 4 BlueprintNames.

⚠️ Risk: if the watch target has latent build issues (never compiled in
CI before), this will surface them on the next PR. Desirable — catch
before merge, not in the field.
2026-07-19 16:50:47 +02:00
Millian Lamiaux
d50e53e4ad fix(ci): pr-iphone-deploy — cache, secrets, LGTM regex, concurrency, squash
10 fixes to .github/workflows/pr-iphone-deploy.yml:

Cache & build hygiene:
- Stop deleting build/spm-cache (was wiped by 'rm -rf build/'); clean only
  build/derived. RevenueCat (~1.1 GiB) is finally actually preserved.
- Stop nuking ~/Library/Caches/com.apple.dt.Xcode (slows every next build).
- Drop '|| true' on brew install — fail loudly if brew is down.
- Bump build-deploy timeout 20m → 30m for cold builds.

Secrets:
- New step writes Config/Secrets.xcconfig from Gitea secrets (SUPABASE_URL,
  SUPABASE_ANON_KEY, REVENUECAT_API_KEY, POSTHOG_API_KEY) before xcodegen.
  Preflight fails loud if a required secret is missing. Heredoc body at
  column 0 (xcconfig keys are whitespace-sensitive).

LGTM/KO handling:
- Regex now matches anywhere in body with word boundary: \bLGTM\b / \bKO\b.
  'Tested, LGTM!' counts; 'KOM' / 'LGTMX' / 'OK' do not.
- Re-fetch ALL comments each poll (not since_id) to catch edits.
- Squash-merge ({"Do":"squash"}) instead of merge commit.

Workflow structure:
- Add concurrency block (per-PR, cancel-in-progress) — prevents double-merge
  and stacked pipelines on successive pushes.
- Remove no-op 'permissions:' block (all mutations go via Gitea API with
  PR_API_TOKEN, native GITHUB_TOKEN is never used).
2026-07-19 16:50:36 +02:00
4 changed files with 26 additions and 24 deletions

View File

@@ -1,8 +1,8 @@
# =============================================================================
# TabataGo — PR → Build → devicectl Deploy → Wait LGTM → Merge
# TabataGo — PR → Build → WiFi/USB Direct Deploy → Wait LGTM → Merge
# =============================================================================
name: PR → Build → devicectl Deploy → LGTM
name: PR → Build → WiFi/USB Deploy → LGTM
on:
pull_request:
@@ -27,7 +27,7 @@ concurrency:
jobs:
build-deploy:
name: Build & Deploy to iPhone (devicectl)
name: Build & Deploy to iPhone (WiFi/USB)
runs-on: macos
timeout-minutes: 30
@@ -82,16 +82,11 @@ jobs:
echo "✅ Caches nettoyés (SPM cache préservé)"
- name: Install tools (xcodegen)
- name: Install tools (xcodegen, node, ios-deploy)
run: |
# The act_runner shell can land under Rosetta 2 on Apple Silicon;
# Homebrew lives in /opt/homebrew (ARM prefix), so run brew natively.
# (Brew refuses to install/upgrade under Rosetta in the ARM prefix.)
# Only xcodegen is needed — node is NOT used by any step in this
# workflow, and installing it triggers brew's "installed dependents
# check" which tries to rebuild unrelated formulae (e.g. gemini-cli)
# and fails the build.
arch -arm64 brew install xcodegen
# No `|| true` — if brew is down, fail loudly here instead of producing
# confusing "command not found" errors in the next steps.
brew install xcodegen node ios-deploy
- name: Write Secrets.xcconfig from Gitea secrets
env:
@@ -148,20 +143,27 @@ jobs:
CODE_SIGN_STYLE=Automatic \
DEVELOPMENT_TEAM=2MJF39L8VY
- name: Install to iPhone (devicectl)
- name: Install to iPhone (WiFi → USB fallback)
run: |
UDID="00008120-000925CE3672201E"
APP=$(find build/derived -name 'TabataGo.app' -type d | head -1)
# devicectl handles both WiFi (network) and wired (USB-C/Thunderbolt)
# discovery natively — no separate USB-fallback tool needed.
echo "📱 Installing via devicectl..."
if xcrun devicectl device install app --device "$UDID" "$APP"; then
echo "✅ Installed via devicectl"
# 1. Try WiFi first (Xcode 15+ devicectl network discovery)
echo "📱 Trying WiFi install via devicectl..."
if xcrun devicectl device install app --device "$UDID" "$APP" > /tmp/devicectl.log 2>&1; then
echo "✅ Installed via WiFi"
exit 0
fi
tail -10 /tmp/devicectl.log
# 2. Fallback to USB via ios-deploy
echo "🔌 WiFi failed, trying USB..."
if ios-deploy --bundle "$APP" --id "$UDID" --justlaunch; then
echo "✅ Installed via USB"
exit 0
fi
echo "❌ devicectl install failed"
echo "❌ Install failed (both WiFi and USB)"
exit 1
@@ -175,7 +177,7 @@ jobs:
curl -s -X POST \
-H "Authorization: token ${GT_TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"body\":\"## 📱 Prêt à tester !\\n\\nL'app est déployée sur l'iPhone (devicectl).\\n\\n- Teste les changements\\n- Reply **LGTM** pour merger\\n- Reply **KO** pour bloquer\"}" \
-d "{\"body\":\"## 📱 Prêt à tester !\\n\\nL'app est déployée sur l'iPhone (USB/WiFi).\\n\\n- Teste les changements\\n- Reply **LGTM** pour merger\\n- Reply **KO** pour bloquer\"}" \
"${GITEA_URL}/api/v1/repos/${REPO}/issues/${PR}/comments"
wait-approval:

View File

@@ -162,10 +162,10 @@ Complications : `TabataGoComplication`.
- Supprime `build/derived`, `TabataGo.xcodeproj`, `Package.resolved`, DerivedData, ModuleCache.
- **GARDE le cache SPM** (`build/spm-cache` — c'est le chemin passé à `-clonedSourcePackagesDirPath`) — RevenueCat ≈ 1.1 GiB, re-cloner = 5+ min et échecs aléatoires du sandbox. **Ne jamais faire `rm -rf build/`** : ça détruirait ce cache. Le clean step ne touche que `build/derived`.
- Ne touche **pas** à `~/Library/Caches/com.apple.dt.Xcode` (cache Xcode global — le nuke ralentit tous les builds suivants).
4. **Install tools** : `arch -arm64 brew install xcodegen` (sans `|| true` — si brew down, on fail ici, pas deux steps plus loin). `arch -arm64` requis car le shell act_runner tourne sous Rosetta 2 sur Apple Silicon, mais Homebrew est dans le prefix ARM `/opt/homebrew` — sans ça, brew refuse d'installer/upgrader. Seul xcodegen est nécessaire : **node n'est pas utilisé** par ce workflow, et l'installer déclenche le "installed dependents check" de brew qui essaie de rebuilder des formulae sans rapport (ex. `gemini-cli`) et fail le build.
4. **Install tools** : `brew install xcodegen node ios-deploy` (sans `|| true` — si brew down, on fail ici, pas deux steps plus loin).
5. **Write `Config/Secrets.xcconfig`** depuis les secrets Gitea (`SUPABASE_URL`, `SUPABASE_ANON_KEY`, `REVENUECAT_API_KEY`, `POSTHOG_API_KEY`). Preflight : fail loud si un secret requis manque. Le fichier est gitigné (règle #9) ; CI l'écrase à chaque run. `Info.plist` lit les valeurs via `$(SUPABASE_URL)` etc., et `project.yml` wire le xcconfig en Debug+Release — aucun autre change­ment nécessaire côté build.
6. **xcodegen generate**`xcodebuild -resolvePackageDependencies`**build** (`-scheme TabataGo`, Debug, auto-provisioning, team `2MJF39L8VY`). Le scheme build les 4 targets : `TabataGo` (app iOS), `TabataGoWidget` (widget iOS, vrai target — ne pas confondre avec `TabataGoWatchWidget` qui est watchOS), `TabataGoWatch` (app watchOS), `TabataGoWatchWidget` (complication watchOS).
7. **Deploy iPhone** UDID `00008120-000925CE3672201E` : `xcrun devicectl device install app` uniquement. `devicectl` gère nativement la découverte WiFi (réseau) et filaire (USB-C/Thunderbolt) — pas de fallback `ios-deploy`.
7. **Deploy iPhone** UDID `00008120-000925CE3672201E` : `devicectl` WiFi d'abord, fallback `ios-deploy` USB.
8. **Post comment** "Prêt à tester" sur la PR.
9. **Job `wait-approval`** : poll (30s, max 240 = 2h). **Re-fetche TOUS les comments** chaque cycle (pas `since_id`) pour attraper aussi les edits (un reviewer passant de "KO" à "LGTM"). Match LGTM/KO n'importe où dans le body (regex `\bLGTM\b` / `\bKO\b`, case-insensitive) — "Tested, LGTM!" compte ; "KOM" ne compte pas. `LGTM`**squash-merge** (`{"Do":"squash"}`). `KO` → blocage. Timeout → fail.

View File

@@ -1,6 +1,6 @@
{
"name": "my-app",
"version": "1.0.1",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "next dev",

View File

@@ -1,3 +1,3 @@
{
"version": "1.0.1"
"version": "1.0.0"
}