Nouveau : Datasets open source gratuits disponibles !Decouvrir →
Intermediaire 25 min Next.js

CI/CD pour Next.js avec GitHub Actions

Pourquoi CI/CD pour Next.js avec GitHub Actions ?

La continuité d'intégration et la livraison continue (CI/CD) sont essentielles dans le développement moderne des applications web, notamment pour les projets basés sur React. La mise en place de pipelines CI/CD permet d'automatiser les tests, la construction et la déploiement de votre application à chaque modification du code source. Cela réduit significativement les erreurs humaines, accélère le feedback des utilisateurs et augmente la qualité globale des applications.

Un cas concret est un projet de gestionnaire de tâches. En mettant en place une CI/CD avec GitHub Actions, chaque fois que vous pushez une modification dans votre dépôt Git, le pipeline vérifie automatiquement si le code compile, s'il passe les tests unitaires et si l'application peut être déployée sur un environnement de production. Cela permet d'identifier rapidement les problèmes et de corriger les bugs avant qu'ils ne soient vus par les utilisateurs.

Prerequis

  • Connaissance du langage JavaScript et React
  • Compréhension de Git et des bases de la gestion de dépôts
  • Un compte GitHub
  • Node.js et npm installés (version 14 ou supérieure)
  • Yarn installé (optionnel)

Concepts fondamentaux

Workflow

Un workflow est une série d'étapes automatisées qui définissent comment un événement spécifique doit être géré. Par exemple, chaque push sur la branche principale déclenche un workflow de déploiement.

## Exemple de workflow simple dans .github/workflows/deploy.yml
name: Deploy

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v2
    - name: Set up Node.js 14
      uses: actions/setup-node@v2
      with:
        node-version: '14'
    - run: npm install
    - run: npm run build

Actions

Les actions sont les unités de travail qui peuvent être exécutées dans un workflow. Elles peuvent être écrites en JavaScript ou utiliser des actions pré-existantes.

## Exemple d'action utilisant une action pré-existante pour installer Node.js
- name: Set up Node.js 14
  uses: actions/setup-node@v2
  with:
    node-version: '14'

Étapes

Les étapes sont les tâches individuelles qui forment un job. Elles peuvent exécuter des commandes shell, installer des dépendances ou appeler d'autres actions.

## Exemple de étape pour installer les dépendances du projet
- run: npm install

Mise en pratique : projet fil rouge

Nous allons créer un mini-projet complet et réaliste : une API de blog. Ce projet comprendra la création, la lecture, la mise à jour et la suppression d'articles.

Étape 1 : Initialisation du projet

Créez un nouveau dépôt GitHub et clonez-le localement. Initialisez le projet Next.js.

npx create-next-app@latest blog-api
cd blog-api

Étape 2 : Configuration de la base de données

Nous utiliserons Prisma pour gérer la base de données SQLite.

npm install prisma --save-dev
npx prisma init

Editez prisma/schema.prisma :

datasource db {
  provider = "sqlite"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}

model Post {
  id        Int     @id @default(autoincrement())
  title     String  @db.VarChar(100)
  content   String
  createdAt DateTime@db.Timestamp(@default(now()))
}

Créez un fichier .env à la racine du projet avec :

DATABASE_URL=file:./dev.db

Étape 3 : Création des modèles Prisma

Générez le client Prisma et créez les fichiers de modèle.

npx prisma migrate dev --name init

Étape 4 : Création des API CRUD

Créez un fichier pages/api/posts.js pour gérer les opérations CRUD :

// pages/api/posts.js
import prisma from '../../lib/prisma'

export default async function handler(req, res) {
  const { method } = req

  switch (method) {
    case 'GET':
      // Récupère tous les articles
      const posts = await prisma.post.findMany()
      res.status(200).json(posts)
      break
    case 'POST':
      // Crée un nouvel article
      const { title, content } = req.body
      const newPost = await prisma.post.create({
        data: {
          title,
          content,
        },
      })
      res.status(201).json(newPost)
      break
    default:
      res.setHeader('Allow', ['GET', 'POST'])
      res.status(405).end(`Method ${method} Not Allowed`)
  }
}

Étape 5 : Création de l'interface utilisateur

Créez un fichier pages/index.js pour afficher les articles et créer de nouveaux :

// pages/index.js
import { useState, useEffect } from 'react'
import axios from 'axios'

function Home() {
  const [posts, setPosts] = useState([])
  const [title, setTitle] = useState('')
  const [content, setContent] = useState('')

  useEffect(() => {
    fetchPosts()
  }, [])

  async function fetchPosts() {
    const response = await axios.get('/api/posts')
    setPosts(response.data)
  }

  async function createPost(event) {
    event.preventDefault()
    await axios.post('/api/posts', { title, content })
    setTitle('')
    setContent('')
    fetchPosts()
  }

  return (
    <div>
      <h1>Blog API</h1>
      <form onSubmit={createPost}>
        <input
          type="text"
          placeholder="Title"
          value={title}
          onChange={(e) => setTitle(e.target.value)}
        />
        <textarea
          placeholder="Content"
          value={content}
          onChange={(e) => setContent(e.target.value)}
        />
        <button type="submit">Create Post</button>
      </form>
      <ul>
        {posts.map((post) => (
          <li key={post.id}>
            <h2>{post.title}</h2>
            <p>{post.content}</p>
            <p>Created at: {post.createdAt.toString()}</p>
          </li>
        ))}
      </ul>
    </div>
  )
}

export default Home

Étape 6 : Ajout de la gestion des erreurs

Ajoutez une gestion des erreurs dans le fichier pages/index.js :

// pages/index.js (avec gestion des erreurs)
async function createPost(event) {
  event.preventDefault()
  try {
    await axios.post('/api/posts', { title, content })
    setTitle('')
    setContent('')
    fetchPosts()
  } catch (error) {
    console.error('Error creating post:', error)
    alert('Failed to create post. Please try again.')
  }
}

Étape 7 : Ajout d'un workflow GitHub Actions

Créez un fichier .github/workflows/deploy.yml pour définir le pipeline CI/CD :

name: Deploy

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v2
    - name: Set up Node.js 14
      uses: actions/setup-node@v2
      with:
        node-version: '14'
    - run: npm install
    - run: npm run build
    - name: Deploy to Vercel
      uses: vercel/actions/deploy@v18
      with:
        apiToken: $secrets.VERCEL_API_TOKEN
        projectRoot: .
        scope: your-vercel-scope
        alias: blog-api

Ajoutez votre token Vercel à vos variables d'environnement GitHub :

gh secret set VERCEL_API_TOKEN -b $(cat ~/.vercel/api-key)

Erreurs frequentes et debugging

1. Erreur : Error: Cannot find module 'prisma-client-js'

Code incorrect :

// pages/index.js (mauvais import)
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()

Code correct :

// pages/index.js (correct import)
import prisma from '../../lib/prisma'

2. Erreur : Error: connect ECONNREFUSED 127.0.0.1:3306

Code incorrect :

## .github/workflows/deploy.yml (mauvaise configuration de la base de données)
generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

Code correct :

## .github/workflows/deploy.yml (correcte configuration de la base de données)
generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "sqlite"
  url      = env("DATABASE_URL")
}

3. Erreur : Error: ENOENT: no such file or directory, open 'dev.db'

Code incorrect :

## .github/workflows/deploy.yml (mauvaise configuration de la base de données)
datasource db {
  provider = "sqlite"
  url      = env("DATABASE_URL")
}

Code correct :

## .github/workflows/deploy.yml (correcte configuration de la base de données)
datasource db {
  provider = "sqlite"
  url      = env("DATABASE_URL")
}

Pour aller plus loin

  1. Tests automatisés avec Jest et Supertest : Ajoutez des tests pour vous assurer que votre API fonctionne correctement.
  2. Déploiement sur Vercel : Utilisez Vercel pour déploiement continu en utilisant des secrets GitHub Actions.
  3. Intégration avec Docker : Créez un fichier Dockerfile pour containeriser votre application et faciliter le déploiement.

Défi pratique

Créez une application de todo list complète en suivant les mêmes étapes que dans ce tutoriel, mais cette fois-ci utilisez MongoDB comme base de données.

Besoin d'aide sur Next.js ?

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 Next.js?
Pour configurer GitHub Actions pour votre projet Next.js, créez un fichier .github/workflows/main.yml dans la racine de votre dépôt. Ajoutez une configuration YAML qui définit les étapes du workflow, comme l'installation des dépendances et le lancement des tests.
Quelles sont les meilleures pratiques pour optimiser les performances de mon application Next.js avec GitHub Actions?
Pour optimiser les performances de votre application Next.js avec GitHub Actions, utilisez un workflow qui inclut des étapes pour la construction et le déploiement. Assurez-vous d'utiliser une machine virtuelle rapide et optimisée pour accélérer le build. Vous pouvez également utiliser des actions spécifiques à Next.js comme nextjs-build-action.
Comment tester les prévisualisations locales avec GitHub Actions?
Pour tester les prévisualisations locales dans GitHub Actions, vous pouvez utiliser l'action vercel/actions-nextjs qui permet de déployer une instance locale de votre application Next.js. Configurez le workflow pour construire et déployer votre application en local chaque fois qu'un commit est poussé.

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.