Mettre en place une CI/CD

De Gandal

index.php?title=Catégorie:Github

Le CI/CD en développement

Le CI/CD, ou Intégration Continue/Livraison Continue, est une pratique logicielle qui vise à automatiser le processus de développement et de déploiement logiciel. Il s'agit d'une approche DevOps qui permet d'améliorer la qualité, la rapidité et la fiabilité du développement logiciel.

Les étapes

  1. Intégration Continue (CI) :
    • La CI consiste à intégrer fréquemment les modifications de code dans un référentiel partagé.
    • Les développeurs fusionnent régulièrement leur code dans une branche commune, déclenchant des processus automatisés qui vérifient la qualité du code.
  2. Tests Automatisés :
    • Les systèmes CI exécutent des tests automatisés pour s'assurer que les nouvelles modifications n'ont pas introduit de régressions.
    • Les tests peuvent inclure des tests unitaires, des tests d'intégration et d'autres formes de tests automatisés.
  3. Déploiement Continu (CD) :
    • L'Implémentation Continue (ou Déploiement Continu) étend la CI en automatisant la livraison du logiciel.
    • Le déploiement continu implique la mise en œuvre automatisée des modifications validées dans l'environnement de production.

Créer un fichier de workflow

Un fichier de workflow est le script qui sera exécuté par Github lors d'un évènement définis commpe un push sur la branch main ou la complétion d'un autre workflow.

C'est généralement un ou plusieurs fichies qui doivent être placés dans le dossier .github/workflows/ (par exemple .github/workflows/ci.yaml)

Exemple commenté d'un workflow d'intégration et de test continue Laravel

# Nom du workflow
name: Laravel CI

# Déclencheurs pour le workflow
on:
  push:
    branches: [ "main" ]   # Déclencher lorsqu'un push est effectué sur la branche principale
  pull_request:
    branches: [ "main" ]   # Déclencher lorsqu'une pull request est ouverte sur la branche principale

# Définition des jobs
jobs:
  laravel-tests:
    runs-on: ubuntu-latest   # Utiliser l'image Ubuntu la plus récente comme environnement d'exécution

    steps:
      - uses: shivammathur/setup-php@v2   # Utiliser l'action pour configurer PHP
        with:
          php-version: '8.1'   # Spécifier la version de PHP à utiliser
      - uses: actions/checkout@v2   # Utiliser l'action pour effectuer un checkout du code

      - name: Copy .env   # Étape pour copier le fichier .env s'il n'existe pas
        run: php -r "file_exists('.env') || copy('.env.example', '.env');"

      - name: Install Dependencies   # Étape pour installer les dépendances Composer
        run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist

      - name: Generate key   # Étape pour générer la clé d'application Laravel
        run: php artisan key:generate

      - name: Directory Permissions   # Étape pour définir les permissions sur les répertoires
        run: chmod -R 777 storage bootstrap/cache

      - name: Create Database   # Étape pour créer une base de données SQLite
        run: |
          mkdir -p database
          touch database/database.sqlite

      - name: Execute tests (Unit and Feature tests) via PHPUnit   # Étape pour exécuter les tests PHPUnit
        env:
          DB_CONNECTION: sqlite
          DB_DATABASE: database/database.sqlite   # Configurer la base de données pour les tests
        run: vendor/bin/phpunit

En incluant ce fichier dans notre système de fichiers, lors du push Github va effectuer les installations nécessaires pour lancer une version de test du projet et également exécuter tous les test unitaires et de features compris dans le projet.

Le déploiement demande un peu plus travail :

Exemple commenté d'un workflow de déploiement continue Laravel

# Nom du workflow
name: Laravel CD

# Déclencheur pour le workflow : déclenche lorsqu'une exécution du workflow "Laravel CI" est terminée
on:
  workflow_run:
    workflows: ["Laravel CI"]
    types:
      - completed

# Définition des jobs
jobs:
  deploy:
    runs-on: ubuntu-latest   # Utiliser l'image Ubuntu la plus récente comme environnement d'exécution

    environment:
      name: 'MyPlesk'   # Nom de l'environnement de déploiement

    steps:
      - name: Deploy to Server   # Étape pour déployer sur le serveur
        uses: appleboy/ssh-action@master   # Utiliser l'action SSH pour effectuer le déploiement
        with:
          host: ${{ secrets.SERVER_HOST }}   # Adresse IP ou nom d'hôte du serveur
          username: ${{ secrets.SERVER_USERNAME }}   # Nom d'utilisateur pour la connexion SSH
          key: ${{ secrets.SSH_PRIVATE_KEY }}   # Clé privée SSH pour l'authentification
          script: |
            cd /var/www/vhosts/abdoulaye-diallo.com/api.abdoulaye-diallo.com/Cv_back/   # Se déplacer vers le répertoire du projet
            git pull origin main   # Mettre à jour le code depuis la branche principale
            php artisan migrate   # Exécuter les migrations de base de données
            composer update   # Mettre à jour les dépendances Composer (si nécessaire)
            composer install   # Installer les dépendances Composer

Comme on peut le voir dans ce code, on doit se connecter en SSH au serveur de production afin de déployer les MAJ. Pour cela et pour des raisons de sécurités, on stock les informations dans les secrets de GitHub (voir https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions) . Ici en l'occurrence nous avons créés des secrets dans un environnement nommé MyPlesk sur GitHub.

Création des clés ssh

La connexion au serveur distant se fait via une clé ssh (d'où le secrets.SSH_PRIVATE_KEY à la ligne 25), pour cela nous allons ouvrir un terminal en local par exemple et lancer la commande de génération de clé ssh : ssh-keygen -t rsa -b 4096 -C "monmail@email.com".

Il faudra ensuite copier la clé privée dans le secret de Github ( secrets.SSH_PRIVATE_KEY) et ajouter la clé publique parmis les clés SSH autorisés du serveur distant (sur Plesk, aller dans l'abonnement concerné et cliquer sur SSH KEYS).

Il faut également renseigner le nom de l'utilisateur qui a accès au serveur.