# ============================================================================ # 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 # 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 # -------------------------------------------------------------------------- # 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: ${{ 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: - 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: ${{ 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: - 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