[DTP-Worker 20260803_033642] Sprint 5 P1 · feat · CI/CD Mobile : workflow Gitea Actions mobile-build.yml (build EAS iOS App Store #32 + Android Play Store)
Livrable FONCTIONNEL non fait, explicitement demandé par DIRECTIVE_MOBILE_STORES _20260803.md P1 (« Créer .gitea/workflows/mobile-build.yml ») — classé non-bloqueur in-périmètre worker. Triggers push main + tags v* + workflow_dispatch ; jobs preflight (toujours vert) + build-ios + build-android → eas build --profile production --non-interactive (profils lus de mobile/app_config/out/eas_build.json). Activation différée (#6/#8) : builds gardés par `if secrets.EAS_TOKEN != '' && vars.MOBILE_NATIVE_REPO != ''` → SKIP tant que Michel n'a pas fourni token+repo natif → CI jamais rouge avant activation ; aucun credential fabriqué (a_confirmer). Code Expo natif = autre dépôt Gitea, cloné au run (jamais recopié). Gitea only (#2). Consommateur régénéré : pointeur README mobile (4261→4917 o) mesuré par critère DOC de l'audit 4Big → audit_4big_gen.py build régénéré (verdict inchangé 22/22 ≥95). check_ci_integrity n'inspecte que ci.yml → 2e workflow invisible au gate. Zéro nouveau module · zéro gate ajouté (#5). run_ci.sh 30 PASS · 0 FAIL. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
# ============================================================================
|
||||
# Mobile Build (EAS) · OTO Enterprise OS DTP · Gitea Actions
|
||||
# ----------------------------------------------------------------------------
|
||||
# Roadmap Sprint 5 l.56-57 « Mobile : Rebuild Expo 54 + submit App Store #32 +
|
||||
# Play Store » · DIRECTIVE_MOBILE_STORES_20260803.md · P1 « CI/CD Mobile ».
|
||||
#
|
||||
# Plateforme : Gitea Actions UNIQUEMENT (CLAUDE.md #2 · JAMAIS GitHub).
|
||||
# Runner : act_runner enregistré sur le VPS avec le label « ubuntu-latest »
|
||||
# (même runner que ci.yml · voir ci/README.md).
|
||||
#
|
||||
# PÉRIMÈTRE (#8). Ce worker versionne la CONFIG CI/CD ; l'exécution `eas build` /
|
||||
# `eas submit` a lieu HORS repo (service EAS / stores), pilotée par l'agent
|
||||
# Mobile. La config des profils de build est la source de vérité versionnée
|
||||
# 05_deliverables_mvp/mobile/app_config/out/eas_build.json (profils development /
|
||||
# preview / production) — ce workflow ne fait que l'invoquer.
|
||||
#
|
||||
# CODE APP HORS REPO. Le code natif Expo vit dans un AUTRE dépôt Gitea
|
||||
# (/opt/oto/mobile/native/ · Expo SDK 51 actuel → cible Expo 54, roadmap l.56).
|
||||
# Il est cloné au run depuis ${{ vars.MOBILE_NATIVE_REPO }} — jamais recopié ici.
|
||||
#
|
||||
# ACTIVATION DIFFÉRÉE (#6 · zéro credential inventé). Tant que le secret
|
||||
# EAS_TOKEN n'est pas fourni par Michel (expo.dev · 2 min · cf. directive
|
||||
# « Vrais bloqueurs »), les jobs de build sont SKIP — donc ce workflow ne rend
|
||||
# JAMAIS le CI rouge avant que Michel n'active. Le job `preflight` reste vert et
|
||||
# rapporte l'état des secrets à fournir. Rien n'est fabriqué : tout identifiant
|
||||
# (repo natif, token, credentials Apple/Google) est un secret/variable
|
||||
# `a_confirmer`, cohérent avec les champs `null · a_confirmer` du livrable mobile.
|
||||
# ============================================================================
|
||||
name: Mobile Build (EAS)
|
||||
|
||||
on:
|
||||
# Conforme directive P1 : « Trigger sur push branche main ou tag v* ».
|
||||
push:
|
||||
branches: [main]
|
||||
tags: ['v*']
|
||||
paths:
|
||||
- '05_deliverables_mvp/mobile/**'
|
||||
- '.gitea/workflows/mobile-build.yml'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
platform:
|
||||
description: 'Plateforme à builder'
|
||||
required: true
|
||||
default: 'all'
|
||||
type: choice
|
||||
options: [all, ios, android]
|
||||
profile:
|
||||
description: 'Profil EAS (cf. eas_build.json)'
|
||||
required: true
|
||||
default: 'production'
|
||||
type: choice
|
||||
options: [production, preview, development]
|
||||
|
||||
# Un seul build mobile à la fois par ref (annule le précédent en cours).
|
||||
concurrency:
|
||||
group: mobile-build-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
# Profil par défaut (aligné directive P4 : builds `--profile production`).
|
||||
EAS_PROFILE: ${{ github.event.inputs.profile || 'production' }}
|
||||
# Config des profils versionnée par le worker (source de vérité).
|
||||
EAS_CONFIG: 05_deliverables_mvp/mobile/app_config/out/eas_build.json
|
||||
|
||||
jobs:
|
||||
# --------------------------------------------------------------------------
|
||||
# Préflight : TOUJOURS vert. Prouve que la config EAS versionnée est présente
|
||||
# et rapporte l'état des secrets requis, SANS jamais échouer avant activation.
|
||||
# --------------------------------------------------------------------------
|
||||
preflight:
|
||||
name: Préflight config EAS + état secrets
|
||||
runs-on: ubuntu-latest
|
||||
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é)
|
||||
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."
|
||||
else
|
||||
echo "EAS_TOKEN : ABSENT → jobs de build SKIP (attente Michel · expo.dev)."
|
||||
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).
|
||||
# App Store #32 · `eas build --platform ios --profile production`.
|
||||
# --------------------------------------------------------------------------
|
||||
build-ios:
|
||||
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') }}
|
||||
env:
|
||||
EXPO_TOKEN: ${{ secrets.EAS_TOKEN }}
|
||||
steps:
|
||||
- name: Cloner le code natif Expo (dépôt Gitea séparé)
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ vars.MOBILE_NATIVE_REPO }}
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
- name: Installer EAS CLI
|
||||
run: npm install -g eas-cli
|
||||
- name: EAS build iOS (production · non-interactive)
|
||||
run: eas build --platform ios --profile "$EAS_PROFILE" --non-interactive --no-wait
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Build Android · SKIP tant que EAS_TOKEN absent (activation Michel · #6/#8).
|
||||
# Play Store · `eas build --platform android --profile production`.
|
||||
# --------------------------------------------------------------------------
|
||||
build-android:
|
||||
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') }}
|
||||
env:
|
||||
EXPO_TOKEN: ${{ secrets.EAS_TOKEN }}
|
||||
steps:
|
||||
- name: Cloner le code natif Expo (dépôt Gitea séparé)
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ vars.MOBILE_NATIVE_REPO }}
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
- name: Installer EAS CLI
|
||||
run: npm install -g eas-cli
|
||||
- name: EAS build Android (production · non-interactive)
|
||||
run: eas build --platform android --profile "$EAS_PROFILE" --non-interactive --no-wait
|
||||
@@ -1,5 +1,55 @@
|
||||
# Activity Log · 2026-08-03 · Claude Code DTP Worker
|
||||
|
||||
## Session 033642 · Sprint 5 P1 · Livrable FONCTIONNEL : workflow CI/CD Mobile `.gitea/workflows/mobile-build.yml` (build EAS iOS + Android)
|
||||
|
||||
**Contexte + choix de tâche.** `./run_ci.sh` au démarrage : **30 PASS · 0 FAIL · 0 SKIP**,
|
||||
arbre propre. Michel : « commits fonctionnels, pas juste docs ». La roadmap est couverte
|
||||
par des modules gatés+verts, mais `DIRECTIVE_MOBILE_STORES_20260803.md` (Sprint 5, actif)
|
||||
liste explicitement en **P1 · CI/CD Mobile** la création de `.gitea/workflows/mobile-build.yml`
|
||||
— classée **non-bloqueur** (« configurer sans token, activation quand Michel fournit »),
|
||||
donc **in-périmètre worker** (fichier config versionné, aucune exécution VPS/stores #8).
|
||||
Vérifié absent : `.gitea/workflows/` ne contenait que `ci.yml`. **Vraie tâche fonctionnelle
|
||||
non faite** → exécutée.
|
||||
|
||||
**Livrable créé : `.gitea/workflows/mobile-build.yml`.**
|
||||
- **Triggers** (conformes directive P1) : push `main` + tags `v*` (paths `mobile/**` +
|
||||
le workflow) + `workflow_dispatch` (inputs `platform` all/ios/android, `profile`).
|
||||
- **Jobs** : `preflight` (TOUJOURS vert · prouve la présence de la config EAS versionnée
|
||||
`mobile/app_config/out/eas_build.json` + rapporte l'état des secrets, sans jamais les
|
||||
logger) ; `build-ios` (App Store #32) + `build-android` (Play Store) → `eas build
|
||||
--platform … --profile production --non-interactive` (directive P4).
|
||||
- **Source de vérité** : les profils de build viennent de l'artefact versionné
|
||||
`eas_build.json` (development/preview/production) — pas réinventés.
|
||||
- **Code natif hors repo** : le code Expo vit dans un **autre dépôt Gitea**
|
||||
(`/opt/oto/mobile/native/` · Expo 51→cible 54) ; cloné au run depuis la variable
|
||||
`vars.MOBILE_NATIVE_REPO` — **jamais recopié ici**.
|
||||
|
||||
**Sûreté (activation différée · #6 zéro invention · #8).** Les jobs de build sont gardés
|
||||
par `if: secrets.EAS_TOKEN != '' && vars.MOBILE_NATIVE_REPO != ''` → **SKIP** tant que
|
||||
Michel n'a pas fourni token+repo (« Vrais bloqueurs » de la directive : EAS_TOKEN 2 min sur
|
||||
expo.dev). Conséquence : ce workflow **ne rend JAMAIS le CI rouge** avant activation, et
|
||||
`preflight` reste vert et informatif. Aucun credential fabriqué : token, repo natif,
|
||||
appleId/ascAppId/serviceAccount restent des secrets/vars `a_confirmer` — cohérent avec les
|
||||
champs `null · a_confirmer` du livrable mobile. Plateforme **Gitea Actions uniquement** (#2).
|
||||
|
||||
**Non-régression des gates (vérifié).** `check_ci_integrity.sh` n'inspecte QUE `ci.yml`
|
||||
(chemin en dur `CI=".gitea/workflows/ci.yml"`) → le 2e workflow lui est invisible, aucun
|
||||
job à ajouter à `gate.needs`. `guard_constraints.sh` vert (aucune URL/usage interdit ;
|
||||
`actions/checkout@v4` déjà toléré via `ci.yml`). YAML valide (pyyaml).
|
||||
|
||||
**Consommateur régénéré (classe [[artifact-reproducibility-gate]]).** Ajout d'un pointeur
|
||||
concis (paragraphe « CI/CD Mobile » + 1 ligne au tableau périmètre) dans
|
||||
`mobile/app_config/README.md` → sa taille passe 4261→4917 octets, mesurée par le critère
|
||||
**DOC** de l'audit 4Big. `check-artifacts` a viré ROUGE (dérive attendue) →
|
||||
`audit_4big_gen.py build -o out` régénéré : **seule** la ligne `evidence "README.md (…octets)"`
|
||||
change ; verdict inchangé **PASS · 22/22 modules ≥ 95**. Lien Markdown vérifié résolvant
|
||||
(`../../../.gitea/workflows/mobile-build.yml`).
|
||||
|
||||
**Vérifications finales.** `./run_ci.sh` → **30 PASS · 0 FAIL · 0 SKIP**. **Zéro nouveau
|
||||
module · zéro gate ajouté (#5)** · aucune commande VPS (#8).
|
||||
Aucun `git clean` exécuté <!-- ci-allow : mention de l'interdit absolu, jamais exécuté -->.
|
||||
|
||||
|
||||
## Session 020634 · Dérive ground-truth résiduelle : roadmap L18 (colonne « Existe déjà ») affirmait encore « Expo 54 » — corrigée → Expo 51 réel (#6)
|
||||
|
||||
**Contexte.** `./run_ci.sh` au démarrage : **30 PASS · 0 FAIL · 0 SKIP**, arbre propre.
|
||||
|
||||
@@ -19,6 +19,14 @@ produit uniquement la **config** que l'agent Mobile consomme sur le poste/CI EAS
|
||||
| `app.config` Expo (thème, locales, navigation) | `eas build` (Expo 54) |
|
||||
| `eas.json` (profils build/submit) | `eas submit` App Store #32 / Play Store |
|
||||
| navigation par rôle (gating RBAC) | credentials / signing / assets binaires |
|
||||
| workflow CI/CD `.gitea/workflows/mobile-build.yml` (Sprint 5 P1) | exécution `eas build` sur runner EAS |
|
||||
|
||||
**CI/CD Mobile (Sprint 5 P1 · directive `DIRECTIVE_MOBILE_STORES_20260803.md`).** Le
|
||||
workflow Gitea Actions [`.gitea/workflows/mobile-build.yml`](../../../.gitea/workflows/mobile-build.yml)
|
||||
invoque `eas build` iOS + Android (profil `production`) depuis les profils versionnés
|
||||
d'`out/eas_build.json`. Il est **désactivé sans effet** (jobs de build SKIP · CI jamais
|
||||
rouge) tant que Michel n'a pas fourni le secret `EAS_TOKEN` et la variable
|
||||
`MOBILE_NATIVE_REPO` (dépôt Gitea du code natif Expo) — aucun credential n'est fabriqué (#6/#8).
|
||||
|
||||
## Zéro invention (#6)
|
||||
|
||||
|
||||
@@ -606,7 +606,7 @@
|
||||
"criterion": "DOC",
|
||||
"weight": 20,
|
||||
"passed": true,
|
||||
"evidence": "README.md (4261 octets)"
|
||||
"evidence": "README.md (4917 octets)"
|
||||
},
|
||||
{
|
||||
"criterion": "CONTRAT",
|
||||
|
||||
Reference in New Issue
Block a user