Commande patch
La commande tk-ota-push patch compile le code Dart mis à jour, contrôle l'intégrité binaire native par rapport à la Release verrouillée, et transmet le nouveau binaire (binaire d'application sur Android, artefact de patch sur iOS) au serveur OTA (POST /api/admin/v1/patches). Le serveur calcule alors le différentiel binaire (différentiel binaire + compression optimisée) et le signe cryptographiquement via moteur cryptographique.
Syntaxe générale
tk-ota-push patch [version] [options] [-- <arguments-flutter>]
Flux d'exécution et génération du différentiel
- Préparation : Vérification des métadonnées du projet et de la configuration
shorebird.yaml. - Compilation Dart : Construction du snapshot applicatif pour chaque architecture cible (
aarch64,arm, etc.). - Calcul du différentiel : Calcul de l'empreinte différentielle compressée par rapport à la release socle.
- Téléversement sécurisé : Transmission du patch au serveur avec le statut initial
STAGED.
1. Compilation et liaison par plateforme
Sur Android (patchAndroid)
- La CLI exécute
flutter build apk --release(ouappbundlesi--artifact aab) avecSHOREBIRD_PUBLIC_KEY. - Elle extrait les binaires
binaire d'applicationstrippés directement depuis l'archive.apkou.aabpour chaque architecture demandée (aarch64etarmpar défaut avec--arch all). - Elle interroge
GET /api/admin/v1/releases/lookuppour récupérer lenativeCodeHashde la Release de référence et le compare aulocalNativeHashcalculé parNativeIntegrityScanner. - Elle envoie chaque
binaire d'applicationet son fichier.symbols(app.android-arm64.symbols/app.android-arm.symbols) àPOST /api/admin/v1/patches.
Sur iOS (patchIos)
- La CLI vérifie la présence de
.ota_ios_release_cache/<version>/Appetdiff_base. - Elle calcule le SHA-256 local de
diff_baseet le compare aubaseSha256Hashretourné parGET /api/admin/v1/releases/lookup(platform=ios,arch=aarch64). En cas de divergence (MISMATCH DE HASH iOS), la génération est immédiatement annulée. - Elle lance
flutter build ios --release --no-codesign, récupèreapp.dilldans.dart_tool/flutter_build/et le copie dansbuild/app.dill. - Elle génère le snapshot ELF
build/out.aotviagen_snapshot_arm64:<gen_snapshot_arm64> --deterministic --snapshot-kind=app-aot-elf --elf=build/out.aot [splitDebugArgs] build/app.dill - Elle exécute
aot-tools.dill linkpour lier le binaire de baseAppet le nouveau snapshotout.aoten un fichierbuild/artefact de patch:<dart> <aot-tools.dill> link \
--base=.ota_ios_release_cache/<version>/App \
--patch=build/out.aot \
--analyze-snapshot=<analyze_snapshot_arm64> \
--gen-snapshot=<gen_snapshot_arm64> \
--kernel=build/app.dill \
--output=build/artefact de patch - Elle restaure le
Runner.appsigné depuis.ota_ios_release_cache/<version>/Runner.app, vérifie l'intégrité native iOS (Info.plistetFrameworks/), puis envoieartefact de patchau serveur OTA.
2. Différentiel différentiel binaire + compression optimisée et Signature cryptographique
À la réception de POST /api/admin/v1/patches, le serveur OTA (Serveur TkushPatch) :
- Contrôle la taille du binaire soumis (garde-fou anti-bomb : 60 Mo max par défaut).
- Charge le binaire de référence exact enregistré lors de la Release (
binaire d'applicationoudiff_base). - Génère le patch différentiel compressé au format
différentiel binaire+compression optimiséeet vérifie que sa taille ne dépasse pas la limitemaxPatchDiffSizeBytes(15 Mo par défaut). - Calcule l'empreinte
targetUncompressedSha256Hex(SHA-256 du nouveau binaire complet). - Si
auto_approve=true(aucun flag--staged) et que le tenant n'impose pas la règle stricte des 4 yeux (enforceFourEyes == false), signe immédiatement les 64 octets ASCII du SHA-256 cible via moteur cryptographique (APPROVED_AND_SIGNED). Sinon, le patch est créé à l'étatSTAGED.
3. Vérifications natives qui bloquent un patch
Le moteur OTA remplace uniquement le code Dart (binaire d'application / App.framework). Si vous modifiez du code natif ou des permissions entre la Release et le Patch, NativeIntegrityScanner détecte une différence de nativeCodeHash :
- Android : modification de
classes*.dex(Java/Kotlin), deAndroidManifest.xmlou d'une librairie C/C++lib/<arch>/*.so(horsbinaire d'application). - iOS : modification de
Info.plist, du binaire principalRunnerou d'un framework dansFrameworks/(horsApp.framework).
Dans ce cas, la CLI bloque la publication avec une CliException (code de sortie 1) et vous invite à publier une nouvelle Release Store. Le flag --force (-f) permet d'outrepasser cette vérification (ainsi que la vérification pubspecLockHash), à vos risques et périls.
pubspec.lock (dépendances Dart pures)Une mise à jour d'un package 100 % Dart modifie pubspec.lock mais ne modifie pas nativeCodeHash. La CLI laisse donc passer le patch sans exiger --force, tandis que le serveur journalise simplement une notification informative.
4. Options clés de la commande patch
| Option / Flag | Rôle | Exemple |
|---|---|---|
-c, --channel <canal> | Canal de publication (stable, staging, beta) | --channel staging |
-m, --message <texte> | Description métier / changelog affiché aux réviseurs dans la Console | -m "Fix calcul TVA" |
--rollout <0-100> | Pourcentage de déploiement initial (Canary) | --rollout 10 |
--countries <codes> | Ciblage géographique ISO-2 séparé par des virgules ou "all" | --countries "CI,SN,CM" |
--staged | Place le patch en quarantaine STAGED (attente de validation 4-yeux) | --staged |
-f, --force | Ignore la divergence native et aligne pubspecLockHash sur la Release | --force |
Exemples pratiques
# 1. Patch simple sur le canal par défaut (100 % rollout, mondial)
tk-ota-push patch -m "Correction affichage solde"
# 2. Patch Android uniquement pour l'architecture 64-bits sur le canal staging
tk-ota-push patch 1.0.0+3 -p android -a aarch64 -c staging -m "Test QA 64-bit"
# 3. Patch avec Flavor prod, fichier d'environnement, ciblage pays et rollout 25 %
tk-ota-push patch 2.1.0+105 -p android \
--flavor prod \
-t lib/main_prod.dart \
--dart-define-from-file=env/prod.json \
--artifact aab \
--countries "CI,SN,CM" \
--rollout 25 \
--staged \
-m "Correctif calcul frais de virement"