Skip to Content
React Native12. Distribution perso ⭐12.6 Versionner & vivre avec

Chapitre 12.6 — Versionner & vivre avec son app

Où on en est : build, sideload, OTA — toutes les pièces existent. Ce chapitre les assemble en ROUTINE : les trois nombres de version, l’arbre de décision des mises à jour, et la checklist de release. La fin de la voie perso — Drill vit sur ton téléphone.

⏱️ TL;DR — Trois versions à tenir droites : version (semver humain, pilote la runtimeVersion), versionCode (entier Android, autoIncrement EAS), et l’updateId (implicite, par OTA). L’arbre de décision : données → git push ; JS → eas update ; natif → bump version + rebuild + réinstall. La checklist de release ferme la partie — et le parallèle avec le futur Play Store est déjà écrit.

🎯 Objectifs

  • Fixer la stratégie de versions (qui bouge quand, qui l’incrémente).
  • Intérioriser l’arbre de décision complet des mises à jour.
  • Poser la checklist de release perso (copiable pour chaque app).
  • Savoir diagnostiquer « quelle version tourne ? » en 30 secondes.

Les trois nombres

NombreExempleQui le changeRôle
version1.3.0Vous, à chaque changement NATIF (et aux jalons marketing)Humain + pilote runtimeVersion
android.versionCode9EAS (autoIncrement)L’ordre pour Android (jamais redescendre)
updateIduuidEAS Update, à chaque publicationIdentifie le JS exact qui tourne

La règle qui simplifie tout : version = la version du CONTENEUR natif. Elle ne bouge que quand le natif bouge (module, config, SDK) — c’est la discipline runtimeVersion du ch. 12.5. Les évolutions JS s’empilent en OTA sous la même version ; leur traçabilité est l’updateId + vos messages -m.

Semver pragmatique pour une app perso : MAJOR = refonte/rupture de données, MINOR = tout changement natif ordinaire, PATCH = rebuild natif sans nouveauté (rare). Pas de dogme — de la cohérence.

L’arbre de décision — le poster de la partie

Trois canaux, trois coûts (secondes / minutes / dizaines de minutes) — et l’architecture du cours entier se relit dedans : l’ADR 0001 (questions hors app) et la frontière bundle/natif (ch. 1.2) étaient précisément des décisions de CANAL de mise à jour. Rien n’était gratuit : tout était pensé pour que le quotidien coûte le moins possible.

La checklist de release perso

À copier dans le README de chaque app (versions Drill) :

Release JS (la routine, ~2 min)

  • La feature marche en dev build (+ test rapide des écrans touchés)
  • pnpm tsc --noEmit (le filet TS — la P14 ajoutera les tests)
  • eas update --channel preview -m "message clair"
  • Ouvrir l’app ×2 sur le téléphone → vérifier

Release native (l’événement, ~20 min)

  • Bump version dans app.config.ts (+ le CHANGELOG.md — 3 lignes suffisent)
  • Le fallback de questions bundlé est-il à rafraîchir ? (ch. 7.4)
  • $env:APP_VARIANT='production'; eas build --profile preview --platform android --local
  • adb install -r → rituel : partie complète, notif, deep link, offline (matrice 7.4)
  • eas update --channel preview -m "baseline 1.3.0" (aligner l’OTA sur le nouveau runtime)
  • Tag git : git tag v1.3.0 && git push --tags

Le dernier point mérite son pourquoi : votre repo Git est la SEULE mémoire de « quel code correspond à quoi » — le tag au moment du build natif est la pierre de gué qui permet, dans six mois, de comprendre ce que contient le binaire qui tourne encore chez votre frère.

Diagnostiquer : « quelle version tourne ? »

L’écran À propos (Réglages) — 10 lignes qui économisent des heures :

import * as Application from 'expo-application' // npx expo install expo-application import * as Updates from 'expo-updates' <Card> <AppText variant="caption">Version {Application.nativeApplicationVersion} {' '}(build {Application.nativeBuildVersion})</AppText> <AppText variant="caption">JS : {Updates.updateId?.slice(0, 8) ?? 'embarqué'} {' · '}channel {Updates.channel ?? 'dev'}</AppText> </Card>

Version native + build + updateId + channel : le quadruplet qui répond à « chez moi ça bugue » — « envoie-moi une capture de l’écran À propos » devient votre première réponse de support.

⚠️ Piège — La dérive classique de la voie perso : builds natifs espacés de plusieurs mois + OTA quotidiennes = un jour, un changement natif s’oublie dans une OTA (« ah, ce fix utilisait aussi expo-camera… »). Les garde-fous : la runtimeVersion (crash évité — l’update ne part pas au mauvais runtime), et eas update qui REFUSE de publier si le bundle référence des modules absents de la runtime cible… dans la plupart des cas. Le réflexe humain reste : chaque expo install d’un module NATIF déclenche mentalement « prochaine release = native ».

💡 Pour un dev Next.js — Votre modèle mental final, en vocabulaire web : le binaire = l’infra (on la redéploie rarement), l’OTA = le deploy continu, le repo de questions = le CMS. Trois cadences que le web fusionne en une seule (l’URL) et que le mobile force à distinguer — mais une fois la routine posée, la différence de confort avec le web est devenue… marginale. C’était le but de la partie.

✏️ Exercices

1. Écrivez le CHANGELOG.md de Drill rétroactivement (versions fictives raisonnables depuis la 0.1.0 du ch. 2.5 jusqu’à la 1.0.0 « fin de P12 »), en marquant pour chaque entrée le canal (natif/OTA).

✅ Solution

Exemple attendu : 0.1.0 natif (naissance) · 0.2.0 natif (dev-client, variantes) · 0.3.0 natif (expo-updates, identité, splash) · puis des 0.3.x en OTA (timer pulse, stats, partage) · 1.0.0 natif (baseline de la voie perso complète). L’exercice révèle la cadence réelle : BEAUCOUP d’OTA entre PEU de natifs — la forme normale d’une app perso saine.

2. Panne simulée : votre frère (v1.2, updateId abc123) a un crash à l’ouverture des stats ; vous êtes en v1.3 localement. Déroulez le diagnostic AVEC les outils du chapitre — puis le fix par le bon canal.

✅ Solution

(1) Écran À propos → version 1.2, updateId abc123, channel preview. (2) Dashboard expo.dev/updates → retrouver le commit du bundle abc123 (vos messages -m + tags git). (3) Reproduire sur ce code (git checkout du tag/commit). (4) Fix JS → eas update --channel preview ciblera runtimeVersion 1.2 ET 1.3 ? Non — une update par runtime : publier DEPUIS la branche 1.2 si le natif diffère, sinon l’update courante suffit (même runtime). Le cas montre pourquoi on limite la dispersion des runtimes : pousser les proches vers le dernier APK de temps en temps reste sain.

3. Fermez la boucle : rédigez en 5 lignes le « contrat de maintenance » de vos apps perso (à quelle vitesse quel type de bug est fixé, par quel canal) — le README de nouveau.

✅ Solution

Type : « Contenu (question fausse) : git push, < 1 h. Bug JS gênant : OTA jour même. Bug JS cosmétique : OTA groupée hebdo. Besoin natif : release native au prochain week-end, tag + changelog. Perte de keystore : impossible — sauvegardé à deux endroits (ch. 12.2). » Un contrat écrit, même pour soi, transforme la maintenance de corvée diffuse en routine bornée.

🧠 Quiz

1. Quand bump-t-on version, et qui gère versionCode ?

Réponse

version bouge à chaque changement natif (elle pilote la runtimeVersion) ; versionCode est incrémenté automatiquement par EAS (autoIncrement) — jamais à la main, jamais en arrière.

2. Récitez l’arbre de décision des mises à jour.

Réponse

Contenu (questions) → git push (~minutes). JS/TS/assets bundlés → eas update (prochaine ouverture). Natif/config/icône/SDK → bump version + rebuild + install -r (réinstallation).

3. Que contient l’écran À propos, et pourquoi ?

Réponse

Version native, build number, updateId (8 premiers caractères), channel — le quadruplet qui identifie EXACTEMENT ce qui tourne : la première réponse à tout rapport de bug.

4. À quoi sert le tag git au moment d’un build natif ?

Réponse

À retrouver dans six mois le code exact du binaire encore installé quelque part — la seule mémoire fiable du lien code ↔ artefact.

5. Quel réflexe mental accompagne chaque expo install d’un module natif ?

Réponse

« La prochaine release est native » : bump de version à prévoir, pas d’OTA pour cette feature — le garde-fou humain au-dessus de la runtimeVersion.


👉 Partie suivante : Partie 13 — Publier sur le Play Store — la voie publique : le compte, l’AAB, la fiche, le test fermé, la review. Tout ce qu’on vient de construire… plus la bureaucratie.