Skip to content

arn00sdq/cicd

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Lab DevOps - GitHub CICD #1

TP - Intégration continue

Warning

Prérequis :

Présentation du TP

Ce TP est une initiation à la création et configuration de pipelines GitHub dans le cadre de la chaîne d'intégration continue (Continuous Integration Continuous Delivery).

L'intégration continue (de l'anglais : Continuous integration, CI), est un ensemble de pratiques utilisées en génie logiciel consistant à vérifier à chaque modification de code source que le résultat des modifications ne produit pas de régression dans l'application développée.

L'intégration continue repose souvent sur la mise en place d'une brique logicielle permettant l'automatisation de tâches : compilation, tests unitaires et fonctionnels, validation produit, tests de performances… À chaque changement du code, cette brique logicielle va exécuter un ensemble de tâches et produire un ensemble de résultats, que le développeur peut par la suite consulter. Cette intégration permet ainsi de ne pas oublier d'éléments lors de la mise en production et donc ainsi améliorer la qualité du produit.

-- Wikipedia : Intégration continue

GitHub Actions est une plateforme d’intégration continue et livraison continue (CI/CD) qui vous permet d’automatiser votre pipeline de génération, de test et de déploiement. Vous pouvez créer des workflows qui créent et testent chaque demande de tirage (pull request) adressée à votre dépôt, ou déployer des demandes de tirage fusionnées en production.

-- Documentation GitHub : Comprendre GitHub Actions

Un workflow est un processus automatisé configurable qui exécutera un ou plusieurs travaux. Les workflows sont définis par un fichier YAML archivé dans votre dépôt et s’exécutent lorsqu’ils sont déclenchés par un événement dans votre dépôt, ou ils peuvent être déclenchés manuellement ou selon une planification définie.

Les workflows sont définis dans le répertoire .github/workflows d’un référentiel, et un référentiel peut avoir plusieurs workflows, chacun pouvant effectuer un ensemble différent de tâches. Par exemple, vous pouvez avoir un workflow pour générer et tester des demandes de tirage, un autre workflow pour déployer votre application chaque fois qu’une version est créée, et encore un autre workflow qui ajoute une étiquette chaque fois que quelqu’un ouvre un nouveau problème.

-- Documentation GitHub : À propos des workflows

Présentation de l'application

Important

  • Un simple éditeur de texte suffit puisqu'il n'est pas demandé d'exécuter l'application en local.
  • Il est possible de travailler directement sur la branche par défaut (main).
  • La visibilité du repository doit être public afin de pouvoir aller jusqu'au bout du TP.
  • Des erreurs volontaires ont été introduites dans le TP. La correction ne doit être effectuée qu'une fois explicitement demandée.

Déroulement pratique

1. Exécution manuelle d'un workflow GitHub

2. Build de l'application

Tip

L'application se build via la ligne de commande npm run build.

Réponse my-workflow.yml
name: Manual build
on:
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "16"

      - name: Install dependencies
        run: npm install

      - name: Build application
        run: npm run build
  • Le build de l'application est en échec. Consulter les logs du workflow et corriger l'application. Vérifier que le build passe avec GitHub Actions.
Réponse index.ts
...
app.get("/minus/:a/:b", (request: Request, response: Response) => {
  ...
  const b = parseInt(request.params.b);
  ...
});
...

3. Tester l'application

  • Mettre à jour le workflow pour lancer les tests de l'application. Les tests sont en échec et doivent le rester pour le moment.

Tip

L'application se teste via la ligne de commande npm test.

Réponse my-workflow.yml
name: Manual build & test
on:
  workflow_dispatch:

jobs:
  build-and-test:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "16"

      - name: Install dependencies
        run: npm install

      - name: Build application
        run: npm run build

      - name: Test application
        run: npm test

4. Ajout d'un paramètre optionnel

Réponse my-workflow.yml
name: Manual build & test
on:
  workflow_dispatch:
    inputs:
      run-tests:
        description: "Run tests?"
        required: true
        default: "false"

jobs:
  build-and-test:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "16"

      - name: Install dependencies
        run: npm install

      - name: Build application
        run: npm run build

      - name: Test application
        if: ${{ github.event.inputs.run-tests == 'true' }}
        run: npm test

5. Déclenchement automatique sur Pull Request

  • Créer une nouvelle branche Git.
  • Mettre à jour le workflow pour qu'il s'exécute automatiquement lorsque le code est poussée sur une Pull Request (Documentation GitHub : Workflow Pull Request).
  • Les tests doivent être joués.
  • Pousser la branche et créer la Pull Request associée sans la fusionner.
Réponse my-workflow.yml
name: Manual or PR build & test
on:
  workflow_dispatch:
    inputs:
      run-tests:
        description: "Run tests?"
        required: true
        default: "false"
  pull_request:
    types: [opened, synchronize, reopened]

jobs:
  build-and-test:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "16"

      - name: Install dependencies
        run: npm install

      - name: Build application
        run: npm run build

      - name: Test application
        if: ${{ github.event.inputs.run-tests == 'true' || github.event_name == 'pull_request' }}
        run: npm test

6. Règles de protection de branche

  • La Pull Request précédemment créée peut tout de même être fusionnée alors que les tests unitaires de l'application ne sont pas tous en succès. Mettre en place une règle de sécurité sur la branche pour empêcher cela et bloquer tout push sur la branche de travail. (Documentation GitHub : Création d'un ensemble de règles pour un dépôt).
  • Vérifier que la Pull Request ne peut être fusionnée et qu'il n'est pas possible de pousser directement sur la branche de travail.

Tip

La vérification d'état s'attend à un job et non pas à un workflow. Dans l'exemple des corrections fournies plus haut, il s'agit de build-and-test.

Réponse
  • Aller dans Settings > Rules > Rulesets.
  • Cliquer sur New ruleset > New branch ruleset.
  • Nommer la règle et la rendre active.
  • Définir la branche sur laquelle les Pull Requests seront fusionnées.
  • Cocher Require a pull request before merging.
  • Cocher Require status checks to pass.
    • Afficher les paramètres additionnels et ajouter la vérification à effectuer.
  • Cliquer sur le bouton Create tout en bas.

7. Débloquer la Pull Request

  • Les tests de l'application sont en échec. Consulter les logs du workflow et corriger les tests de l'application.
  • Fusionner la Pull Request.
Réponse compute.util.ts
static minus(a: number, b: number): number {
  return a - b;
}

8. Utiliser des services

  • Créer une nouvelle branche et la Pull Request associée et y ajouter le fichier de test de connexion à la base de données suivant :

test/database.test.ts

import { Client } from "pg";

describe("Database", () => {
  test("connection", async () => {
    const database = new Client({
      host: "127.0.0.1",
      port: 5432,
      database: "cicd_database",
      user: "cicd_user",
      password: "cicd_password",
    });

    const connected = await database
      .connect()
      .then(() => true)
      .catch(() => false)
      .finally(async () => await database.end());
    expect(connected).toBe(true);
  });
});
Réponse my-workflow.yml
...
jobs:
  build-and-test:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:latest
        env:
          POSTGRES_DB: "cicd_database"
          POSTGRES_USER: "cicd_user"
          POSTGRES_PASSWORD: "cicd_password"
        ports:
          - 5432:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    ...

9. Mise en place de secrets

Réponse my-workflow.yml
---
POSTGRES_DB: ${{ secrets.CICD_POSTGRES_DB }}
POSTGRES_USER: ${{ secrets.CICD_POSTGRES_USER }}
POSTGRES_PASSWORD: ${{ secrets.CICD_POSTGRES_PASSWORD }}
  • Aller dans Settings > Secrets and variables > Actions.
  • Cliquer sur New repository secret.
  • Saisir successivement les 3 secrets :
    • CICD_POSTGRES_DB : cicd_database
    • CICD_POSTGRES_USER : cicd_user
    • CICD_POSTGRES_PASSWORD : cicd_password

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • TypeScript 100.0%