Dans le monde rapide du développement web, l’intégration et le déploiement continus (CI/CD) sont devenus des pratiques indispensables pour fournir efficacement des logiciels de haute qualité. L’intégration et le déploiement continus permettent aux développeurs d’automatiser le processus de construction, de test et de déploiement des modifications du code, réduisant ainsi le risque d’erreur humaine et permettant des itérations plus rapides.

Cet article explique l’importance de la CI/CD, comment créer un pipeline de CI et comment mettre en place un déploiement continu dans votre pipeline de CI avec l’API Kinsta de manière programmatique – le tout avec les Actions GitHub dans votre dépôt GitHub.

Pourquoi utiliser CI/CD ?

La plateforme d’hébergement d’applications de Kinsta a toujours offert une option de déploiement automatique, déclenchée chaque fois qu’une modification est apportée à une branche spécifique de votre dépôt Git hébergé. Cependant, cela peut ne pas être idéal pour les grands projets avec plusieurs membres de l’équipe. De nombreux développeurs ont tendance à éviter d’activer le déploiement automatique pour diverses raisons.

L’une d’entre elles est que, dans un environnement collaboratif où plusieurs développeurs travaillent sur le même projet, les déploiements automatiques déclenchés par la modification d’un développeur dans le dépôt peuvent entraîner une instabilité et des problèmes imprévus. En l’absence de tests et de validation appropriés, même une petite modification du code peut perturber le site en production, entraînant potentiellement des temps d’arrêt et des expériences négatives pour les utilisateurs.

C’est là qu’un pipeline CI/CD entre en jeu. En créant un flux de travail CI/CD soigneusement orchestré, les développeurs peuvent s’assurer que les modifications du code sont testées et validées avant d’être déployées sur le site réel. Il existe de nombreux outils disponibles pour mettre en œuvre le CI/CD dans le développement de logiciels, nous utiliserons GitHub Actions pour ce tutoriel.

Qu’est-ce que GitHub Actions ?

GitHub Actions est un puissant outil d’automatisation fourni par GitHub. Il offre aux développeurs la possibilité d’automatiser diverses tâches, processus et flux de travail au sein de leurs projets de développement logiciel. Il s’intègre aux dépôts GitHub, ce qui le rend facile à utiliser.

Grâce aux actions GitHub et à l’API Kinsta, vous pouvez définir des flux de travail personnalisés qui répondent aux exigences de votre projet. Vous pouvez mettre en place un pipeline CI qui teste votre application et déclenche le déploiement sur Kinsta.

Démarrer avec GitHub Actions

Les Actions GitHub fonctionnent sur le concept de flux de travail, qui sont des ensembles de tâches automatisées déclenchées par des évènements spécifiques ou programmées à intervalles réguliers. Ces évènements peuvent être des poussées de code, des demandes d’extraction, la création d’une question, etc. Lorsque l’un de ces événements se produit, GitHub Actions lance automatiquement un flux de travail associé, en exécutant une série d’étapes prédéfinies.

Chaque étape du flux de travail représente une action particulière, telle que la construction du code, l’exécution de tests, le déploiement ou l’envoi de notifications. Créons un flux de travail avec trois tâches :

  1. Vérifier la syntaxe avec ESLint
  2. Exécuter les tests
  3. Redéployer votre application

Étape 1 : Configurer votre dépôt GitHub

Pour commencer à utiliser les Actions GitHub, vous avez besoin d’un dépôt GitHub.

Ici, nous utilisons ce dépôt GitHub, développé pour le tutoriel Comment construire et déployer une application clone de ChatGPT avec React et OpenAI API.

N’hésitez pas à utiliser le dépôt vous-même en naviguant jusqu’à lui sur GitHub et en sélectionnant : Utiliser ce modèle > Créer un nouveau dépôt.

Dans cette application React, des tests unitaires sont créés pour tester chaque composant. ESLint est également utilisé pour s’assurer que la syntaxe et le formatage du code sont parfaits. Le pipeline CI bloquera un déploiement si une demande d’extraction ou un code fusionné poussé vers le dépôt échoue les tests du flux de travail.

Étape 2 : Créer un fichier de flux de travail

Définissez votre flux de travail en créant un fichier YAML dans le répertoire .github/workflows de votre dépôt. Ce répertoire doit se trouver à la racine de votre référentiel. La convention de nommage pour les fichiers de flux de travail est nom-du-flux-de-travail.yml.

  1. Dans votre dépôt, créez un répertoire .github.
  2. Dans le répertoire .github, créez un nouveau répertoire appelé workflows.
  3. Dans le répertoire workflows, créez un nouveau fichier avec un nom comme build-test-deploy.yml.

Étape 3 : Écrire le flux de travail CI/CD

Maintenant que vous avez créé votre fichier de flux de travail, définissez un flux de travail avec les étapes nécessaires pour vérifier la syntaxe avec ESLint, exécuter les tests et déployer l’application.

Créer un événement CI

Lors de la création d’un pipeline CI, la première étape consiste à donner un nom au flux de travail, puis à définir l’événement qui déclenchera le flux de travail. Pour cet exemple, les deux événements sont une pull request et un push vers la branche principale.

name: Build, Test, and Deploy

on:
  push:
    branches: "main"
  pull_request:
    branches: "main"

Si vous souhaitez programmer des tâches périodiques (CRON jobs) pour des tâches spécifiques, vous pouvez les ajouter au flux de travail. Par exemple, vous pourriez vouloir exécuter certaines tâches telles que des sauvegardes de bases de données, des nettoyages de données ou d’autres tâches de maintenance périodiques.

Voici un exemple de la manière dont vous pouvez ajouter un travail CRON au flux de travail :

on:
  # Existing event triggers for push and pull_request

  # Add a schedule for CRON jobs
  schedule:
    - cron: "0 0 * * *"

L’exemple ci-dessus déclenchera le flux de travail tous les jours à minuit (heure UTC) puisque le programme cron est défini sur 0 0 * * *. Vous pouvez personnaliser le programme cron pour répondre à vos besoins spécifiques.

Supposons que vous souhaitiez programmer le flux de travail CI/CD pour qu’il s’exécute tous les lundis à 8 heures. Nous pouvons configurer une tâche CRON à l’aide de l’évènement schedule:

name: Build, Test, and Deploy

on:
  push:
    branches: "main"
  pull_request:
    branches: "main"

  # Schedule the workflow to run every Monday at 8 a.m. (UTC time)
  schedule:
    - cron: "0 8 * * 1"

jobs:
 # Add jobs

La syntaxe de planification utilisée dans l’évènement schedule pour les flux de travail GitHub Actions est basée sur la syntaxe UNIX cron. Elle vous permet de définir des heures ou des intervalles spécifiques pour l’exécution automatique de votre flux de travail. La syntaxe se compose de cinq champs qui représentent différents aspects de la planification. Chaque champ est séparé par un espace. Le format général de la syntaxe de planification est le suivant :

* * * * *
┬ ┬ ┬ ┬ ┬
│ │ │ │ │
│ │ │ │ └─ Day of the week (0 - 7) (Sunday to Saturday, where both 0 and 7 represent Sunday)
│ │ │ └─── Month (1 - 12)
│ │ └───── Day of the month (1 - 31)
│ └─────── Hour (0 - 23)
└───────── Minute (0 - 59)

Décomposons maintenant chaque champ :

  • Minute (0 – 59) : La minute à laquelle la tâche cron se déclenchera. Par exemple, 15 signifie que le flux de travail se déclenchera à la 15ème minute de l’heure.
  • Hour (0 – 23) : L’heure à laquelle la tâche cron se déclenchera. Par exemple, 8 signifie que le flux de travail se déclenchera à 8 heures du matin.
  • Day of the month (1 – 31) : Le jour du mois où la tâche cron se déclenchera. Par exemple, 1 signifie que le flux de travail se déclenchera le 1er jour du mois.
  • Month (1 – 12) : Le mois au cours duquel la tâche cron se déclenchera. Par exemple, 6 signifie que le flux de travail se déclenchera en juin.
  • Day of the week (0 – 7) : Le jour de la semaine où la tâche cron se déclenchera. Ici, 0 et 7 représentent tous deux le dimanche, tandis que 1 représente le lundi, et ainsi de suite. Par exemple, 4 signifie que le flux de travail se déclenchera le jeudi.

Caractères spéciaux :

  • * (astérisque) : Correspond à n’importe quelle valeur de ce champ. Par exemple, * dans le champ minute signifie que le flux de travail se déclenchera toutes les minutes.
  • */n (barre oblique) : Spécifie un intervalle. Par exemple, */5 dans le champ des minutes signifie que le flux de travail se déclenchera toutes les 5 minutes.
  • , (virgule) : Spécifie plusieurs valeurs spécifiques. Par exemple, 1,15,30 dans le champ des minutes signifie que le flux de travail se déclenchera aux 1ère, 15ème et 30ème minutes de l’heure.
  • - (trait d’union) : Spécifie une plage de valeurs. Par exemple, 1-5 dans le champ du jour de la semaine signifie que le flux de travail se déclenchera du lundi au vendredi (1 à 5).
  • ? (point d’interrogation) : Utilisé pour ne pas spécifier de valeur particulière. Il est généralement utilisé dans le champ du jour de la semaine lorsque le jour du mois est spécifié. Par exemple, ? dans le champ du jour de la semaine et 15 dans le champ du jour du mois signifie que le flux de travail se déclenchera le 15e jour du mois, quel que soit le jour de la semaine.

Créer une tâche CI pour vérifier la syntaxe avec ESLint

Pour mettre en place le processus de CI, nous allons créer les travaux ou tâches nécessaires. Chaque tâche doit avoir un nom clair et compréhensible. Appelons le premier job eslint puisqu’il s’agit de vérifier la syntaxe du code à l’aide d’ESLint.

En outre, nous pouvons fournir une description lisible par l’homme, bien que cette partie soit facultative. Ensuite, nous spécifions que le job doit s’exécuter sur un environnement Ubuntu et utiliser une stratégie matricielle pour tester le code par rapport à deux versions de Node.js: 18.x et 20.x.

jobs:
  eslint:
    name: Check Syntax with ESLint
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [18.x, 20.x]

Ensuite, définissez les étapes que la tâche « ESLint » exécutera. Ces étapes comprennent l’extraction du code, la configuration de la version Node.js spécifiée pour exécuter ESLint, la mise en cache des paquets npm, l’installation des dépendances du projet et, enfin, l’exécution d’ESLint pour vérifier la syntaxe du code.

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

      - name: Use Node.js ${{ matrix.node-version }} to Check Lint
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'

      - name: Install Dependencies
        run: npm ci

      - name: Run ESLint
        run: npm run lint

Dans le flux de travail ci-dessus, chaque étape est décrite par un nom afin de faciliter l’identification de la source des erreurs ou des bogues lors de l’inspection du flux de travail à partir des actions GitHub. Notamment, dans la troisième étape, nous utilisons la commande npm ci pour installer les dépendances, ce qui est préférable à npm install car elle effectue une installation propre. En outre, la dernière étape, qui consiste à exécuter ESLint à l’aide de npm run lint, suppose que vous avez configuré cette commande dans votre fichier package.json.

Vous trouverez ci-dessous le travail complet de vérification de la syntaxe du code avec ESLint :

jobs:
  eslint:
    name: Check Syntax with ESLint
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [18.x, 20.x]

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

      - name: Use Node.js ${{ matrix.node-version }} to Check Lint
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'

      - name: Install Dependencies
        run: npm ci

      - name: Run ESLint
        run: npm run lint

Créer une tâche CI pour exécuter les tests

Pour ajouter la tâche CI permettant d’exécuter les tests, commencez par définir la tâche et donnez-lui un nom descriptif, par exemple tests. Nous préciserons également que cette tâche dépend de la tâche eslint, ce qui signifie que la tâche eslint s’exécutera d’abord avant la tâche tests. Cette dépendance permet de s’assurer que le code n’est pas entaché d’erreurs de syntaxe avant l’exécution des tests.

  tests:
    name: Run Tests
    needs: eslint
    runs-on: ubuntu-latest

Définissez ensuite les étapes de la tâche tests. Comme pour la tâche précédente, nous allons vérifier le code, configurer la version de Node.js 18.x pour exécuter les tests, installer les dépendances du projet à l’aide de npm ci, puis exécuter les tests à l’aide de la commande npm run test.

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

      - name: Use Node.js 18.x to run Test
        uses: actions/setup-node@v3
        with:
          node-version: 18.x
          cache: 'npm'

      - name: Install Dependencies
        run: npm ci

      - name: Run Tests
        run: npm run test

Créer une tâche CI pour déployer avec l’API Kinsta

Pour créer la tâche CI de déploiement vers Kinsta à l’aide de l’API Kinsta, nous allons définir la tâche et la nommer deploy. Cette tâche aura des dépendances sur les jobs eslint et tests, garantissant que le déploiement n’est exécuté qu’après que le code a été vérifié pour les erreurs de syntaxe et qu’il a passé les tests. Nous allons configurer la tâche pour qu’elle s’exécute dans un environnement Ubuntu en utilisant la dernière version disponible.

  deploy:
    name: Re-Deploy Application
    needs: [eslint, tests]
    runs-on: ubuntu-latest

Ensuite, définissez les étapes. Dans ce cas, vous exécuterez une commande cURL pour interagir avec l’API Kinsta de manière programmatique et déclencher un redéploiement. Commençons par comprendre l’API Kinsta, les différentes informations nécessaires pour interagir avec l’API, et comment obtenir/stocker des informations importantes associées à l’API – comme la clé API – en toute sécurité sur GitHub.

Comprendre l’API Kinsta

L’API de Kinsta est un outil puissant qui vous permet d’interagir avec les services de Kinsta de manière programmatique. Pour utiliser l’API, vous devez avoir un compte avec au moins un site WordPress, une application ou une base de données dans MyKinsta. Vous devez également générer une clé API pour vous authentifier et accéder à votre compte via l’API.

Pour générer une clé API :

  1. Allez sur votre tableau de bord MyKinsta.
  2. Naviguez jusqu’à la page des clés API (Votre nom > Réglages de l’entreprise > Clés API).
  3. Cliquez sur Créer une clé API.
  4. Choisissez une date d’expiration ou définissez une date de début personnalisée et un nombre d’heures pour l’expiration de la clé.
  5. Donnez un nom unique à la clé.
  6. Cliquez sur Générer.
Créez une clé API sur MyKinsta.
Créez une clé API sur MyKinsta.

Après avoir créé une clé API, copiez-la et conservez-la dans un endroit sûr (nous vous recommandons d’utiliser un gestionnaire de mot de passe), car c’est la seule fois où elle sera révélée dans MyKinsta.

Comment déclencher le déploiement avec l’API Kinsta

Pour déployer une application sur Kinsta à l’aide de l’API, vous avez besoin de deux paramètres : l’identifiant de l’application et la branche. Vous pouvez récupérer par programme l’identifiant de votre application en consultant d’abord la liste de vos applications, qui fournira des détails sur chaque application, y compris son identifiant.

Après avoir obtenu les informations nécessaires, vous pouvez effectuer une requête POST au point de terminaison /applications/deployments de l’API. Pour le pipeline CI, nous utiliserons cURL, un outil de ligne de commande permettant d’interagir avec les URL.

curl -i -X POST 
  https://api.kinsta.com/v2/applications/deployments 
  -H 'Authorization: Bearer <YOUR_TOKEN_HERE>' 
  -H 'Content-Type: application/json' 
  -d '{
    "app_id": "<YOUR_APP_ID>",
    "branch": "main"
  }'

Déclencher le déploiement avec cURL dans le pipeline CI/CD

Pour déclencher le déploiement avec l’API Kinsta, ajoutez la commande cURL à la commande run de votre pipeline CI. Cependant, il est important de stocker votre clé API et votre ID d’application en toute sécurité.

Pour stocker des secrets sur GitHub et les utiliser dans les actions GitHub, suivez ces étapes :

  1. Naviguez jusqu’au dépôt dans lequel vous souhaitez configurer le secret.
  2. Cliquez sur l’onglet Réglages dans le menu du dépôt.
  3. Dans la colonne latérale de gauche, sélectionnez Secrets dans la catégorie Options.
  4. Cliquez sur Nouveau secret du dépôt.
  5. Donnez un nom à votre secret (comme KINSTA_API_KEY) et entrez votre clé API Kinsta dans le champ Valeur.
  6. Après avoir saisi le nom et la valeur, cliquez sur le bouton Ajouter un secret pour le sauvegarder.
  7. Répétez le processus pour d’autres secrets.
Stockez les secrets dans GitHub.
Stockez les secrets dans GitHub.

Une fois les secrets ajoutés, vous pouvez les référencer dans votre flux de travail GitHub Actions à l’aide de la syntaxe ${{ secrets.SECRET_NAME }}.

Terminons maintenant la tâche deploy pour votre pipeline CI/CD GitHub Actions. Définissez les étapes comme précédemment, avec une seule étape de déploiement vers Kinsta. Tout d’abord, définissez les secrets dans la commande env, puis ajoutez la commande cURL pour exécuter le déploiement.

    steps:
      - name: Deploy to Kinsta
        env:
          KINSTA_API_KEY: ${{ secrets.KINSTA_API_KEY }}
          APP_ID: ${{ secrets.APP_ID }}
        run: |
          curl -i -X POST 
            https://api.kinsta.com/v2/applications/deployments 
            -H "Authorization: Bearer $KINSTA_API_KEY" 
            -H "Content-Type: application/json" 
            -d '{
              "app_id": "'"$APP_ID"'",
              "branch": "main"
            }'

Dans la commande cURL, vous remarquerez que les variables d’environnement sont ajoutées dans la commande, ce qui permet aux secrets d’être accessibles en toute sécurité pendant le processus de déploiement.

Voici à quoi ressemblera votre flux de travail CI/CD final :

name: Build, Test, and Deploy

on:
  push:
    branches: "main"
  pull_request:
    branches: "main"

jobs:
  eslint:
    name: Check Syntax with ESLint
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [18.x, 20.x]

    steps:
      - name: Checkout code
        uses: actions/checkout@v3
        
      - name: Use Node.js ${{ matrix.node-version }} to Check Lint
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'
          
      - name: Install Dependencies
        run: npm ci
        
      - name: Run ESLint
        run: npm run lint

  tests:
    name: Run Tests
    needs: eslint
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v3
        
      - name: Use Node.js 18.x to run Test
        uses: actions/setup-node@v3
        with:
          node-version: 18.x
          cache: 'npm'
          
      - name: Install Dependencies
        run: npm ci
        
      - name: Run Tests
        run: npm run test

  deploy:
    name: Re-Deploy Application
    needs: [eslint, tests]
    runs-on: ubuntu-latest

    steps:
      - name: Deploy to Kinsta
        env:
          KINSTA_API_KEY: ${{ secrets.KINSTA_API_KEY }}
          APP_ID: ${{ secrets.APP_ID }}
        run: |
          curl -i -X POST 
            https://api.kinsta.com/v2/applications/deployments 
            -H "Authorization: Bearer $KINSTA_API_KEY" 
            -H "Content-Type: application/json" 
            -d '{
              "app_id": "'"$APP_ID"'",
              "branch": "main"
            }'

Copiez le flux de travail donné et collez-le dans votre fichier build-test-deploy.yml. Ensuite, lancez une demande d’extraction pour ajouter ce fichier à la branche principale de votre dépôt. N’oubliez pas que cette demande d’extraction déclenchera automatiquement le flux de travail.

Cela vous permet d’examiner les modifications apportées à votre dépôt et de vous assurer que toute nouvelle modification dans la demande d’extraction répond aux vérifications spécifiées avant de décider de la fusionner dans votre base de code.

Stockez les secrets dans GitHub.
Stockez les secrets dans GitHub.

Lorsque vous fusionnez la demande d’extraction. Naviguez vers l’onglet Actions de votre dépôt GitHub et vous verrez alors le flux de travail CI/CD en cours d’exécution.

Résumé des actions GitHub.
Résumé des actions GitHub.

Vous pouvez cliquer sur chaque tâche pour obtenir plus de détails à son sujet (c’est pourquoi vous devez donner à chaque étape de votre tâche une description significative).

Détails des étapes CI.
Détails des étapes CI.

Renforcer le flux de travail des demandes d’extraction sur GitHub

Pour assurer une gestion efficace du code et de la collaboration dans les dépôts GitHub, il est utile d’appliquer un flux de demandes d’extraction et de bloquer les livraisons directes à la branche principale. Cette approche établit un processus de développement contrôlé et organisé, exigeant que toutes les modifications fassent l’objet de demandes d’extraction et de révisions avant d’être fusionnées dans la branche principale.

En adoptant cette pratique, les équipes de développement peuvent améliorer la qualité du code, minimiser le risque d’introduction de bogues et conserver un historique transparent des modifications.

Voici comment configurer l’application du flux de travail des demandes d’extraction :

  1. Cliquez sur l’onglet Réglages dans votre dépôt GitHub.
  2. Sous Code et automatisation, sélectionnez Branches dans les options de la colonne latérale.
  3. Si aucune règle n’existe, cliquez sur Ajouter une règle de protection des branches.
  4. Donnez un nom à la règle, puis cochez la case Exiger une demande d’extraction avant de fusionner. Cela affichera plus d’options pour la configuration.
  5. Cochez également la case Exiger que les vérifications d’état soient réussies avant de fusionner.
  6. Personnalisez les options supplémentaires en fonction de vos préférences et de vos besoins.
  7. Cliquez sur le bouton Créer pour enregistrer la règle.
Renforcer le flux de travail des demandes d'extraction sur GitHub.
Renforcer le flux de travail des demandes d’extraction sur GitHub.

En suivant ces étapes, vous avez réussi à configurer une règle pour appliquer le flux de travail des demandes d’extraction dans votre dépôt GitHub. Cela garantit que toutes les modifications sont soumises à une révision et à des contrôles automatisés avant d’être fusionnées dans la branche principale, ce qui favorise un environnement de développement plus fiable et plus collaboratif.

Résumé

En combinant la puissance des actions GitHub et de l’API Kinsta, vous pouvez rationaliser votre flux de développement et favoriser un environnement collaboratif et efficace pour votre équipe de développement.

Les développeurs peuvent contribuer au code en toute confiance, sachant qu’il sera testé en profondeur avant d’atteindre la production, et les parties prenantes peuvent avoir l’esprit tranquille en sachant que le processus de déploiement est bien contrôlé et exempt d’erreurs.

Comment utilisez-vous l’API Kinsta ? Quels sont les points d’e terminaison que vous aimeriez voir ajoutés à l’API ? Quel tutoriel relatif à l’API Kinsta aimeriez-vous lire ensuite ?

Joel Olawanle Kinsta

Joel is a Frontend developer working at Kinsta as a Technical Editor. He is a passionate teacher with love for open source and has written over 200 technical articles majorly around JavaScript and it's frameworks.