Canaux (Tracks) et Promotion Zéro-Recompilation
La page /apps/[appId]/tracks (src/app/apps/[appId]/tracks/page.tsx) permet d'isoler le cycle de validation des patchs OTA par environnement (Track / Channel) et de promouvoir un binaire certifié d'un canal à un autre sans jamais recompiler le code source Dart.
1. Les canaux standards et personnalisés
Par défaut, chaque application dispose de trois pistes standards auxquelles l'opérateur peut ajouter des pistes personnalisées :
| Canal | Usage recommandé | Comportement typique |
|---|---|---|
dev | Développement interne et tests unitaires d'intégration | Auto-approbation rapide en mode non-4-Yeux, tests sur émulateurs ou téléphones développeurs |
staging | Recette QA, pré-production et validation métier (UAT) | Protégé par la Liste Blanche QA (allowedClientIds) pour empêcher toute fuite hors de l'équipe de test |
stable | Flotte de production finale (clients finaux) | Soumis au bouclier IN_STORE_REVIEW, au contrôle à 4-Yeux (APPROVED_AND_SIGNED) et au Canary Rollout progressif |
| Canaux personnalisés | Pistes dédiées (ex. beta-vip, pilote-agences, canary-interne) | Créés depuis le bouton Nouveau Canal sur /apps/[appId]/tracks et persistés dans localStorage sous tks_custom_channels_<appId> (fusionnés automatiquement avec tout canal retourné par le backend) |
2. Pourquoi la promotion Zéro-Recompilation est essentielle
Dans un pipeline mobile classique, recompiler l'application entre l'environnement staging et l'environnement stable présente deux risques majeurs :
- Dérive non déterministe du binaire : Horodatages de compilation, versions mineures de dépendances ou variables d'environnement modifiées entre le build de recette et le build de production.
- Invalidation de la recette QA : Le binaire livré aux clients finaux sur
stablen'est plus mathématiquement identique au binaire validé par l'équipe QA surstaging.
Avec la Promotion 1-Clic de TkushPatch (Serveur TkushPatch), le serveur réutilise exactement le même artefact physique .vmcode (diffArtifactPath), le même targetSha256Hash et le même fichier de symboles .symbols.
- Recette initiale sur
devoustaging: Le patch est testé par les équipes de validation sur une flotte restreinte d'appareils autorisés. - Décision de promotion : Dès validation complète de la recette, le responsable clique sur Promouvoir vers Stable.
- Scellement de production : Le correctif reçoit la signature de production et le déploiement public commence.
3. Fonctionnement technique de la promotion (POST /api/admin/v1/patches/{id}/promote)
Lorsque l'opérateur (ROLE_ADMIN ou ROLE_SECURITY_OFFICER, permission PROMOTE_PATCH) clique sur Promouvoir depuis /apps/[appId]/tracks, /releases ou /rollout :
- Requête HTTP :
POST /api/admin/v1/patches/{patchId}/promote
Content-Type: application/json
{
"target_channel": "stable",
"promoted_by": "rssi@entreprise.com",
"tenant_id": "sara-money"
} - Contrôles de sécurité côté serveur (
Serveur TkushPatch) :- Vérifie l'isolation multi-tenant (
assertReleaseBelongsToTenant). - Contrôle d'état strict : Seul un patch dans l'état
APPROVED_AND_SIGNEDpeut être promu (sourcePatch.status() == PatchStatus.APPROVED_AND_SIGNED). Un patchSTAGEDouROLLED_BACKest formellement rejeté. - Contrôle de canal : Interdit de promouvoir un patch vers son propre canal source (
cleanTargetChannel.equalsIgnoreCase(sourcePatch.channel())).
- Vérifie l'isolation multi-tenant (
- Numérotation séquentielle par canal :
- Le serveur calcule le prochain numéro de patch disponible sur le canal cible pour cette release :
nextPatchNumber = patchRepository.findMaxPatchNumberForReleaseAndChannel(releaseId, cleanTargetChannel) + 1.
- Le serveur calcule le prochain numéro de patch disponible sur le canal cible pour cette release :
- Re-signature cryptographique par environnement (si l'isolation des clés est active) :
- Si
ota.crypto.per-environment-keys-enabled=true,cryptoSigner.signPatchHash(tenantId, appId, cleanTargetChannel, targetSha256Hash)signe le hash SHA-256 avec la clé RSA isolée du canal cible (prodvsnonprod). Sinon, la signature certifiée est conservée.
- Si
- Traçabilité et éviction du cache :
- Le nouveau patch est enregistré avec
approvedBy = "PROMOTED_FROM_<SOURCE_CHANNEL>:<promotedBy>", le cache L1/L2 de la release est immédiatement invalidé et un événement d'auditPATCH_PROMOTEDest inscrit avecsourcePatchId,sourceChannel,targetChanneletpatchNumber.
- Le nouveau patch est enregistré avec