Article original : How to Automate Flutter Testing and Builds with GitHub Actions for Android and iOS
GitHub Actions est un outil de CI/CD (Intégration Continue et Déploiement Continu) directement intégré à GitHub. Il permet aux développeurs de définir des workflows, qui sont des séquences d'étapes automatisées déclenchées par des événements tels que le push de code, l'ouverture de pull requests ou la création de releases.
Pour les développeurs Flutter, GitHub Actions est un moyen puissant d'automatiser les tests, les builds et le déploiement sur plusieurs plateformes.
Ce guide vous accompagnera dans la configuration de GitHub Actions pour un projet Flutter, couvrant tout, des prérequis aux explications détaillées du workflow.
Table des matières
Pourquoi utiliser GitHub Actions dans le développement Flutter ?
Les tests automatisés de GitHub Actions garantissent que toutes les modifications de code sont validées par des tests unitaires et d'intégration. L'intégration continue build automatiquement les applications Flutter pour confirmer que le nouveau code s'intègre correctement.
L'analyse de code et le linting peuvent s'exécuter automatiquement pour imposer un style et maintenir la qualité du code. Les releases automatisées simplifient le processus de packaging et de distribution des applications. Les workflows personnalisés peuvent être adaptés aux besoins spécifiques du projet. La collaboration est également améliorée car les développeurs peuvent voir les résultats du workflow directement dans les pull requests.
En introduisant GitHub Actions, les projets Flutter deviennent plus fiables, maintenables et efficaces.
Prérequis
Avant de configurer GitHub Actions pour votre projet Flutter, assurez-vous d'avoir :
Le SDK Flutter installé localement pour pouvoir créer et tester le projet avant de le pousser sur GitHub.
Git installé pour gérer le contrôle de version et pousser votre projet sur GitHub.
Un compte GitHub et un nouveau dépôt créé pour votre projet Flutter.
Une compréhension de base de la syntaxe YAML, car les workflows sont définis dans des fichiers
.yml.Un token d'accès personnel GitHub (PAT) pour publier les builds, qui sera stocké en tant que secret de dépôt.
Étape 1 : Créer un nouveau projet Flutter
Commencez par créer un nouveau projet Flutter et accédez-y :
flutter create gh_flutter
cd gh_flutter
Remplacez gh_flutter par le nom de projet de votre choix. Cela initialise un projet Flutter avec la structure et les dépendances par défaut.
Étape 2 : Pousser le projet sur GitHub
Initialisez Git dans votre projet et poussez-le vers GitHub :
git init
git add .
git commit -m "Initial commit"
git remote add origin <repository_url>
git push -u origin main
Remplacez <repository_url> par l'URL du dépôt que vous avez créé sur GitHub. Cela lie votre projet Flutter local à GitHub, permettant à GitHub Actions de s'exécuter sur votre dépôt.
Étape 3 : Créer un workflow GitHub Actions
À l'intérieur de votre projet, créez un fichier de configuration de workflow. Les workflows doivent être placés dans .github/workflows/. Créez un fichier nommé ci.yml :
name: CI
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
flutter_test:
name: Run Flutter Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
- uses: subosito/flutter-action@v2
with:
channel: 'stable'
- run: flutter pub get
- run: flutter --version
- run: flutter analyze
- run: flutter test
build_iOSApp:
name: Build Flutter App (iOS)
needs: [flutter_test]
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
- uses: subosito/flutter-action@v2
with:
flutter-version: '3.19.0'
dart-verion: '3.3.4'
channel: 'stable'
- run: flutter pub get
- run: flutter clean
- run: |
flutter build ios --no-codesign
cd build/ios/iphoneos
mkdir Payload
cd Payload
ln -s ../Runner.app
cd ..
zip -r app.ipa Payload
build_androidApk:
name: Build Flutter App (Android)
needs: [flutter_test]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
- uses: subosito/flutter-action@v2
with:
channel: 'stable'
- run: flutter pub get
- run: flutter clean
- run: flutter build apk --debug
- uses: ncipollo/release-action@v1
with:
artifacts: "build/app/outputs/apk/debug/*"
tag: v1.0.${{ github.run_number}}
token: ${{ secrets.TOKEN}}
Ce workflow est nommé CI et est destiné à l'Intégration Continue (exécution de tests et build d'applications automatiquement chaque fois que du code est poussé ou qu'une pull request est créée).
Déclencheurs
Dans GitHub Actions, les déclencheurs (triggers) définissent les événements qui provoquent l'exécution d'un workflow. Pour ce workflow, il s'exécute automatiquement lorsque certains événements se produisent dans le dépôt. Plus précisément, il écoute :
push: Chaque fois que du nouveau code est poussé vers la branchemain, le workflow démarre.pull_request: Chaque fois qu'une pull request est ouverte ou mise à jour vers la branchemain, le workflow démarre également.
Cela garantit que les mises à jour directes de la branche principale et les contributions via les pull requests sont validées et testées.
on:
push:
branches:
- main
pull_request:
branches:
- main
Ce code exécute le workflow lorsque :
Vous poussez des commits sur la branche
main.Une pull request est ouverte ou mise à jour ciblant
main.
Jobs
Il y a 3 jobs dans le workflow :
Job 1 : flutter_test exécute les tests unitaires et l'analyse.
jobs:
flutter_test:
runs-on: ubuntu-latest
Il utilise Ubuntu comme runner.
Voici les étapes qu'il suit :
Récupère le code :
- uses: actions/checkout@v3Télécharge votre dépôt dans le runner.
Configure Java (nécessaire pour les builds Flutter Android) :
- uses: actions/setup-java@v3 with: distribution: 'temurin' java-version: '17'Configure le SDK Flutter :
- uses: subosito/flutter-action@v2 with: channel: 'stable'Cela installe le canal stable de Flutter.
Exécute les commandes :
flutter pub getinstalle les dépendances.flutter --versionvérifie la version installée de Flutter.flutter analyzeanalyse le code Dart pour détecter les erreurs.flutter testexécute les tests unitaires/de widgets.
Si ce job échoue, les jobs suivants ne s'exécuteront pas.
Job 2 : build_iOSApp construit un fichier iOS .ipa.
build_iOSApp:
needs: [flutter_test]
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- uses: subosito/flutter-action@v2
with:
flutter-version: '3.22.0'
- name: Install CocoaPods dependencies
run: |
cd ios
pod install
- name: Build iOS App
run: flutter build ipa --release --no-codesign
Ceci ne s'exécute qu'après que flutter_test a réussi et utilise un runner macOS (nécessaire pour les builds iOS).
Après avoir installé les dépendances CocoaPods, le workflow exécute flutter build ipa --release --no-codesign. Cette commande shell indique à Flutter d'empaqueter votre application iOS dans un fichier .ipa à l'intérieur du répertoire de build du runner. Le drapeau --no-codesign permet de builder sans identifiants de signature, ce qui est pratique pour les pipelines CI.
Voici les étapes qu'il suit :
Récupère le dépôt + configure Java (comme précédemment).
Configure Flutter mais cette fois-ci en fixant les versions :
flutter-version: '3.19.0' dart-verion: '3.3.4' # faute de frappe : devrait être `dart-version` channel: 'stable'Exécute le build :
flutter pub getrécupère les packages.flutter cleannettoie les anciens builds.flutter build ios --no-codesignbuild l'application iOS sans signature.Après le build :
Va dans
build/ios/iphoneosCrée un dossier
Payload(nécessaire pour la structure IPA).Crée un lien symbolique de l'application
Runner.appgénérée versPayload.Compresse le dossier en
app.ipa.
Résultat : Un fichier .ipa non signé.
Job 3 : build_androidApk build un .apk Android de debug et le télécharge en tant qu'artefact de release.
build_androidApk:
needs: [flutter_test]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: subosito/flutter-action@v2
with:
flutter-version: '3.22.0'
- name: Build Android APK
run: flutter build apk --release
Ceci ne s'exécute qu'après la réussite des tests.
Pour Android, après avoir configuré l'environnement Flutter, le workflow appelle flutter build apk --release. Cette commande compile et empaquette l'application Android dans un fichier .apk prêt pour la distribution. Le fichier résultant est placé dans le répertoire build/app/outputs/flutter-apk du projet.
Voici les étapes qu'il suit :
Récupère le dépôt, configure Java et configure Flutter.
Exécute :
flutter pub getflutter cleanflutter build apk --debugcrée un APK de debug.
Télécharge l'APK à l'aide de
ncipollo/release-action@v1:artifacts: "build/app/outputs/apk/debug/*" tag: v1.0.${{ github.run_number }} token: ${{ secrets.TOKEN }}Télécharge tous les APK de debug en tant qu'artefacts de release.
Marque la release avec le tag
v1.0.<run_number>(ex:v1.0.5).Utilise un Token d'Accès Personnel GitHub (
TOKEN) stocké dans les secrets du dépôt.
Étape 4 : Générer et ajouter un token GitHub
Le job de build Android publie les APK à l'aide de release-action. Pour s'authentifier, vous devez fournir un token d'accès personnel GitHub. Pour ce faire, allez dans GitHub Settings → Developer settings → Personal access tokens.
Générez un nouveau token avec les permissions repo et copiez-le immédiatement. Ensuite, allez dans votre dépôt → Settings → Secrets → New repository secret. Ajoutez le token avec le nom TOKEN.
Désormais, le workflow peut utiliser ${{ secrets.TOKEN }} en toute sécurité.
Étape 5 : Comprendre le workflow
Ce workflow est déclenché lorsque du code est poussé vers la branche main ou lorsqu'une pull request est ouverte contre celle-ci. Analysons-le :
Job de test Flutter
- Environnement : S'exécute sur
ubuntu-latest.
Étapes :
actions/checkout@v3récupère le code source.actions/setup-java@v3installe Java, requis pour certains outils Flutter.subosito/flutter-action@v2installe Flutter sur le runner.flutter pub getinstalle les dépendances.flutter analyzevérifie les problèmes de code.flutter testexécute les cas de test.
Ce job garantit que votre code compile, passe le linting et n'a pas de tests échoués.
Job de build d'application iOS
Environnement : S'exécute sur
macos-latestcar les builds iOS nécessitent macOS.Dépendances : Ce job ne s'exécute que si
flutter_testréussit (needs: [flutter_test]).
Étapes : Configuration similaire à la précédente, mais après avoir nettoyé les anciens builds avec flutter clean, il exécute flutter build ios --no-codesign pour construire une application iOS sans nécessiter de certificat de signature. Les commandes shell empaquettent l'application dans un fichier .ipa.
Job de build d'APK Android
Environnement : S'exécute sur
ubuntu-latest.Dépendances : Dépend également de
flutter_test.
Étapes :
Installe Flutter.
Exécute
flutter cleanpuis construit l'APK Android.Utilise
ncipollo/release-action@v1pour télécharger l'APK en tant que release GitHub, taguée automatiquement avec une version telle quev1.0.<run_number>.
Étape 6 : Pousser et activer le workflow
Enregistrez votre fichier sous .github/workflows/ci.yml et poussez les modifications :
git add .
git commit -m "Add GitHub Actions workflow"
git push
Lorsque vous poussez vos modifications sur GitHub, le fichier de workflow est automatiquement détecté. Pour confirmer qu'il s'exécute, ouvrez votre dépôt sur GitHub et cliquez sur l'onglet Actions en haut de la page. Vous verrez une liste des exécutions de workflow, chacune liée au message de commit qui l'a déclenchée.
Cliquez sur l'exécution la plus récente pour voir les détails. À l'intérieur, vous trouverez des jobs séparés pour les builds Android et iOS. Chaque job affichera son statut en temps réel :
Un point jaune avec « In progress » indique que le job est toujours en cours d'exécution.
Une coche verte avec « Success » signifie que le job s'est terminé avec succès.
Une croix rouge avec « Failed » signifie que quelque chose s'est mal passé.
De cette façon, vous pouvez immédiatement savoir si vos builds Android et iOS ont réussi ou si l'un d'eux nécessite votre attention.






Notes finales
Avec cette configuration, vous avez maintenant :
Des tests automatisés chaque fois que vous poussez ou ouvrez une pull request.
Des builds iOS automatiques sur les runners macOS.
Des builds Android automatiques avec des APK publiés sur GitHub.
Cela garantit que chaque modification est testée et que les builds sont générés de manière cohérente sans étapes manuelles.
Pour plus de détails, consultez la documentation officielle de GitHub Actions : https://docs.github.com/en/actions.