Skip to Content

Chapitre 12.3 — Le build local gradle : release illimitée

Où on en est : le cloud sait faire. Maintenant TA machine : le même APK release, en 3 minutes, sans quota — à condition de gérer la signature toi-même. C’est le chapitre le plus « sous le capot » du cours ; il paie pour toutes tes futures apps.

⏱️ TL;DR — Deux routes locales : eas build --local (le pipeline EAS exécuté chez toi — signature EAS incluse, le meilleur des deux mondes) et gradle direct (prebuild + gradlew assembleRelease — le contrôle total, keystore à configurer). On importe LE keystore EAS (ch. 12.2) pour que local et cloud signent PAREIL — la règle qui évite le mur « signatures incompatibles ».

🎯 Objectifs

  • Builder en local via eas build —local (la route recommandée).
  • Comprendre la route gradle pure (assembleRelease, signing config) — pour la maîtrise.
  • Faire signer local et cloud avec LE MÊME keystore.
  • Choisir sa route par défaut et documenter le rituel dans le README.

Route 1 : eas build —local (recommandée)

eas build --profile preview --platform android --local

Le MÊME pipeline que le cloud (mêmes profils eas.json, même prebuild, même signature — la CLI récupère le keystore EAS), exécuté sur votre machine : zéro quota, zéro file, ~3-8 min sur votre config. Le résultat : un build-xxxx.apk dans le dossier courant.

Prérequis déjà en place depuis la P2 : ANDROID_HOME, le SDK. C’est la route par défaut du cours : la reproductibilité d’EAS + la vitesse du local, et un seul keystore pour tout le monde.

Limites honnêtes : indisponible pour iOS sur Windows (évidemment), et quelques Go de disque pour les images de build. Rien de bloquant.

Route 2 : gradle direct (la maîtrise)

Savoir la dérouler à la main démystifie tout le pipeline — et sert le jour où un build échoue mystérieusement :

# 1. Générer le natif (identité prod !) $env:APP_VARIANT = 'production' npx expo prebuild --platform android --clean # 2. Compiler la release cd android .\gradlew assembleRelease # → android/app/build/outputs/apk/release/app-release.apk

Mais cet APK est signé avec la debug key par défaut — installable, mais PAS compatible avec vos builds EAS (signatures différentes = Android refuse la mise à jour de l’un par l’autre). Pour signer avec le VRAI keystore (celui téléchargé au ch. 12.2) :

# android/gradle.properties (ou mieux : ~/.gradle/gradle.properties, hors repo !) DRILL_UPLOAD_STORE_FILE=drill.jks DRILL_UPLOAD_KEY_ALIAS=<alias du keystore EAS> DRILL_UPLOAD_STORE_PASSWORD=<…> DRILL_UPLOAD_KEY_PASSWORD=<…>
// android/app/build.gradle — bloc signingConfigs (dans la section android { }) signingConfigs { release { storeFile file(DRILL_UPLOAD_STORE_FILE) keyAlias DRILL_UPLOAD_KEY_ALIAS storePassword DRILL_UPLOAD_STORE_PASSWORD keyPassword DRILL_UPLOAD_KEY_PASSWORD } } buildTypes { release { signingConfig signingConfigs.release } }

…et là, dissonance : android/ est généré (contrat CNG, ch. 11.4) — cette modif manuelle serait effacée ! La résolution propre : soit un config plugin qui injecte le signingConfig (le pattern du ch. 11.3 — c’est exactement son cas d’usage), soit… la route 1, qui règle tout ça pour vous. C’est le vrai argument d’eas build —local : il n’existe pas de version « simple ET propre » du gradle direct sous CNG.

La règle d’or : UN keystore pour tous les chemins

Le scénario cauchemar évité : APK cloud installé lundi, APK local (autre clé) mercredi → INSTALL_FAILED_UPDATE_INCOMPATIBLE → désinstaller = perdre l’historique SQLite. Avec un keystore unique : jamais.

Vérifier une signature en cas de doute :

keytool -printcert -jarfile app-release.apk # → empreinte SHA-1 à comparer

Le rituel de release locale (à mettre au README)

# Drill — release perso (routine ~5 min) $env:APP_VARIANT = 'production' eas build --profile preview --platform android --local adb install .\build-*.apk # téléphone branché (ch. 12.4 pour la vie sans câble)

Trois lignes. C’est TOUT le coût d’une release d’app perso — à comparer aux frictions imaginées qui retiennent les gens de faire des apps.

⚠️ Piège — Le prebuild —clean sous variante PROD écrase l’éventuel natif de variante dev : si run:android se met à installer « Drill » au lieu de « Drill Dev » ensuite, c’est que la variable APP_VARIANT a fuité d’une session PowerShell. Réflexe : afficher $env:APP_VARIANT avant tout build, et penser « une fenêtre de terminal = une variante ».

💡 Pour un dev Next.js — gradle est le webpack+npm du monde JVM : ses tâches (assembleRelease, bundleRelease pour l’AAB), son cache (~/.gradle), ses propriétés. Vous n’aurez presque jamais à écrire du gradle — mais savoir LIRE ses erreurs (la première ligne > Task :app:xyz FAILED + le premier Caused by:) transforme les échecs de build de malédiction en diagnostic.

✏️ Exercices

1. Faites le build local (route 1), vérifiez l’empreinte SHA-1 contre celle notée au ch. 12.2, installez par-dessus l’APK cloud SANS désinstaller. La mise à jour passe-t-elle ?

✅ Solution

keytool -printcert -jarfile build-*.apk → même SHA-1 que le keystore EAS (la CLI l’a utilisé) → adb install -r build-*.apk (le -r = replace) passe sans erreur, historique SQLite intact. C’est la preuve opérationnelle de la règle d’or — la faire UNE fois vaut toutes les explications.

2. Provoquez le cauchemar en environnement contrôlé : gradle direct SANS config de signature (debug key) et tentez l’installation par-dessus. Lisez l’erreur, puis nettoyez.

✅ Solution

gradlew assembleRelease naïf → adb install -r app-release.apkINSTALL_FAILED_UPDATE_INCOMPATIBLE (signatures debug ≠ EAS). Nettoyage : supprimer cet APK, ne PAS désinstaller Drill (les données !). L’erreur vue une fois en TP se reconnaît en 3 secondes en situation réelle.

3. Chronométrez les trois chemins sur votre machine (cloud, —local, gradle direct chaud) et écrivez la doctrine personnelle de VOTRE README (quand quoi).

✅ Solution

Ordres de grandeur attendus : cloud ~15-25 min porte à porte ; —local ~4-8 min ; gradle chaud ~2-3 min (mais signature à gérer). Doctrine type : « —local par défaut ; cloud si machine occupée/partage de lien ; gradle direct jamais en release (signature), utile en debug pour bisecter un échec de build ». L’important est d’avoir VOS chiffres.

🧠 Quiz

1. Qu’est-ce qu’eas build —local exécute exactement ?

Réponse

Le pipeline EAS complet (profils eas.json, prebuild, gradle, signature avec le keystore EAS) sur votre machine — mêmes artefacts que le cloud, sans quota ni file.

2. Pourquoi le gradle direct « propre » est-il compliqué sous CNG ?

Réponse

La config de signature vit dans android/… qui est généré : la poser à la main viole le contrat (effacée au —clean) — il faudrait un config plugin dédié. eas build —local contourne le problème entièrement.

3. Quelle erreur signale deux signatures incompatibles ?

Réponse

INSTALL_FAILED_UPDATE_INCOMPATIBLE à l’installation par-dessus — la mise à jour est refusée ; seule issue : désinstaller (et perdre les données) ou re-signer correctement.

4. Comment vérifier qui a signé un APK ?

Réponse

keytool -printcert -jarfile app.apk → comparer l’empreinte SHA-1 à celle du keystore de référence (notée au ch. 12.2).

5. Récitez le rituel de release perso de Drill.

Réponse

$env:APP_VARIANT='production'eas build --profile preview --platform android --localadb install .\build-*.apk. Trois lignes, ~5 minutes.


👉 Chapitre suivant : 12.4 — Installer sur TON téléphone — la vie de l’APK sans câble ni store.