fix(ci): pr-iphone-deploy — cache, secrets, LGTM regex, concurrency, watch build, scope #12
Reference in New Issue
Block a user
Delete Branch "fix/ci-pr-iphone-deploy"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Fix
pr-iphone-deploy.yml— cache, secrets, LGTM handling, watch build, scopeReview of the existing
pr-iphone-deploy.ymlsurfaced a number of bugs and doc/code mismatches. This PR fixes them and alignsAGENTS.md§5/§7/§8 with the real behaviour.⚠️ Do NOT auto-merge this PR via the workflow
This PR changes the merge logic itself (squash-merge, LGTM regex, concurrency). A bug here could block all future merges. Merge this PR manually from the Gitea UI, then validate the new flow on a throwaway follow-up PR before relying on auto-merge.
Summary of changes
.github/workflows/pr-iphone-deploy.ymltabatago-swift/project.ymlTabataGoWatch+TabataGoWatchWidgetto the scheme (+2)AGENTS.mdCommits
fix(ci): pr-iphone-deploy — cache, secrets, LGTM regex, concurrency, squash— all 10 CI fixesfix(project.yml): build watch targets in TabataGo schemedocs(agents): align CI docs (§5/§7/§8) with real workflow behaviorfix(ci): only run pr-iphone-deploy when tabatago-swift or the workflow changesThe 10 workflow fixes
Cache & build hygiene
1. Stop deleting the SPM cache we claim to keep
The clean step ran
rm -rf build/, which wipedbuild/spm-cache— exactly the RevenueCat cache (≈1.1 GiB) the comments and AGENTS.md §5/§8 claimed was preserved. Every CI run re-cloned RevenueCat (5+ min, random sandbox failures). Now onlybuild/derivedis deleted; the cache is finally actually preserved.2. Stop nuking the global Xcode cache
rm -rf ~/Library/Caches/com.apple.dt.Xcodeslowed every subsequent build. Removed.DerivedData/*andModuleCache.noindexdeletion stay (per-build hygiene + stale.pcmfix).3. Drop
|| trueonbrew installIf brew was down, the install "succeeded" silently and later steps failed with confusing "command not found". Now it fails loudly at the source.
4. Bump build-deploy timeout 20m → 30m
Cold builds (first run after this change, or after cache eviction) need to re-clone RevenueCat. 30m gives room without being excessive.
Secrets
5. Write
Config/Secrets.xcconfigfrom Gitea secretsNew step before
xcodegen generatematerializes the xcconfig file from theSUPABASE_URL,SUPABASE_ANON_KEY,REVENUECAT_API_KEY,POSTHOG_API_KEYsecrets. Preflight fails loudly if a required secret is missing (so we never ship an.appthat silently can't reach Supabase/RevenueCat).Info.plistalready reads the values via$(VAR)andproject.ymlwires the xcconfig to Debug+Release — no other build change needed.Heredoc body is at column 0 (verified with
od -c) — xcconfig keys are whitespace-sensitive.LGTM / KO handling
6. Match LGTM/KO anywhere in the comment body
Old grep
'"body": *"LGTM"'only matched when LGTM was the first token, so "Tested, LGTM!" was silently ignored. New regex:Word boundaries prevent false positives — verified that
KOM,LGTMX,OKdo not match.7. Re-fetch all comments each poll (not
since_id)since_idfiltering made edits invisible (a reviewer changing "KO" → "LGTM" wouldn't be seen). Now re-fetches all comments every 30s cycle. Negligible cost for PRs with <50 comments.8. Squash-merge instead of merge commit
{"Do":"merge"}→{"Do":"squash"}. Matches the clean linear history already onmain(e.g.32ccbcc chore(release): 1.0.0).Workflow structure
9. Add
concurrency:block (per-PR, cancel-in-progress)Every push to a PR previously started a fresh
build-deploy+wait-approvalpipeline with nothing cancelling the previous one → stacked pipelines, wasted runner time, double-merge risk. Nowgroup: pr-iphone-deploy-<PR#>withcancel-in-progress: truecancels superseded runs. Different PRs still run in parallel.10. Remove the no-op
permissions:blockAll mutations (comments, merge) go through the Gitea API with
PR_API_TOKEN, never the runner's nativeGITHUB_TOKEN. Thepermissions: contents: write / pull-requests: writeblock only scoped the native token, so it had no effect here. Removed with an explanatory comment.Path filter (scope the trigger)
The workflow now only runs when the PR touches the Swift app (
tabatago-swift/**) or the workflow itself. Docs-only /admin-web//youtube-worker//supabase//AGENTS.md/ root-config PRs skip the macOS runner entirely — no point rebuilding and deploying an unchanged.app.The workflow file is included in
paths:so a PR that only edits the workflow logic still triggers it (which is why this branch's own PR runs).Scheme: build watch targets in CI
The
TabataGoscheme previously listed onlyTabataGo+TabataGoWidget(iOS), soxcodebuild -scheme TabataGonever compiled the watchOS app in CI. AddedTabataGoWatch+TabataGoWatchWidgetto the build targets.Verified locally with
xcodegen generate— the generatedTabataGo.xcschemenow lists all 4BlueprintNames:TabataGo,TabataGoWatch,TabataGoWatchWidget,TabataGoWidget.Docs: AGENTS.md §5 / §7 / §8
Brought the canon doc in line with the corrected workflow:
GARDE build/spm-cache" (was../build/spm-cache), explicit warning never torm -rf build/, note that the global Xcode cache is spared.Secrets.xcconfigwrite-from-secrets step.TabataGoWidget(iOS) vsTabataGoWatchWidget(watchOS).\bLGTM\b/\bKO\bregex, squash-merge.Config/Secrets.xcconfig→ Info.plist" with the real flow. Add a historical-exposure warning (Secrets.xcconfigwas committed before the gitignore rule; key rotation recommended).permissions:block, Xcode global cache.Verification done locally
python3 -c "import yaml; yaml.safe_load(...)"parses both.github/workflows/pr-iphone-deploy.ymlandtabatago-swift/project.yml.paths:correctly nested underpull_request:(same level asbranches/types).xcodegen generateproduces a scheme with all 4BlueprintNames.lgtm, KOM✗, OK✗, LGTMX✗). The one "failure" was an artificial"body" : "..."spacing that Gitea's Go JSON serializer never produces.od -c) — xcconfig-safe.POSTHOG_API_KEYempty.Out of scope
Config/Secrets.xcconfigcontents — it stays on disk for local dev; CI overwrites it at build time.89cca25) is documented but not addressed here. Rotating the Supabase anon key and RevenueCat key is a separate ops task only the owner can do.TabataGo.xcodeprojis not committed (not git-tracked; XcodeGen regenerates it locally per AGENTS.md rule #8).Reviewer checklist
SUPABASE_URL,SUPABASE_ANON_KEY,REVENUECAT_API_KEY,POSTHOG_API_KEY(POSTHOG can be empty).tabatago-swift/PR after merge may surface watch issues).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).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.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.📱 Prêt à tester !
L'app est déployée sur l'iPhone (devicectl).
LGTM