Nouveau : Datasets open source gratuits disponibles !Decouvrir →
🟢
Intermediaire 25 min Express

CI/CD pour Express avec GitHub Actions

Pourquoi CI/CD pour Express avec GitHub Actions ?

Le Continuous Integration et Continuous Deployment (CI/CD) sont des pratiques essentielles en développement logiciel modernes. Ils permettent aux développeurs de vérifier automatiquement leur code, de détecter les erreurs en temps réel et de déployer rapidement leurs applications. Pour un projet Express, GitHub Actions est une solution idéale car il offre une intégration fluide avec le processus de développement et offre des outils puissants pour automatiser le CI/CD.

Un cas concret d'utilisation serait le déploiement d'une application API qui gère les données utilisateurs. Avec un flux de travail CI/CD, chaque fois qu'un développeur soumet une modification via GitHub, le code est automatiquement testé et déployé sur un serveur. Cela permet une meilleure collaboration entre les équipes, réduit les erreurs humaines et accélère le lancement des nouvelles fonctionnalités.

Prerequis

Pour suivre ce tutoriel, vous aurez besoin des connaissances suivantes :

  • Connaissance de base d'Express
  • Un compte GitHub avec une organisation ou un dépôt privé
  • Node.js et npm installés sur votre machine (v14.0.0 ou plus)
  • Git installé sur votre machine

Concepts fondamentaux

Workflow GitHub Actions

Un workflow dans GitHub Actions est une séquence d'étapes qui s'exécutent automatiquement à chaque événement déclenchant le workflow. Pour un projet Express, un workflow typique pourrait inclure les étapes suivantes :

  1. Checkout du dépôt : Récupérer le code source du dépôt GitHub.
  2. Installation des dépendances : Installer toutes les dépendances nécessaires à l'application.
  3. Tests unitaires : Exécuter les tests unitaires pour s'assurer que le code fonctionne correctement.
  4. Déploiement : Déployer l'application sur un serveur.

Configuration du Workflow

Le fichier de configuration d'un workflow est écrit en YAML et se trouve dans le répertoire .github/workflows de votre dépôt GitHub. Voici un exemple simple d'un workflow pour un projet Express :

## .github/workflows/main.yml
name: CI/CD for Express App

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

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

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

    - name: Set up Node.js
      uses: actions/setup-node@v2
      with:
        node-version: '14'

    - name: Install dependencies
      run: npm install

    - name: Run tests
      run: npm test

Bloc de Code : Installation des Dépendances

Voici un exemple de fichier package.json pour un projet Express simple :

{
  "name": "express-app",
  "version": "1.0.0",
  "description": "A simple Express app",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
    "test": "jest"
  },
  "dependencies": {
    "express": "^4.17.1"
  },
  "devDependencies": {
    "jest": "^26.6.3"
  }
}

Bloc de Code : Tests Unitaires

Voici un exemple de fichier test/index.test.js pour les tests unitaires :

const express = require('express');
const app = express();
app.get('/', (req, res) => {
  res.send('Hello World!');
});

// Test unitaire
const request = require('supertest');

describe('GET /', () => {
  it('should return "Hello World!"', async () => {
    const response = await request(app).get('/');
    expect(response.status).toBe(200);
    expect(response.text).toBe('Hello World!');
  });
});

Mise en pratique : projet fil rouge

Mini-Projet : Gestionnaire de Tâches

Dans ce mini-projet, nous allons créer un simple gestionnaire de tâches avec Express. Le projet comprendra les routes suivantes :

  • GET /tasks : Obtenir la liste des tâches
  • POST /tasks : Ajouter une nouvelle tâche
  • PUT /tasks/:id : Mettre à jour une tâche existante
  • DELETE /tasks/:id : Supprimer une tâche

Étapes pour le Projet

  1. Initialisation du projet

    mkdir express-task-manager
    cd express-task-manager
    npm init -y
    
  2. Installation des dépendances

    npm install express body-parser
    
  3. Structure de fichiers

    express-task-manager/
    ├── .github/
    │   └── workflows/
    │       └── main.yml
    ├── index.js
    ├── package.json
    └── tasks.js
    
  4. Fichier index.js

    const express = require('express');
    const bodyParser = require('body-parser');
    const app = express();
    const port = 3000;
    const tasks = require('./tasks');
    
    app.use(bodyParser.json());
    
    // Récupérer la liste des tâches
    app.get('/tasks', (req, res) => {
      res.send(tasks);
    });
    
    // Ajouter une nouvelle tâche
    app.post('/tasks', (req, res) => {
      const newTask = req.body;
      tasks.push(newTask);
      res.status(201).send(newTask);
    });
    
    // Mettre à jour une tâche existante
    app.put('/tasks/:id', (req, res) => {
      const id = parseInt(req.params.id);
      const updatedTask = req.body;
      tasks[id] = { ...tasks[id], ...updatedTask };
      res.send(tasks[id]);
    });
    
    // Supprimer une tâche
    app.delete('/tasks/:id', (req, res) => {
      const id = parseInt(req.params.id);
      tasks.splice(id, 1);
      res.status(204).send();
    });
    
    app.listen(port, () => {
      console.log(`Server running at http://localhost:${port}`);
    });
    
  5. Fichier tasks.js

    let tasks = [];
    
    module.exports = tasks;
    
  6. Configuration du Workflow GitHub Actions (main.yml)

    # .github/workflows/main.yml
    name: CI/CD for Express App
    
    on:
      push:
        branches: [ main ]
      pull_request:
        branches: [ main ]
    
    jobs:
      build-and-test:
        runs-on: ubuntu-latest
    
        steps:
        - name: Checkout code
          uses: actions/checkout@v2
    
        - name: Set up Node.js
          uses: actions/setup-node@v2
          with:
            node-version: '14'
    
        - name: Install dependencies
          run: npm install
    
        - name: Run tests
          run: npm test
    
  7. Configuration des Tests Unitaires (tasks.test.js)

    const request = require('supertest');
    const app = require('../index');
    
    describe('GET /tasks', () => {
      it('should return an array of tasks', async () => {
        await request(app).post('/tasks').send({ title: 'Task 1' });
        const response = await request(app).get('/tasks');
        expect(response.status).toBe(200);
        expect(Array.isArray(response.body)).toBe(true);
      });
    });
    
    describe('POST /tasks', () => {
      it('should add a new task', async () => {
        const response = await request(app).post('/tasks').send({ title: 'Task 1' });
        expect(response.status).toBe(201);
        expect(response.body.title).toBe('Task 1');
      });
    });
    
    describe('PUT /tasks/:id', () => {
      it('should update an existing task', async () => {
        await request(app).post('/tasks').send({ title: 'Task 1' });
        const taskId = 0;
        const response = await request(app).put(`/tasks/${taskId}`).send({ title: 'Updated Task 1' });
        expect(response.status).toBe(200);
        expect(response.body.title).toBe('Updated Task 1');
      });
    });
    
    describe('DELETE /tasks/:id', () => {
      it('should delete an existing task', async () => {
        await request(app).post('/tasks').send({ title: 'Task 1' });
        const taskId = 0;
        const response = await request(app).delete(`/tasks/${taskId}`);
        expect(response.status).toBe(204);
      });
    });
    

Erreurs frequentes et debugging

Erreur : "Cannot find module 'express'"

// ❌ Mauvais
const express = require('express');
javascript
// ✅ Correct
npm install express --save
const express = require('express');

Erreur : "SyntaxError: Unexpected token import"

Si vous obtenez cette erreur, assurez-vous que vous utilisez un environnement qui supporte ES6 modules. Vous pouvez ajouter le type module dans votre package.json :

{
  "type": "module"
}

Erreur : "Error: listen EADDRINUSE: address already in use"

Si vous obtenez cette erreur, il peut y avoir un autre processus qui utilise déjà le port sur lequel l'application s'exécute. Vous pouvez changer le port dans votre fichier index.js :

const port = 3001; // Changer de port

Pour aller plus loin

Piste 1 : Ajouter des Tests d'Intégration

Vous pouvez ajouter des tests d'intégration pour vous assurer que toutes les parties de votre application fonctionnent ensemble correctement.

// tasks.integration.test.js
const request = require('supertest');
const app = require('../index');

describe('Integration tests', () => {
  it('should add a task and retrieve it', async () => {
    const response1 = await request(app).post('/tasks').send({ title: 'Task 1' });
    expect(response1.status).toBe(201);

    const taskId = 0;
    const response2 = await request(app).get(`/tasks/${taskId}`);
    expect(response2.status).toBe(200);
    expect(response2.body.title).toBe('Task 1');
  });
});

Piste 2 : Déploiement sur Heroku

Vous pouvez déployer votre application Express sur Heroku en utilisant GitHub Actions.

## .github/workflows/deploy.yml
name: Deploy to Heroku

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest

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

    - name: Set up Node.js
      uses: actions/setup-node@v2
      with:
        node-version: '14'

    - name: Install dependencies
      run: npm install

    - name: Build the app (if necessary)
      run: npm run build # Si votre application nécessite une étape de construction

    - name: Deploy to Heroku
      uses: akhileshns/heroku-deploy@v3.12.12
      with:
        heroku_api_key: $secrets.HEROKU_API_KEY
        heroku_app_name: "your-heroku-app-name"
        heroku_email: "your-email@example.com"

Piste 3 : Utiliser Docker

Vous pouvez utiliser Docker pour encapsuler votre application Express et la déployer facilement sur un serveur.

## Dockerfile
FROM node:14

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 3000

CMD ["node", "index.js"]

Créez ensuite un fichier docker-compose.yml :

## docker-compose.yml
version: '3'

services:
  app:
    build: .
    ports:
      - "3000:3000"

Déployez l'application avec Docker Compose :

docker-compose up -d

Défi pratique

  1. Ajoutez une nouvelle fonctionnalité à votre gestionnaire de tâches, par exemple, la possibilité de filtrer les tâches par statut (complétées/non-complétées).
  2. Configurez un workflow GitHub Actions pour déployer votre application sur AWS Elastic Beanstalk.
  3. Créez une documentation complète pour votre API en utilisant Swagger.

En suivant ces étapes et en résolvant les erreurs communes, vous serez bien équipé pour mettre en œuvre un CI/CD efficace pour vos projets Express avec GitHub Actions.

Besoin d'aide sur Express ?

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

Recevoir des conseils

Questions frequentes

Comment configurer GitHub Actions pour un projet Express?
Pour configurer GitHub Actions, vous devez créer un fichier .github/workflows/ci-cd.yml dans votre répository GitHub. Ce fichier doit contenir des étapes de configuration spécifiques à votre application Express, comme l'installation des dépendances et le lancement des tests.
Quels types de travaux (jobs) puis-je inclure dans mon workflow GitHub Actions pour un projet Express?
Vous pouvez inclure différents types de travaux dans votre workflow, comme 'build' pour construire votre application, 'test' pour exécuter les tests, et 'deploy' pour déployer l'application sur une plateforme telle que Heroku ou AWS.
Comment puis-je spécifier des environnements de travail distincts dans mon workflow GitHub Actions?
Vous pouvez définir des environnements de travail distincts en créant plusieurs travaux (jobs) dans votre fichier .github/workflows/ci-cd.yml. Chaque travail peut avoir ses propres étapes et configurations spécifiques, ce qui vous permet de contrôler les tests et le déploiement en fonction du type d'environnement.

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.