Introduction : Quand "ça marche sur ma machine" est une catastrophe
Chaque développeur C++ a au moins une fois entendu la phrase : "Chez moi ça marche, c'est étrange que ça plante chez toi". Ou l'a lui-même prononcée. Compilation de templates, édition de liens, particularités des différentes normes (C++17, C++20), macros dépendantes de la plateforme — le C++ est plein de surprises qui surgissent lors d'un changement d'environnement.
Un pipeline CI/CD (Intégration Continue / Déploiement Continu) pour C++ n'est pas un luxe, mais une nécessité. Il compile automatiquement le projet, exécute les tests, vérifie la qualité du code et, en cas de succès, déploie l'application sur un serveur (ou publie une bibliothèque). Dans cet article, nous allons configurer un pipeline complet de zéro en utilisant GitHub Actions, CMake et C++. Vous obtiendrez une configuration prête à l'emploi que vous pourrez adapter à votre projet.
1. Préparation du projet : structure et système de build
Avant d'écrire le pipeline, il faut mettre de l'ordre dans le projet. Nous utiliserons CMake — le standard de facto pour les projets C++ modernes. Notre exemple sera un simple utilitaire de traitement de chaînes de caractères avec des tests unitaires utilisant Google Test.
Structure du dépôt
my_cpp_project/├── .github/│ └── workflows/│ └── ci.yml # Fichier du pipeline├── src/│ ├── main.cpp│ └── string_utils.cpp├── include/│ └── string_utils.hpp├── tests/│ ├── CMakeLists.txt│ └── test_string_utils.cpp├── CMakeLists.txt # CMake racine├── Dockerfile # Pour le déploiement final└── README.mdCMakeLists.txt racine
Nous compilons la bibliothèque et l'exécutable. Notez l'export des tests :
cmake_minimum_required(VERSION 3.20)project(MyStringUtils VERSION 1.0.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Bibliothèque principaleadd_library(string_utils STATIC src/string_utils.cpp include/string_utils.hpp)target_include_directories(string_utils PUBLIC include)
# Exécutableadd_executable(my_app src/main.cpp)target_link_libraries(my_app PRIVATE string_utils)
# Tests (optionnels, activés par une option)option(BUILD_TESTS "Build unit tests" ON)if(BUILD_TESTS) enable_testing() add_subdirectory(tests)endif()Exemple de test (tests/test_string_utils.cpp)
#include <gtest/gtest.h>#include "string_utils.hpp"
TEST(StringUtilsTest, ToUpper) { EXPECT_EQ(to_upper("hello"), "HELLO"); EXPECT_EQ(to_upper("C++20"), "C++20");}
TEST(StringUtilsTest, Trim) { EXPECT_EQ(trim(" spaced "), "spaced"); EXPECT_EQ(trim("\\t\\r"), "");}Maintenant que le projet est prêt, passons à l'essentiel — la configuration du pipeline CI/CD pour C++.
2. GitHub Actions : écrire le premier pipeline
GitHub Actions est l'outil le plus populaire pour le CI/CD dans l'Open Source. Sa configuration s'écrit en YAML et se trouve dans le dossier .github/workflows. Créons le fichier ci.yml.
Structure de base : déclenchement lors d'un push et d'une PR
name: C++ CI/CD Pipeline
on: push: branches: [ main, develop ] pull_request: branches: [ main ]
jobs: build-and-test: runs-on: ubuntu-latest
steps: - name: Checkout code uses: actions/checkout@v4
- name: Install dependencies run: | sudo apt-get update sudo apt-get install -y cmake g++ libgtest-dev
- name: Configure CMake run: cmake -B build -DCMAKE_BUILD_TYPE=Release
- name: Build run: cmake --build build --parallel $(nproc)
- name: Run tests run: cd build && ctest --output-on-failureC'est un pipeline CI/CD pour C++ minimal mais déjà fonctionnel. Si les tests échouent, le pipeline se termine par une erreur et vous recevez une notification. Mais nous allons plus