Nouveau : Datasets open source gratuits disponibles !Decouvrir →
💙
Intermediaire 25 min Flutter

CI/CD pour Flutter avec GitHub Actions

CI/CD pour Flutter avec GitHub Actions

Pourquoi CI/CD pour Flutter avec GitHub Actions ?

Contexte réal : pourquoi un dev a besoin de ca au quotidien

Le Continuous Integration (CI) et le Continuous Deployment (CD) sont essentiels dans le développement moderne. Ils permettent de tester, construire et déployer votre application en continu, réduisant ainsi le temps d'intégration et la probabilité d'erreurs. Avec Flutter, qui utilise des widgets réactifs, un bon processus CI/CD peut aider à détecter les problèmes tôt dans le cycle de développement.

Un cas d'utilisation concret en 2-3 phrases

En supposant que vous travailliez sur une application de gestion des tâches pour une entreprise. A chaque modification du code, vous voudriez avoir automatiquement l'application testée et déployée dans un environnement de pré-production pour validation avant le déploiement final.

Prerequis

  • Connaissances nécessaires :

    • Connaissance de base de Flutter
    • Familiarité avec les pipelines CI/CD
    • Compréhension des versions Git et GitHub Actions
    • Connaissances en gestion de projet
  • Outils à installer (versions) :

    • Node.js v14.x ou supérieur
    • Flutter SDK (v2.5.0 ou supérieur)
    • Android Studio avec la version du SDK appropriée
    • Git

Concepts fondamentaux

Workflow GitHub Actions

Un workflow est une série d'étapes définies pour exécuter des tâches. Voici un exemple de workflow pour Flutter :

## .github/workflows/flutter.yml
name: Flutter CI/CD

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v2

    - name: Set up Flutter
      uses: subosito/flutter-action@v1
      with:
        channel: 'stable'

    - name: Install dependencies
      run: flutter pub get

    - name: Run tests
      run: flutter test

Actions GitHub Actions

Les actions sont des unités de travail individuelles qui peuvent être exécutées dans un workflow. Par exemple, actions/checkout permet de récupérer le code à partir du référentiel.

- name: Checkout code
  uses: actions/checkout@v2

Triggers GitHub Actions

Les triggers définissent quand un workflow doit être exécuté. Par exemple, le trigger suivant exécute le workflow chaque fois qu'un push est effectué sur la branche main ou que une pull request est soumise.

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

Mise en pratique : projet fil rouge

Nous allons construire un simple gestionnaire de tâches Flutter. Ce projet comprendra les fonctionnalités suivantes :

  1. Afficher la liste des tâches
  2. Ajouter une nouvelle tâche
  3. Marquer une tâche comme terminée

Étape 1 : Création du projet

Commencez par créer un nouveau projet Flutter :

flutter create task_manager
cd task_manager

Étape 2 : Structure des fichiers

Voici la structure de base du projet :

task_manager/
├── lib/
│   ├── main.dart
│   ├── screens/
│   │   └── tasks_screen.dart
│   ├── models/
│   │   └── task.dart
│   ├── widgets/
│   │   └── task_item.dart
├── .gitignore
├── pubspec.yaml

Étape 3 : Installation des dépendances

Ajoutez les dépendances nécessaires dans pubspec.yaml :

dependencies:
  flutter:
    sdk: flutter
  provider: ^6.0.1

dev_dependencies:
  flutter_test:
    sdk: flutter

Étape 4 : Création du modèle de tâche

Créez un fichier task.dart dans le dossier models/ :

// lib/models/task.dart
class Task {
  final String id;
  final String title;
  bool isCompleted;

  Task({required this.id, required this.title, this.isCompleted = false});
}

Étape 5 : Création de la liste des tâches

Créez un fichier tasks_screen.dart dans le dossier screens/ :

// lib/screens/tasks_screen.dart
import 'package:flutter/material.dart';
import '../models/task.dart';
import '../widgets/task_item.dart';

class TasksScreen extends StatefulWidget {
  @override
  _TasksScreenState createState() => _TasksScreenState();
}

class _TasksScreenState extends State<TasksScreen> {
  List<Task> tasks = [];

  void addTask(String title) {
    setState(() {
      tasks.add(Task(id: DateTime.now().toString(), title: title));
    });
  }

  void toggleTask(int index) {
    setState(() {
      tasks[index].isCompleted = !tasks[index].isCompleted;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Gestionnaire de Tâches'),
      ),
      body: ListView.builder(
        itemCount: tasks.length,
        itemBuilder: (context, index) {
          return TaskItem(task: tasks[index], onToggle: toggleTask);
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          final title = await showDialog<String>(
            context: context,
            builder: (BuildContext context) {
              String? newTitle;
              return AlertDialog(
                title: const Text('Ajouter une tâche'),
                content: TextField(
                  onChanged: (value) {
                    newTitle = value;
                  },
                ),
                actions: <Widget>[
                  TextButton(
                    onPressed: () => Navigator.of(context).pop(),
                    child: const Text('Annuler'),
                  ),
                  TextButton(
                    onPressed: () {
                      if (newTitle != null && newTitle!.isNotEmpty) {
                        addTask(newTitle!);
                        Navigator.of(context).pop();
                      }
                    },
                    child: const Text('Ajouter'),
                  ),
                ],
              );
            },
          );
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

Étape 6 : Création de l'item de tâche

Créez un fichier task_item.dart dans le dossier widgets/ :

// lib/widgets/task_item.dart
import 'package:flutter/material.dart';
import '../models/task.dart';

class TaskItem extends StatelessWidget {
  final Task task;
  final Function(int) onToggle;

  TaskItem({required this.task, required this.onToggle});

  @override
  Widget build(BuildContext context) {
    return CheckboxListTile(
      title: Text(task.title),
      value: task.isCompleted,
      onChanged: (value) {
        onToggle(tasks.indexOf(task));
      },
    );
  }
}

Étape 7 : Mise à jour de main.dart

Ajoutez le code pour afficher la liste des tâches :

// lib/main.dart
import 'package:flutter/material.dart';
import 'screens/tasks_screen.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Task Manager',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: TasksScreen(),
    );
  }
}

Étape 8 : Ajout du workflow GitHub Actions

Ajoutez le fichier flutter.yml dans le dossier .github/workflows/ :

## .github/workflows/flutter.yml
name: Flutter CI/CD

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v2

    - name: Set up Flutter
      uses: subosito/flutter-action@v1
      with:
        channel: 'stable'

    - name: Install dependencies
      run: flutter pub get

    - name: Run tests
      run: flutter test

Étape 9 : Commit et push du code

Commitez et poussez le code sur GitHub :

git add .
git commit -m "Initial commit of task manager"
git push origin main

Erreurs fréquentes et debugging

  1. Erreur : Target file doesn't exist.

    # ❌ Mauvais
    flutter build apk --target=lib/main.dart
    
    # ✅ Correct
    flutter build apk
    
  2. Erreur : Failed to compile project 'task_manager' in debug mode.

    # ❌ Mauvais
    flutter run
    
    # ✅ Correct
    flutter clean
    flutter pub get
    flutter run
    
  3. Erreur : Test failed. Either the test failed, or there was a problem running the test.

    # ❌ Mauvais
    flutter test
    
    # ✅ Correct
    flutter test --update-golden
    

Pour aller plus loin

  1. Intégration avec Firebase : Ajoutez Firebase pour la gestion des utilisateurs et la base de données.
  2. Déploiement sur Google Play Store : Configurez le déploiement sur le Google Play Store en utilisant Fastlane ou Gradle.
  3. Tests UI automatisés : Utilisez Flutter Driver pour écrire des tests UI automatisés.

Défi pratique

Développez un gestionnaire de blog simple avec les fonctionnalités suivantes :

  1. Afficher la liste des articles
  2. Ajouter un nouvel article
  3. Modifier un article existant
  4. Supprimer un article

En utilisant ces concepts, vous pouvez approfondir votre compréhension du développement Flutter et des pipelines CI/CD.

Besoin d'aide sur Flutter ?

Besoin d'aide sur un projet technique ? Decrivez-le pour des conseils personnalises.

Recevoir des conseils

Questions frequentes

Qu'est-ce que CI/CD pour Flutter ?
CI/CD pour Flutter signifie Continuous Integration / Continuous Deployment. Cela permet d'automatiser le processus de construction et du déploiement de votre application Flutter, ce qui vous permet d'être sûr que tout fonctionne correctement avant la publication.
Comment configurer GitHub Actions pour un projet Flutter ?
Pour configurer GitHub Actions sur un projet Flutter, vous devez créer un fichier .github/workflows/flutter.yml dans votre dépôt. Dans ce fichier, vous définissez les étapes de construction et de déploiement que vous voulez automatiser.
Quelles sont les avantages d'utiliser GitHub Actions pour Flutter ?
GitHub Actions offre une variété d'avantages pour les développeurs Flutter, notamment un environnement sûr et fiable pour le développement continu, des rapports en temps réel sur la qualité du code, et la possibilité de déployer automatiquement votre application à travers différents canaux.

Pages liees

Chaque semaine, le meilleur de la tech francaise

Tendances, salaires, outils et opportunites — directement dans votre boite mail.

Gratuit. Desabonnement en un clic. Pas de spam.