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 --localLe 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.apkMais 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 à comparerLe 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_VARIANTavant 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 premierCaused 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.apk →
INSTALL_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 --local
→ adb 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.