Intégration continue (CI/CD)
L'automatisation des déploiements OTA au sein d'une chaîne d'intégration et de livraison continue (CI/CD) repose sur le mode headless de la CLI tk-ota-push.
En environnement CI/CD, l'authentification interactive par navigateur (PKCE) est remplacée par des variables d'environnement sécurisées, et le flag --json permet d'extraire les métadonnées (identifiant du patch, URL de téléchargement, statut) pour les étapes ultérieures (tests automatisés, notifications Slack/Teams).
1. Variables d'environnement requises
Pour autoriser l'agent CI/CD à communiquer avec le serveur Serveur TkushPatch, configurez les secrets suivants dans votre orchestrateur (GitHub Secrets, GitLab CI/CD Variables) :
| Variable | Exemple / Format | Description |
|---|---|---|
OTA_SERVER_URL | https://ota.entreprise.com | URL racine du serveur OTA Serveur TkushPatch On-Premise |
OTA_TENANT_ID | banque-digitale | Identifiant du Tenant (organisation) |
OTA_API_KEY | ota_sec_live_9f8a... | Jeton de service CI/CD avec rôle ROLE_RELEASE_ENGINEER ou ROLE_TENANT_ADMIN |
Lorsqu'OTA_API_KEY est présente dans l'environnement du runner, tk-ota-push l'utilise immédiatement en en-tête Authorization: Bearer <token>, sans tenter d'ouvrir de session locale ni de lancer de navigateur.
2. Template GitHub Actions
Le workflow ci-dessous illustre une chaîne complète comprenant la publication d'un binaire de référence (release) lors de la création d'un tag Git, et le déploiement d'un patch d'urgence (patch) sur la branche hotfix/*.
name: TkushPatch OTA Deployment Pipeline
on:
push:
tags:
- 'v*.*.*'
branches:
- 'hotfix/**'
workflow_dispatch:
inputs:
action:
description: 'Action OTA à exécuter'
required: true
default: 'patch'
type: choice
options:
- patch
- release
- promote
rollout:
description: 'Pourcentage de déploiement (0-100)'
required: false
default: '100'
channel:
description: 'Canal de destination'
required: false
default: 'stable'
jobs:
ota-pipeline:
runs-on: macos-14 # Requis pour la compilation iOS et Android unifiée
env:
OTA_SERVER_URL: ${{ secrets.OTA_SERVER_URL }}
OTA_TENANT_ID: ${{ secrets.OTA_TENANT_ID }}
OTA_API_KEY: ${{ secrets.OTA_API_KEY }}
steps:
- name: Récupération du code source
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Configuration de Java 17
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
- name: Configuration de Dart & Flutter
uses: subosito/flutter-action@v2
with:
channel: 'stable'
cache: true
- name: Installation de la toolchain Shorebird
run: |
curl --proto '=https' --tlsv1.2 https://raw.githubusercontent.com/shorebirdtech/install/main/install.sh -sSf | bash
echo "$HOME/.shorebird/bin" >> $GITHUB_PATH
- name: Détection de la toolchain Shorebird
run: |
shorebird --version
ls -la "$HOME/.shorebird/bin/cache/flutter"
- name: Activation globale de la CLI tk-ota-push
run: |
dart pub global activate --source path ./tkushpatch_releases/tk_ota_push
echo "$HOME/.pub-cache/bin" >> $GITHUB_PATH
- name: Installation des dépendances Flutter
run: flutter pub get
# SCÉNARIO 1 : VERROUILLAGE D'UNE RELEASE STORE (Tag Git)
- name: Verrouiller la Release Android & iOS (Tag)
if: startsWith(github.ref, 'refs/tags/v') || github.event.inputs.action == 'release'
run: |
tk-ota-push release -p android \
--artifact aab \
--obfuscate \
--split-debug-info=build/symbols \
--json > release_receipt.json
cat release_receipt.json
# SCÉNARIO 2 : DÉPLOIEMENT D'UN PATCH OTA (Hotfix ou Manuel)
- name: Publier le Patch OTA (Android)
if: startsWith(github.ref, 'refs/heads/hotfix/') || github.event.inputs.action == 'patch'
id: deploy_patch
run: |
ROLLOUT_PERCENT=${{ github.event.inputs.rollout || '100' }}
CHANNEL_NAME=${{ github.event.inputs.channel || 'stable' }}
# Exécution de tk-ota-push avec sortie JSON structurée
tk-ota-push patch -p android \
-c "$CHANNEL_NAME" \
--rollout "$ROLLOUT_PERCENT" \
-m "Hotfix ${{ github.ref_name }} : ${{ github.event.head_commit.message }}" \
--json > patch_receipt.json
cat patch_receipt.json
PATCH_ID=$(jq -r '.patch_id // empty' patch_receipt.json)
echo "patch_id=$PATCH_ID" >> $GITHUB_OUTPUT
- name: Archivage des symboles de débogage
if: always()
uses: actions/upload-artifact@v4
with:
name: ota-debug-symbols
path: build/symbols/
if-no-files-found: ignore
3. Template GitLab CI
Dans GitLab CI, vous pouvez structurer le pipeline en jobs distincts avec gestion fine des caches :
stages:
- prepare
- release
- patch
- promote
variables:
OTA_SERVER_URL: $OTA_SERVER_URL
OTA_TENANT_ID: $OTA_TENANT_ID
OTA_API_KEY: $OTA_API_KEY
default:
tags:
- saas-macos-medium-m1 # Runner macOS pour iOS et Android
before_script:
- export PATH="$HOME/.shorebird/bin:$HOME/.pub-cache/bin:$PATH"
- if ! command -v shorebird &> /dev/null; then
curl --proto '=https' --tlsv1.2 https://raw.githubusercontent.com/shorebirdtech/install/main/install.sh -sSf | bash ;
fi
- dart pub global activate --source path ./tkushpatch_releases/tk_ota_push
- flutter pub get
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- .dart_tool/
- build/
# Job de verrouillage d'une Release lors d'un tag de version
release_store:
stage: release
only:
- tags
script:
- tk-ota-push release -p android --artifact aab --json > release_output.json
artifacts:
name: "release-symbols-$CI_COMMIT_TAG"
paths:
- build/ota_symbols/
- release_output.json
expire_in: 6 mos
# Job de déploiement automatique d'un patch OTA sur branche de hotfix
patch_ota_hotfix:
stage: patch
only:
- /^hotfix\/.*$/
script:
- tk-ota-push patch -p android --rollout 20 -c staging --staged -m "$CI_COMMIT_MESSAGE" --json > patch_output.json
- cat patch_output.json
artifacts:
reports:
dotenv: patch.env
paths:
- patch_output.json
# Job manuel de promotion staging vers production (Règle des 4 yeux)
promote_to_stable:
stage: promote
when: manual
only:
- /^hotfix\/.*$/
script:
- PATCH_UUID=$(jq -r '.patch_id' patch_output.json)
- tk-ota-push promote --patch-id "$PATCH_UUID" --to-channel stable --json
4. Bonnes pratiques de sécurité en CI/CD
- Jeton d'API dédié par environnement : Ne partagez pas la clé
OTA_API_KEYde production avec des runners exécutant des branches de fonctionnalités de contributeurs externes. - Utilisation du mode
--staged: En entreprise bancaire ou de santé, configurez le pipeline pour toujours publier avec--staged. Un responsable QA ou RSSI doit ensuite valider manuellement la promotion vers le canalstablevia la Console Web outk-ota-push promote. - Archivage systématique des
.symbols: Conservez toujours le dossierbuild/ota_symbols/généré par--obfuscatedans les artefacts de votre CI. En cas de crash utilisateur remonté par Crashlytics ou Sentry, ces symboles seront indispensables pour reconstituer la stacktrace dé-obfusquée.