Intro
Dans le développement logiciel moderne, l’intégration continue (CI) et le déploiement continu (CD) sont devenus incontournables pour garantir qualité et efficacité.
Dans cet article, je vais vous expliquer comment mettre en place, facilement et rapidement, un workflow CI/CD pour vos projets en tirant parti de GitHub Actions. Suivez le guide !
Qu’est-ce qu’un workflow CI/CD ?
Avant d'entrer dans les détails techniques, rappelons ce que représente un workflow CI/CD :
GitHub Actions permet de définir ces workflows sous forme de fichiers YAML qui décrivent les actions à effectuer en réponse à des événements comme un « push » ou une « pull request ».
Prêt à plonger ? Suivez les prochaines étapes pour créer votre propre pipeline CI/CD avec GitHub Actions !
Création du fichier de workflow
Créez un fichier YAML dans votre dépôt à l’emplacement suivant :
.github/workflows/ci-cd.yml
Nommage et déclencheurs d'événements
name: CI/CD Workflow
on:
push:
branches:
- main
pull_request:
branches:
- main
name: ce champ permet de définir le nom du workflow. C'est ce nom qui apparaîtra dans l'interface de GitHub Actions afin de l'identifier facilement.
on: cette section spécifie les événements qui déclencheront l'exécution du workflow.
Deux événements sont configurés ici :
- push: le workflow sera exécuté chaque fois qu'un changement est poussé vers la branche main.
- pull_request: le workflow sera également déclenché chaque fois qu'une pull request est ouverte, modifiée ou mise à jour sur la branche main.
Compilation d’un projet
C’est parti ! Ecrivons notre premier job qui permettra de compiler notre projet et d’exécuter les tests unitaires :
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Set up JDK
uses: actions/setup-java@v3
with:
java-version: '23'
- name: Build project
run: ./gradlew build
- name: Run tests
run: ./gradlew test
jobs: c’est dans cette section que l’on définit les différents jobs qui seront exécutés dans notre workflow. Un job est un ensemble d'étapes (steps) exécutées sur une machine virtuelle.
build: il s'agit du nom du job, que j’ai ici appelé build. Ce nom peut être personnalisé en fonction de ce que le job est censé faire.
runs-on: c’est ici que l’on spécifie l'environnement d'exécution sur lequel ce job sera exécuté. Il est possible de choisir entre des runners hébergés (fournis par GitHub) ou des runners auto-hébergés (configurés par vous ou votre organisation).
J’ai choisi ubuntu-latest, qui désigne un environnement Ubuntu (machine virtuelle) avec la dernière version disponible, pré-configuré avec des outils communs.
Description des étapes
Chaque job peut être composé de plusieurs étapes, qui sont exécutées dans un ordre séquentiel sur l'environnement spécifié.
La section steps définit la liste des étapes que le job doit suivre. Chaque étape peut être soit une action GitHub préconfigurée, soit une commande personnalisée, et doit toujours être accompagnée d'un nom.
- L’étape “Checkout repository” permet de récupérer le code source du dépôt. L'action actions/checkout est une action GitHub officielle qui clone le dépôt dans l'environnement d'exécution du job. La mention @v3 indique que la version 3 de cette action est utilisée.
- L’étape “Set up JDK” configure l’environnement pour utiliser une version spécifique du JDK. L’action actions/setup-java est une action préconfigurée par GitHub permettant d’installer et de configurer le JDK dans l’environnement d’exécution.
Le champ with permet de spécifier des paramètres à l’action, et dans ce cas, java-version: '17' indique la version du JDK à utiliser.
- L’étape “Build project” est responsable de la compilation du projet et de la génération de ses artefacts. La commande personnalisée run: ./gradlew build exécute Gradle pour compiler le projet, générant ainsi les artefacts nécessaires pour les étapes suivantes ou pour le déploiement.
- Enfin, l’étape “Run tests” nous permettra de lancer les les tests définis dans le projet, tels que les tests unitaires ou d'intégration, via la commande personnalisée run: ./gradlew test. Pour aller plus loin dans l'analyse de la qualité du code, vous pouvez également intégrer des outils comme SonarQube ou SonarCloud dans votre workflow. Ces outils permettent d’effectuer une analyse statique du code afin de détecter des bugs, des vulnérabilités et des mauvaises pratiques. Il suffira d'ajouter une étape dédiée pour envoyer les résultats des tests et des analyses de couverture à Sonar.
Déploiement d’un projet
Écrivons maintenant un second job qui se chargera de déployer notre application sur un serveur distant :
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Deploy to server
uses: appleboy/ssh-action@v0.1.5
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
password: ${{ secrets.SERVER_PASS }}
script: |
cd /var/www/myapp
git pull origin main
./restart.sh
Pour déployer notre application, il est essentiel qu'elle soit préalablement compilée et testée avec succès. Pour cela, nous utilisons le mot-clé needs, qui permet d'exécuter notre nouveau job deploy uniquement si le job build s'est terminé avec succès.
En cas d'échec de ce dernier, le job deploy ne sera pas lancé.
Description des étapes
- L’étape “Deploy to server” nous permet d’exécuter des commandes via SSH sur un serveur distant grâce à l’action appleboy/ssh-action.
La section with contient les paramètres nécessaires pour établir la connexion SSH et exécuter le script de déploiement.
Voici les éléments fournis :
- host: ${{ secrets.SERVER_HOST }} : l'adresse du serveur distant. Cette valeur est stockée dans les secrets GitHub pour la sécurité.
- username: ${{ secrets.SERVER_USER }} : le nom d'utilisateur SSH pour se connecter au serveur. Il est également stocké dans les secrets pour garantir la sécurité.
- password: ${{ secrets.SERVER_PASS }} : le mot de passe pour l'utilisateur SSH. Également stocké dans les secrets GitHub pour la sécurité.
La section script contient les commandes à exécuter sur le serveur distant afin de récupérer les dernières modifications du code depuis le dépôt Git. Ici, le script est supposé redémarrer l'application, appliquant ainsi les dernières modifications du code.
Conclusion
Et voilà ! Vous disposez désormais de toutes les informations nécessaires pour configurer rapidement et efficacement un workflow CI/CD avec GitHub Actions.
Mais ce n’est qu’un début : les possibilités sont nombreuses !
Par exemple, vous pouvez créer et déployer des images Docker pour effectuer des tests d’intégration avancés ou encore publier ces images dans un Google Artifact Registry. Cela ouvre la voie à des déploiements optimisés sur vos environnements de production et à une gestion simplifiée des releases.
Il est aussi possible d'exécuter des scripts Python pour générer automatiquement de la documentation, ainsi que de publier une release note de manière automatisée avec des outils comme release-please.
GitHub Actions offre une interface intuitive pour le débogage, avec des logs clairs et détaillés, facilitant ainsi l’identification et la résolution des éventuels problèmes dans vos workflows. N’hésitez pas à les consulter régulièrement !