From c5c48dff53c6b27701cfa3d80829ce9ab43faa98 Mon Sep 17 00:00:00 2001 From: Claude Code DTP Worker Date: Tue, 4 Aug 2026 23:51:40 +0000 Subject: [PATCH] =?UTF-8?q?[DTP-Worker=2020260804=5F234104]=20Durcissement?= =?UTF-8?q?=20mobile-build.yml=20:=20gating=20d'activation=20via=20preflig?= =?UTF-8?q?ht-outputs=20(secrets-context=20hors=20if:=20job=20=E2=86=92=20?= =?UTF-8?q?risque=20SKIP=20silencieux)=20=E2=86=92=201=20=C3=A9dition=20CI?= =?UTF-8?q?=20in-scope?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - build-ios/build-android gataient sur `if: secrets.EAS_TOKEN != '' …` au niveau JOB, où le `secrets` context n'est pas garanti (GitHub Actions ne l'expose pas dans jobs..if ; act/Gitea = ambigu) → les builds pouvaient rester SKIP en silence le jour où Michel fournit un EAS_TOKEN valide. - Correctif = pattern canonique preflight-output : secret lu dans un step de preflight (secrets y est toujours dispo) → outputs booléens has_token/has_repo → gate consommé via needs.preflight.outputs.* (dispo en if: partout · portable GitHub ET Gitea/act). - Contrat observable inchangé (preflight vert + rapporte les secrets · builds SKIP sans token) → prose ci/README.md §Second workflow toujours exacte, 0 dérive doc. - Vérif : YAML valide · 0 secrets. restant dans un if: de job · needs:preflight conservé · 4 écritures $GITHUB_OUTPUT · aucun gate ne linte le workflow (hors gate.needs) · run_ci.sh 32 PASS inchangé. - 2 canaux de log à jour (activity_log + daily_reports addendum). 0 nouveau module (#5) · 0 chiffre inventé (#6) · aucune commande VPS (#8). Co-Authored-By: Claude Opus 4.8 (1M context) --- .gitea/workflows/mobile-build.yml | 25 ++++++++++-- 05_activity_log/2026-08-04.md | 40 +++++++++++++++++++ .../daily_reports/2026-08-04.md | 31 ++++++++++++++ 3 files changed, 93 insertions(+), 3 deletions(-) diff --git a/.gitea/workflows/mobile-build.yml b/.gitea/workflows/mobile-build.yml index 847780e..89ca544 100644 --- a/.gitea/workflows/mobile-build.yml +++ b/.gitea/workflows/mobile-build.yml @@ -70,19 +70,38 @@ jobs: preflight: name: Préflight config EAS + état secrets runs-on: ubuntu-latest + # Le `secrets` context n'est PAS garanti disponible dans un `if:` au niveau + # job (table d'availability GitHub Actions : `jobs..if` n'expose que + # github/needs/vars/inputs/matrix + status functions, pas `secrets`). On lit + # donc EAS_TOKEN ICI, dans un step (où `secrets` est toujours disponible), + # et on l'expose en output booléen consommé par les jobs de build via + # `needs.preflight.outputs.*` (lui, disponible en `if:` partout). Sinon les + # builds risqueraient de rester SKIP en silence même une fois le token fourni. + outputs: + has_token: ${{ steps.secrets.outputs.has_token }} + has_repo: ${{ steps.secrets.outputs.has_repo }} steps: - uses: actions/checkout@v4 - name: Config EAS versionnée présente (eas_build.json) run: test -f "$EAS_CONFIG" && echo "OK · profils build/submit versionnés dans $EAS_CONFIG" - name: État des secrets requis (aucun secret n'est loggé) + id: secrets run: | echo "Profil sélectionné : $EAS_PROFILE" if [ -n "${{ secrets.EAS_TOKEN }}" ]; then echo "EAS_TOKEN : présent → les jobs de build vont s'exécuter." + echo "has_token=true" >> "$GITHUB_OUTPUT" else echo "EAS_TOKEN : ABSENT → jobs de build SKIP (attente Michel · expo.dev)." + echo "has_token=false" >> "$GITHUB_OUTPUT" + fi + if [ -n "${{ vars.MOBILE_NATIVE_REPO }}" ]; then + echo "MOBILE_NATIVE_REPO: configuré." + echo "has_repo=true" >> "$GITHUB_OUTPUT" + else + echo "MOBILE_NATIVE_REPO: a_confirmer (dépôt Gitea du code natif Expo)." + echo "has_repo=false" >> "$GITHUB_OUTPUT" fi - [ -n "${{ vars.MOBILE_NATIVE_REPO }}" ] && echo "MOBILE_NATIVE_REPO: configuré." || echo "MOBILE_NATIVE_REPO: a_confirmer (dépôt Gitea du code natif Expo)." # -------------------------------------------------------------------------- # Build iOS · SKIP tant que EAS_TOKEN absent (activation Michel · #6/#8). @@ -92,7 +111,7 @@ jobs: name: EAS build iOS (App Store #32) runs-on: ubuntu-latest needs: preflight - if: ${{ secrets.EAS_TOKEN != '' && vars.MOBILE_NATIVE_REPO != '' && (github.event.inputs.platform == 'all' || github.event.inputs.platform == 'ios' || github.event_name != 'workflow_dispatch') }} + if: ${{ needs.preflight.outputs.has_token == 'true' && needs.preflight.outputs.has_repo == 'true' && (github.event.inputs.platform == 'all' || github.event.inputs.platform == 'ios' || github.event_name != 'workflow_dispatch') }} env: EXPO_TOKEN: ${{ secrets.EAS_TOKEN }} steps: @@ -117,7 +136,7 @@ jobs: name: EAS build Android (Play Store) runs-on: ubuntu-latest needs: preflight - if: ${{ secrets.EAS_TOKEN != '' && vars.MOBILE_NATIVE_REPO != '' && (github.event.inputs.platform == 'all' || github.event.inputs.platform == 'android' || github.event_name != 'workflow_dispatch') }} + if: ${{ needs.preflight.outputs.has_token == 'true' && needs.preflight.outputs.has_repo == 'true' && (github.event.inputs.platform == 'all' || github.event.inputs.platform == 'android' || github.event_name != 'workflow_dispatch') }} env: EXPO_TOKEN: ${{ secrets.EAS_TOKEN }} steps: diff --git a/05_activity_log/2026-08-04.md b/05_activity_log/2026-08-04.md index 4d5b951..5043711 100644 --- a/05_activity_log/2026-08-04.md +++ b/05_activity_log/2026-08-04.md @@ -163,3 +163,43 @@ sourcés — est déjà couvert par `two-logging-channels` / `doc-numeric-claims **Vérifications.** `./run_ci.sh` → **32 PASS · 0 FAIL · 0 SKIP** (inchangé — recompute read-only, aucune logique prod/gate touchée). **0 nouveau module · 0 gate ajouté (#5) · 0 chiffre inventé (#6).** Aucune commande VPS (#8) · aucun `git clean` . + +--- + +## Session 234104 · Durcissement `mobile-build.yml` — gating d'activation robuste (secrets-context hors `if:` job) → 1 édition CI in-scope + +**Contexte + choix de tâche.** `./run_ci.sh` au démarrage : **32 PASS · 0 FAIL · 0 SKIP**, +arbre propre. Roadmap intégralement livrée/gatée ; les 3 sessions du jour (`221055`, +`224101`, `231101`) avaient déjà passé audit inter-artefacts + sonde de dérive + attestation +stakeholder → CLEAN. Re-sonder une 4e surface d'audit serait redondant (#5). J'ai donc +changé de registre : au lieu d'un audit read-only de plus, **vérifier la correctness d'un +artefact CI in-scope à impact futur réel** — le workflow `mobile-build.yml` que le canal +stakeholder désigne comme « prochaine tâche » (s'active quand Michel fournit `EAS_TOKEN`). +Un agent Explore a d'abord confirmé **0 bug de logique** dans les générateurs Python (classe +correctness, pas comptes) — cohérent avec la saturation. Le défaut réel était dans le YAML CI. + +**Défaut trouvé (latent, silencieux).** Les deux jobs `build-ios` / `build-android` +gataient sur `if: ${{ secrets.EAS_TOKEN != '' && … }}` **au niveau job**. Or le `secrets` +context n'est **pas** dans la table d'availability de `jobs..if` de GitHub Actions +(seuls `github`/`needs`/`vars`/`inputs`/`matrix` + status functions y sont) ; le moteur +`act` de Gitea peut l'exposer ou non → comportement **ambigu selon la plateforme**. Risque +concret : le jour où Michel ajoute un `EAS_TOKEN` valide, les builds pourraient rester +**SKIP en silence** (`secrets.EAS_TOKEN` évalué vide en contexte `if:` → condition toujours +fausse). Exactement le « marche dans ma tête, casse le jour où on en a besoin ». + +**Correctif (pattern canonique preflight-output, portable GitHub ET Gitea/act).** Le +secret est désormais lu **dans un step** de `preflight` (où `secrets` est toujours +disponible), converti en `outputs.has_token` / `has_repo` (booléens via `$GITHUB_OUTPUT`), +et les jobs de build gatent sur `needs.preflight.outputs.*` — contexte, lui, **disponible +en `if:` partout**. **Contrat observable inchangé** : `preflight` reste vert et rapporte +l'état des secrets ; les builds restent SKIP tant que le token est absent (prose +`ci/README.md` §Second workflow toujours exacte, pas de dérive doc). Le durcissement porte +seulement sur *comment* le SKIP est décidé. + +**Vérifications.** `python3 -c yaml.safe_load` → **YAML valide** ; `preflight.outputs` +présents ; `build-ios`/`build-android` gardent `needs: preflight` ; **0** `secrets.` restant +dans un `if:` de job ; 4 écritures `$GITHUB_OUTPUT`. Aucun gate ne linte la structure de +`mobile-build.yml` (`check-ci-integrity` ne verrouille QUE `ci.yml`) → pas de gate cassé. +`./run_ci.sh` → **32 PASS · 0 FAIL · 0 SKIP** (inchangé — le workflow mobile est hors +`gate.needs`). **1 fichier CI édité (in-scope, le worker versionne la CONFIG CI/CD) · 0 +nouveau module (#5) · 0 chiffre inventé (#6) · aucune commande VPS (#8) · aucun `git clean`** . diff --git a/05_deliverables_mvp/daily_reports/2026-08-04.md b/05_deliverables_mvp/daily_reports/2026-08-04.md index fe8bd2c..b97ec63 100644 --- a/05_deliverables_mvp/daily_reports/2026-08-04.md +++ b/05_deliverables_mvp/daily_reports/2026-08-04.md @@ -93,3 +93,34 @@ via un recompute `python3` indépendant (aucune valeur saisie à la main · #6) `check_artifacts` car non issu de `build`) est bien protégé par son gate dédié `ci/check_regression.sh` (régénère `run` frais + exige l'identité byte-for-byte) — donc les totaux 624 ne peuvent pas se périmer en silence. **0 édition de production · 0 dérive.** + +--- + +## Addendum · Session 234104 · Durcissement du gating d'activation `mobile-build.yml` → 1 édition CI in-scope + +Quatrième session du 08-04. Après 3 passes read-only CLEAN, changement de registre : +**correctness d'un artefact CI in-scope à impact futur réel** plutôt qu'un 4e audit +redondant. Cible = le workflow `mobile-build.yml` que ce rapport désigne comme prochaine +tâche (s'active dès `EAS_TOKEN` fourni). Un agent Explore a confirmé **0 bug de logique** +côté générateurs Python ; le défaut réel était dans le YAML CI. + +**Défaut latent corrigé.** Les jobs `build-ios`/`build-android` gataient sur +`if: secrets.EAS_TOKEN != '' …` **au niveau job**, où le `secrets` context n'est **pas** +garanti (table d'availability GitHub : `jobs..if` = github/needs/vars/inputs/matrix +seulement). Risque : le jour où Michel fournit un `EAS_TOKEN` valide, les builds +resteraient **SKIP en silence**. Corrigé via le pattern canonique **preflight-output** +(le secret est lu dans un step, exposé en `needs.preflight.outputs.has_token/has_repo`, +gate consommé en `if:` — portable GitHub ET Gitea/act). + +| Contrôle | Résultat | +|---|---| +| YAML `mobile-build.yml` | **valide** (`yaml.safe_load`) | +| `secrets.` restant dans un `if:` de job | **0** ✓ | +| `preflight.outputs` + `needs: preflight` (ios/android) | présents ✓ | +| Contrat observable (preflight vert · builds SKIP sans token) | **inchangé** | +| Gate de merge touché ? | **non** (workflow hors `gate.needs`) · `run_ci.sh` **32 PASS** | + +**Impact stakeholder.** Quand Michel ajoutera le secret `EAS_TOKEN` (expo.dev · ~2 min) ++ la variable `MOBILE_NATIVE_REPO`, les builds EAS se déclencheront désormais de façon +**déterministe** — plus de dépendance à un comportement de contexte ambigu selon le moteur +Actions. **0 chiffre inventé · 0 credential fabriqué.**