Aller au contenu principal

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​

Étapes de génération d'un patch
  1. Préparation : Vérification des métadonnées du projet et de la configuration shorebird.yaml.
  2. Compilation Dart : Construction du snapshot applicatif pour chaque architecture cible (aarch64, arm, etc.).
  3. Calcul du différentiel : Calcul de l'empreinte différentielle compressée par rapport à la release socle.
  4. Téléversement sécurisé : Transmission du patch au serveur avec le statut initial STAGED.

1. Compilation et liaison par plateforme​

Sur Android (patchAndroid)​

  1. La CLI exécute flutter build apk --release (ou appbundle si --artifact aab) avec SHOREBIRD_PUBLIC_KEY.
  2. Elle extrait les binaires binaire d'application strippés directement depuis l'archive .apk ou .aab pour chaque architecture demandée (aarch64 et arm par défaut avec --arch all).
  3. Elle interroge GET /api/admin/v1/releases/lookup pour récupérer le nativeCodeHash de la Release de référence et le compare au localNativeHash calculé par NativeIntegrityScanner.
  4. Elle envoie chaque binaire d'application et son fichier .symbols (app.android-arm64.symbols / app.android-arm.symbols) à POST /api/admin/v1/patches.

Sur iOS (patchIos)​

  1. La CLI vérifie la présence de .ota_ios_release_cache/<version>/App et diff_base.
  2. Elle calcule le SHA-256 local de diff_base et le compare au baseSha256Hash retourné par GET /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.
  3. Elle lance flutter build ios --release --no-codesign, récupère app.dill dans .dart_tool/flutter_build/ et le copie dans build/app.dill.
  4. Elle génère le snapshot ELF build/out.aot via gen_snapshot_arm64 :
    <gen_snapshot_arm64> --deterministic --snapshot-kind=app-aot-elf --elf=build/out.aot [splitDebugArgs] build/app.dill
  5. Elle exécute aot-tools.dill link pour lier le binaire de base App et le nouveau snapshot out.aot en un fichier build/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
  6. Elle restaure le Runner.app signé depuis .ota_ios_release_cache/<version>/Runner.app, vérifie l'intégrité native iOS (Info.plist et Frameworks/), puis envoie artefact de patch au 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) :

  1. Contrôle la taille du binaire soumis (garde-fou anti-bomb : 60 Mo max par défaut).
  2. Charge le binaire de référence exact enregistré lors de la Release (binaire d'application ou diff_base).
  3. Génère le patch différentiel compressé au format différentiel binaire + compression optimisée et vérifie que sa taille ne dépasse pas la limite maxPatchDiffSizeBytes (15 Mo par défaut).
  4. Calcule l'empreinte targetUncompressedSha256Hex (SHA-256 du nouveau binaire complet).
  5. 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'état STAGED.

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), de AndroidManifest.xml ou d'une librairie C/C++ lib/<arch>/*.so (hors binaire d'application).
  • iOS : modification de Info.plist, du binaire principal Runner ou d'un framework dans Frameworks/ (hors App.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.

Changements dans 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 / FlagRôleExemple
-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"
--stagedPlace le patch en quarantaine STAGED (attente de validation 4-yeux)--staged
-f, --forceIgnore 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"