Un guide pas à pas, indépendant de la version, pour mettre à niveau React Native avec des tableaux d'inventaire, des commandes d'alignement multiplateforme, des vérifications de validation et des procédures de restauration.

## TL;DR

- Capturer un tag de base précis et un inventaire avant toute modification.

- Mettre à niveau par étapes délimitées : noyau RN → modèle/chaîne d'outils iOS → modèle/chaîne d'outils Android → bibliothèques critiques.

- Vérifier avec des vérifications de build Debug reproductibles, puis passer aux builds Release sur appareils physiques.

- Maintenir un chemin de restauration rapide via les tags git, les lockfiles gelés et les reconstructions natives propres.

- Protéger les changements risqués avec des feature flags et des déploiements progressifs ; utiliser l'OTA uniquement quand l'ABI native est stable.

## Prérequis et Hypothèses

- État git propre : arbre de travail commité ou mis de côté ; pas d'artefacts natifs non suivis (ios/build, android/.gradle, ios/Pods).

- Parité CI : versions de Node, Yarn/npm, Java, Xcode, CocoaPods, Android SDK/NDK identiques à celles de vos agents CI.

- Accès aux plateformes : compte Apple Developer et accès Google Play Console pour la validation Release et le déploiement progressif.

- Appareils physiques : requis pour le comportement Hermes JIT/AOT, les bibliothèques de facturation et le profilage de performance Release.

- Convention : toutes les versions, bundle IDs, noms de schémas et chemins sont des exemples ; remplacez par vos valeurs projet.

## Architecture et Contexte d'Exécution

Comprendre les points de couplage empêche les régressions silencieuses.

- Hermes vs JavaScriptCore : Hermes compile le JS en bytecode ahead-of-time (AOT sur iOS, JIT+AOT sur Android). Des réglages Hermes/JSC mixtes entre plateformes causent des incompatibilités ABI et des crashs. Maintenez enableHermes / :hermes_enabled identiques sur iOS et Android.

- Cache Metro : Metro met en cache la résolution de modules et les transformations. Les mises à niveau natives (version RN, modules natifs) invalident ce cache. Lancez toujours npx react-native start --reset-cache après des changements natifs.

- Couplage de la chaîne d'outils native : chaque version RN épingle les versions minimales de Xcode, CocoaPods, AGP, Gradle wrapper, NDK, minSdkVersion et cible de déploiement iOS. S'éloigner du modèle cause des échecs de build ou des crashs runtime. Utilisez l'assistant de mise à niveau pour lire les exigences exactes de votre version cible.

## Matrice de Compatibilité des Versions et Utilisation de l'Assistant de Mise à Niveau

Consultez les notes de version officielles React Native et l'assistant de mise à niveau pour la matrice faisant autorité. Le schéma de tableau ci-dessous montre quoi enregistrer pour votre version cible X.Y.Z.

<div class="my-stack-md overflow-x-auto">
<table class="w-full min-w-[42rem] border-collapse text-left">
<thead><tr><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Composant</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Source de Vérité</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Exemple de Valeur (Construit)</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Notes</th></tr></thead>
<tbody><tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">React Native</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">reactnative.dev/versions / Upgrade Helper</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">0.76.x</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Version cible</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Xcode</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Diff Upgrade Helper / Release notes</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">15.4</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Minimum supporté</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">CocoaPods</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Release notes</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">1.15.2</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Aligner équipe/CI</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Cible de déploiement iOS</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Diff modèle ios/Podfile</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">15.1</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">platform :ios, &#39;15.1&#39;</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">AGP</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Diff modèle android/build.gradle</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">8.5.0</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">com.android.application</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Gradle Wrapper</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Diff modèle gradle-wrapper.properties</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">8.7</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">distributionUrl</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">NDK</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Diff modèle android/app/build.gradle</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">26.1.10909125</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Installation côte à côte OK</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">compileSdkVersion</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Diff modèle</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">34</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Exigence Google Play</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">minSdkVersion</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Diff modèle</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">24</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Les minimums de bibliothèques peuvent l&#39;augmenter</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">targetSdkVersion</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Diff modèle</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">34</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Exigence Google Play</td></tr></tbody>
</table>
</div>
Récupérez le diff de modèle pour votre version cible :

# Mise à niveau CLI en simulation (utilise rn-diff-purge en arrière-plan)
npx @react-native-community/cli upgrade --dry-run X.Y.Z

# Ou consultez l'assistant web de mise à niveau (cherchez "React Native upgrade helper" sur reactnative.dev) 
 Examinez les diffs via git diff après la commande de mise à niveau, ou inspectez les changements fichier par fichier de l'assistant web. Préférez l'alignement manuel du modèle quand votre projet a de lourdes personnalisations (MainApplication, AppDelegate, scripts de build ou modules natifs forkés sur mesure).

## Inventaire

Capturez l'état exact d'exécution et de build avant tout changement. Enregistrez dans un ticket ou README-upgrade.md.

<div class="my-stack-md overflow-x-auto">
<table class="w-full min-w-[42rem] border-collapse text-left">
<thead><tr><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Élément</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Où / Commande</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Exemple de Valeur (Construit)</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Notes</th></tr></thead>
<tbody><tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">React Native</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">package.json ou node -p &quot;require(&#39;./package.json&#39;).dependencies[&#39;react-native&#39;]&quot;</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">0.74.5</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Version actuelle</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Node &amp; Gestionnaires de paquets</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">node -v, npm -v, yarn -v, pnpm -v</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Node 20.12, Yarn 4.1</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Aligner CI</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Chaîne d&#39;outils iOS</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">xcodebuild -version, pod --version</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Xcode 15.3, CocoaPods 1.15.2</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Sync équipe</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Chaîne d&#39;outils Android</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">cat android/gradle/wrapper/gradle-wrapper.properties, grep &quot;com.android.tools.build:gradle&quot; android/build.gradle</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Gradle 8.5, AGP 8.4.0</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Aligner avec modèle RN</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Niveaux SDK</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">android/app/build.gradle, ios/Podfile</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">minSdk 23, targetSdk 34, compileSdk 34, iOS 15.1</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Politiques stores</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Hermes</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">grep hermes android/app/build.gradle ios/Podfile</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">activé</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Cohérence requise</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Bibliothèques critiques</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">npm ls --depth=0 | grep -E &quot;navigation|reanimated|gesture|stripe|billing&quot;</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">@react-navigation/native 6.x, react-native-reanimated 3.x</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Contraintes PeerDependency</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Parité CI</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Config CI (.github/workflows, bitrise.yml)</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Node 20.12, Xcode 15.3, JDK 17</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Doit correspondre local</td></tr></tbody>
</table>
</div>
Notes Expo (construites) :

- Workflow géré : noter la version SDK (ex: SDK 51) ; lancer npx expo doctor avant la mise à niveau.

- Workflow nu : traiter comme app RN standard ; expo prebuild --clean peut valider la config native après changements.

## Chemin de Configuration Sécurisé

La portée et le séquencement limitent le rayon d'impact. Promouvez les changements par étapes observables.

### 1. Choisir la Version Cible et Créer la Base

git checkout -b upgrade/rn-X.Y.Z
git tag pre-rn-X.Y.Z # tag de base pour restauration rapide 
 Commitez les lockfiles (yarn.lock / package-lock.json) s'ils ne sont pas déjà suivis. Enregistrez le tableau d'inventaire dans la description de branche.

### 2. Définir un Flux Pilote Restreint

Sélectionnez un écran touchant la logique JS, l'UI native et les E/S réseau (exemple construit : Paramètres → Connexion → Récupérer Profil). Définissez les critères succès/échec : pas de redbox, API 200, token persisté, UI rendue.

### 3. Mettre à Niveau le Noyau React Native et Appliquer les Diffs de Modèle

# Dépendance JavaScript (choisir l'un)
npm install react-native@X.Y.Z --save
# ou
yarn add react-native@X.Y.Z

# Appliquer les diffs de modèle via CLI (utilise rn-diff-purge)
npx react-native upgrade X.Y.Z 
 Résolvez les invites prudemment : préférez conserver les changements spécifiques au projet. Inspectez git diff immédiatement ; commitez le bump RN et l'alignement de modèle séparément.

### 4. Ordre de Mise à Niveau des Dépendances (Sensible aux PeerDependencies)

Mettez à niveau les bibliothèques critiques une par une, en committant après chacune. Lisez les changelogs pour les exigences minimales RN/Android/iOS.

- react-native (noyau)

- @react-native-community/* (cli, netinfo, async-storage, etc.)

- Navigation (@react-navigation/*)

- react-native-gesture-handler, react-native-reanimated (couplage étroit RN)

- react-native-stripe-sdk, react-native-google-play-billing (couplage politiques stores)

- Chargeurs d'images, analytics, crash reporting, autres

## Alignement iOS

Alignez le projet Xcode, CocoaPods et la signature au modèle RN cible.

### Configuration Podfile (Exemple Construit)

# ios/Podfile
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

platform :ios, '15.1' # du diff modèle
prepare_react_native_project!

target 'YourApp' do
 config = use_native_modules!
 use_react_native!(
 :path => config[:reactNativePath],
 :hermes_enabled => true, # correspondre à Android
 :fabric_enabled => false, # activer quand prêt
 :flipper_configuration => FlipperConfiguration.disabled, # ou .enabled pour Debug
 :app_path => "#{Pod::Config.instance.installation_root}/.."
 )
 post_install do |installer|
 react_native_post_install(installer)
 # Contournement signature Xcode 15+ en CI
 installer.pods_project.targets.each do |target|
 target.build_configurations.each do |config|
 config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
 end
 end
 end
end 

### Installation et Build Debug

 cd ios
pod install --repo-update
cd ..

# Build Debug pour simulateur (CI-friendly)
xcodebuild -workspace ios/YourApp.xcworkspace \
 -scheme YourApp \
 -configuration Debug \
 -sdk iphonesimulator \
 -derivedDataPath ios/build \
 clean build 
 Points clés : cible de déploiement conforme au modèle ; hermes_enabled cohérent ; Flipper désactivé pour Release ou aligné à la version RN ; signature réglée sur CODE_SIGNING_ALLOWED=NO pour CI.

## Alignement Android

Alignez Gradle wrapper, AGP, NDK, niveaux SDK et drapeaux Hermes/Fabric.

### Gradle Wrapper et AGP (Construit pour Cible RN 0.76)

# Mettre à jour le wrapper
cd android
./gradlew wrapper --gradle-version 8.7
cd .. 
 // android/build.gradle (niveau projet)
plugins {
 id 'com.android.application' version '8.5.0' apply false
 id 'com.android.library' version '8.5.0' apply false
 id 'org.jetbrains.kotlin.android' version '1.9.20' apply false
} 

### Module App SDK et Hermes (Construit)

 // android/app/build.gradle
android {
 namespace "com.yourcompany.yourapp"
 compileSdkVersion 34
 ndkVersion "26.1.10909125"

 defaultConfig {
 applicationId "com.yourcompany.yourapp"
 minSdkVersion 24
 targetSdkVersion 34
 versionCode 1
 versionName "1.0"
 }

 // Drapeaux Hermes et Fabric (correspondre à iOS)
 project.ext.react = [
 enableHermes: true,
 enableFabric: false
 ]
} 

### Règles ProGuard / R8 Keep (Construit)

 # android/app/proguard-rules.pro
# Reanimated
-keep class com.swmansion.reanimated.** { *; }
-keepclassmembers class com.swmansion.reanimated.** { *; }

# Stripe
-keep class com.stripe.** { *; }
-dontwarn com.stripe.**

# Google Play Billing
-keep class com.android.billingclient.** { *; }
-keep class com.google.android.play.core.** { *; } 

### Build Debug Propre

 cd android
./gradlew clean assembleDebug --no-daemon
cd .. 

## Migrations de Bibliothèques

 Suivez l'ordre de mise à niveau des dépendances du Chemin de Configuration Sécurisé. Pour chaque bibliothèque :

- Bumpez la version dans package.json (respectez les plages peerDependency).

- Lancez npm install / yarn install .

- Lancez cd ios && pod install && cd .. si la bibliothèque a du code natif iOS.

- Construisez Debug sur les deux plateformes.

- Exécutez le flux pilote.

- Commitez avec message : upgrade: <bibliothèque>@<version> – <intention> .

Points de vigilance PeerDependency : react-native-reanimated et react-native-gesture-handler verrouillent souvent sur des versions mineures RN spécifiques. react-native-stripe-sdk et react-native-google-play-billing imposent des planchers minSdk / compileSdk. Lisez leurs package.json peerDependencies avant de mettre à niveau.

## Vérification et Diagnostics

Prouvez que la mise à niveau fonctionne avec des vérifications reproductibles. Commencez en Debug ; passez au Release sur appareils physiques.

### Build Debug et Flux Pilote

# Android
npx react-native run-android

# iOS Simulateur
npx react-native run-ios 
 Exécutez le flux pilote : Lancement → Navigation → Connexion (API 200, token stocké) → Récupération Profil (rendu, pull-to-refresh).

### Logs et Diagnostics

# Android : filtrer logs RN/JS
adb logcat *:S ReactNative:V ReactNativeJS:V

# iOS : logs récents (remplacez YourApp)
log show --predicate 'process == "YourApp"' --style syslog --last 2m

# Reset cache Metro
npx react-native start --reset-cache 

### Vérifications Statiques

 npm test -- --watchAll=false
npx tsc --noEmit
npx eslint . 

### Test de Fumée Release Build (Appareil Physique Requis)

 # Android Release (inclut bundle JS)
./gradlew assembleRelease bundleReleaseJsAndAssets

# iOS Release (CI-friendly, sans signature)
xcodebuild -workspace ios/YourApp.xcworkspace \
 -scheme YourApp \
 -configuration Release \
 -sdk iphoneos \
 -derivedDataPath ios/build \
 CODE_SIGNING_ALLOWED=NO \
 clean build 
 Installez les builds Release sur appareils physiques. Testez Hermes JIT/AOT, flux facturation, Stripe et transitions premier/arrière-plan.

### Validation de Performance (Exemples Construits)

- Démarrage à froid : ajoutez console.time('bootstrap') à l'entrée app ; console.timeEnd('bootstrap') dans useEffect du composant racine. Extrayez depuis adb logcat / os_log. Comparez avant/après ; dérive dans 10–15% acceptable.

- Chutes de frames : activez why-did-you-render en Debug ou capturez Systrace ( npx react-native profile-hermes ).

- Taille du bundle :

npx react-native bundle --dev false --platform ios \
 --entry-file index.js \
 --bundle-output /tmp/main.jsbundle \
 --assets-dest /tmp
 # Analyser avec hermes-bytecode-analyzer si Hermes activé 

### Vérifications Sécurité et Conformité

- Vérifiez TLS 1.2+ sur toutes les requêtes réseau (Charles/ProxyMan).

- Confirmez pas de drapeaux __DEV__, console.log de secrets, ou debuggable true dans Release AndroidManifest.xml / Entitlements.plist.

- Validez que versions SDK Stripe / Google Play Billing respectent les minimums actuels des stores.

### Tableau de Vérification (Adaptez à Votre Projet)

 Vérification Comment Exécuter Critères Succès Notes 
 Build Android Debug ./gradlew assembleDebug Build réussit, app lance Exemple construit 
 Build iOS Debug xcodebuild clean build (simulateur) Simulateur lance app Exemple construit 
 Flux pilote fonctionne Navigation manuelle Pas de redbox ; UI rendue ; API 200 Exemple construit 
 Logs propres adb logcat, log show Pas de crash/avertissements sévères Exemple construit 
 Vérifications statiques passent npm test, tsc, eslint Zéro échec Exemple construit 
 Build Android Release ./gradlew assembleRelease bundleReleaseJsAndAssets APK/AAB produit ; installe sur appareil Appareil physique 
 Build iOS Release xcodebuild -configuration Release .app produit ; installe sur appareil Appareil physique 
 Flux pilote Release Test appareil physique Pas de crash ; facturation/Stripe fonctionnent Hermes AOT, réseau réel 
 Base performance console.time démarrage à froid Dans 10–15% d'avant mise à niveau Exemple construit 
 Scan sécurité Proxy TLS, grep __DEV__ TLS 1.2+ ; pas de fuites debug Exemple construit 

## Modes de Défaillance et Récupération

 Diagnostics ciblés pour symptômes courants de mise à niveau.

<div class="my-stack-md overflow-x-auto">
<table class="w-full min-w-[42rem] border-collapse text-left">
<thead><tr><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Symptôme</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Cause Probable</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Action et Commandes</th></tr></thead>
<tbody><tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Erreur spec/CDN CocoaPods</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Repo ou lockfile obsolète</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">cd ios &amp;&amp; rm -rf Pods Podfile.lock &amp;&amp; pod repo update &amp;&amp; pod install &amp;&amp; cd ..</code></td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Symboles dupliqués Xcode / Crash Flipper</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Incompatibilité version Flipper</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Désactiver Flipper dans Podfile : <code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">:flipper_configuration =&gt; FlipperConfiguration.disabled</code> ; reconstruire ; réactiver après alignement.</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Classe dupliquée Android</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Conflit dépendance transitive</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">cd android &amp;&amp; ./gradlew :app:dependencies --configuration debugCompileClasspath &gt; debugDeps.txt &amp;&amp; cd ..</code> ; aligner versions.</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Incompatibilité bytecode Hermes / Crash lancement</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Drapeau Hermes incohérent ou caches obsolètes</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Assurer enableHermes / :hermes_enabled identiques ; <code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">cd ios &amp;&amp; rm -rf build Pods Podfile.lock &amp;&amp; pod install &amp;&amp; cd ..</code> ; <code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">cd android &amp;&amp; ./gradlew clean &amp;&amp; cd ..</code> ; <code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">npx react-native start --reset-cache</code>.</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Metro &quot;Unable to resolve module&quot;</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Cache obsolète / watchman</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">rm -rf node_modules &amp;&amp; npm ci &amp;&amp; npx react-native start --reset-cache</code> ; <code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">watchman watch-del-all</code>.</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Xcode &quot;Command PhaseScriptExecution failed&quot; (Hermes dSYM)</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Course génération dSYM</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Nettoyer derived data ; assurer DEBUG_INFORMATION_FORMAT = dwarf-with-dsym seulement pour Release ; désactiver Hermes dSYM en Debug si persistant.</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Android &quot;Manifest merger failed&quot;</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Conflit minSdk / targetSdk</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Augmenter minSdkVersion dans android/app/build.gradle pour satisfaire toutes bibliothèques ; assurer tools:node=&quot;replace&quot; pour permissions conflictuelles.</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Crashs ProGuard/R8 (Release seulement)</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Règles keep manquantes</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Ajouter règles keep pour reanimated, Stripe, Play Billing (voir Alignement Android) ; tester build Release après chaque ajout.</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Échec réseau/TLS Release seulement</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Trafic clair ou pinning certificat</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Vérifier android:usesCleartextTraffic ; valider network_security_config.xml ; tester avec ProxyMan/Charles.</td></tr></tbody>
</table>
</div>

## Procédures de Restauration

### Restauration Locale (Rapide)

# Reset au tag de base
git reset --hard pre-rn-X.Y.Z

# Restaurer déps JS
npm ci --prefer-offline # ou yarn install --frozen-lockfile

# iOS reconstruction propre
cd ios
rm -rf Pods Podfile.lock build
pod install
cd ..

# Android reconstruction propre
cd android
./gradlew clean
cd .. 

### Restauration CI

- Revertez le commit PR/merge de mise à niveau.

- Déclenchez le pipeline sur main ; il utilisera les lockfiles gelés et toolchains en cache pour reconstruire la version précédente.

- Vérifiez la publication d'artefacts (TestFlight, piste interne Play Console).

### Stratégies de Restauration Production

- Déploiement progressif : mettez en pause ou réduisez le pourcentage de déploiement dans Play Console / App Store Connect quand le taux de crash augmente.

- Feature flags : désactivez les fonctionnalités risquées à distance (LaunchDarkly, Firebase Remote Config, personnalisé) en gardant la version app live.

- Mise à jour OTA JS (CodePush, Expo Updates, personnalisé) : revertez le bundle JS seulement si l'ABI native est inchangée. Si des modules natifs ont été ajoutés/supprimés ou la version RN a changé les interfaces natives, livrez un binaire hotfix.

### Validation Post-Restauration

- La version précédente build et lance sur les deux plateformes.

- Flux pilote passe ; logs propres.

- Taux de crash et avis stores reviennent à la base.

## Liste de Contrôle Opérationnelle

### Préparation

- [ ] Créer branche upgrade/rn-X.Y.Z ; taguer base pre-rn-X.Y.Z.

- [ ] Compléter inventaire : Node, gestionnaire paquets, RN, toolchains iOS/Android, Hermes, libs critiques, parité CI.

- [ ] Définir flux pilote restreint avec critères succès/échec.

### Étapes de Mise à Niveau

- [ ] Bumper react-native ; npm install / yarn add.

- [ ] Appliquer diffs modèle : npx react-native upgrade X.Y.Z.

- [ ] iOS : pod install ; confirmer Hermes ; build Debug.

- [ ] Android : mettre à jour Gradle wrapper & AGP ; confirmer niveaux SDK ; build Debug.

- [ ] Mettre à niveau bibliothèques critiques une par une (ordre selon Chemin Configuration Sécurisé) ; commiter après chacune.

### Vérification

- [ ] Lancer les deux plateformes ; exécuter flux pilote bout en bout.

- [ ] Vérifier logs : pas de crash/avertissements sévères.

- [ ] Lancer tests : unitaires, TypeScript, lint.

- [ ] Contrôle santé performance (démarrage à froid, navigation).

- [ ] Valider API REST, Stripe, Google Play Billing sur appareils physiques.

### Stabilisation

- [ ] Construire variantes Release localement une fois Debug propre.

- [ ] Réexécuter flux pilote et tests de fumée étendus sur builds Release.

- [ ] Documenter changements et étapes manuelles éventuelles.

### Préparation Récupération

- [ ] Tag de base accessible ; lockfiles committés.

- [ ] Commandes reconstruction propre documentées et testées.

- [ ] Feature flags configurés pour zones risquées.

### Transmission

- [ ] Partager inventaire, diffs, résultats vérification.

- [ ] Planifier déploiement avec monitoring et déclencheur restauration.

## Intégration CI/CD

 Exécutez inventaire, vérification et étapes de build dans le pipeline. Échouez vite sur régressions. Publiez artefacts pour QA.

### Extrait GitHub Actions (Construit)

# .github/workflows/rn-upgrade-validation.yml
name: RN Upgrade Validation
on:
 pull_request:
 branches: [main]
 paths:
 - 'package.json'
 - 'yarn.lock'
 - 'ios/**'
 - 'android/**'

jobs:
 validate:
 runs-on: macos-latest # ou self-hosted avec Xcode/Android SDK
 timeout-minutes: 60
 steps:
 - uses: actions/checkout@v4
 with:
 fetch-depth: 0 # nécessaire pour git diff / tags

 - name: Setup Node
 uses: actions/setup-node@v4
 with:
 node-version: '20.12'
 cache: 'yarn'

 - name: Setup Java
 uses: actions/setup-java@v4
 with:
 distribution: 'temurin'
 java-version: '17'

 - name: Setup Ruby
 uses: ruby/setup-ruby@v1
 with:
 ruby-version: '3.2'
 bundler-cache: true

 - name: Cache CocoaPods
 uses: actions/cache@v4
 with:
 path: ios/Pods
 key: pods-${{ hashFiles('ios/Podfile.lock') }}

 - name: Cache Gradle
 uses: actions/cache@v4
 with:
 path: |
 ~/.gradle/caches
 ~/.gradle/wrapper
 key: gradle-${{ hashFiles('android/gradle/wrapper/gradle-wrapper.properties', 'android/build.gradle') }}

 - name: Install JS deps
 run: yarn install --frozen-lockfile

 - name: Inventaire (capture base)
 run: |
 node -v
 yarn -v
 node -p "require('./package.json').dependencies['react-native']"
 xcodebuild -version
 pod --version
 cat android/gradle/wrapper/gradle-wrapper.properties
 grep "com.android.tools.build:gradle" android/build.gradle

 - name: TypeScript & Lint
 run: |
 npx tsc --noEmit
 npx eslint .

 - name: Tests Unitaires
 run: yarn test --watchAll=false --ci

 - name: iOS Debug Build
 run: |
 cd ios
 pod install --repo-update
 cd ..
 xcodebuild -workspace ios/YourApp.xcworkspace \
 -scheme YourApp \
 -configuration Debug \
 -sdk iphonesimulator \
 -derivedDataPath ios/build \
 clean build

 - name: Android Debug Build
 run: |
 cd android
 ./gradlew assembleDebug --no-daemon
 cd ..

 - name: Upload Android Debug APK
 uses: actions/upload-artifact@v4
 with:
 name: app-debug
 path: android/app/build/outputs/apk/debug/app-debug.apk

 # Optionnel : builds Release sur tags commits ou dispatch manuel
 # - name: Android Release Build
 # if: github.event_name == 'workflow_dispatch'
 # run: cd android && ./gradlew assembleRelease bundleReleaseJsAndAssets --no-daemon 
 Équivalents Bitrise / CircleCI : reprenez les mêmes étapes — cache CocoaPods/Gradle, gèlez lockfiles, lancez typecheck/lint/test, build Debug sur les deux plateformes, publiez artefacts. Conditionnez les builds Release à une approbation manuelle ou push de tag.

## Notes Sécurité et Conformité

- Sécurité transport : vérifiez que toutes requêtes réseau utilisent TLS 1.2+ ; pas de trafic en clair en Release. Inspectez Network Security Config (Android) et NSAppTransportSecurity (iOS).

- Drapeaux debug : assurez android:debuggable="false" dans Release AndroidManifest.xml ; DEBUG=0 / __DEV__=false dans bundle JS ; pas de console.log de PII/tokens.

- Conformité facturation : SDK Stripe et Google Play Billing Library doivent respecter les minimums stores actuels (ex: Play Billing Library 6+ pour cible Android 14). Testez flux achat sur appareils physiques avec comptes test.

- Droits et permissions : auditez Entitlements.plist et AndroidManifest.xml pour permissions inutilisées (localisation, caméra, microphone) après mises à niveau modules natifs.

- Chaîne d'approvisionnement : npm audit / yarn audit post-mise à niveau ; épinglez dépendances transitives si CVEs critiques apparaissent.

## Conclusion

Vous disposez maintenant d'un chemin pratique et à faible risque pour mettre à niveau React Native : rendre l'état actuel explicite avec un inventaire précis ; changer une tranche délimitée à la fois, en commençant par un flux pilote étroit ; aligner les modèles et chaînes d'outils iOS et Android, puis mettre à niveau les bibliothèques dans l'ordre des dépendances ; vérifier les résultats avec builds Debug, vérifications statiques, builds Release sur appareils physiques, bases de performance et scans de sécurité ; récupérer rapidement en utilisant le tag de base commité, les lockfiles gelés, les reconstructions natives propres et les feature flags. Répétez ce processus pour chaque étape de version, et vous réduirez les surprises, raccourcirez la récupération d'échec et continuerez à livrer tout en modernisant votre application.