CI/CD avanzado para proyectos C++ en GitHub Actions
Cuando el pipeline simple de "compilar - ejecutar pruebas - desplegar" ya no es suficiente, llega el momento de las técnicas avanzadas. En este artículo veremos cómo configurar GitHub Actions para proyectos C++ a nivel profesional: caché de dependencias, matriz de compilación para diferentes compiladores, análisis estático de código, artefactos y disparadores inteligentes. Todos los ejemplos están en C++ usando CMake.
1. Caché de dependencias y aceleración de la compilación
Cada ejecución del workflow comienza con una máquina virtual limpia. Sin caché, descargarás y compilarás la misma biblioteca (por ejemplo, Boost o Google Test) cada vez. La solución es usar el caché integrado de GitHub Actions.
name: CI para C++ (avanzado)on: [push, pull_request]
jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- name: Caché de dependencias uses: actions/cache@v3 with: path: | ~/.cache build/_deps key: ${{ runner.os }}-c++-${{ hashFiles('CMakeLists.txt', '**/*.cmake') }} restore-keys: | ${{ runner.os }}-c++-
- name: Instalación de dependencias del sistema run: sudo apt-get update && sudo apt-get install -y libboost-all-dev
- name: Compilación run: | cmake -B build -DCMAKE_BUILD_TYPE=Release cmake --build build -j$(nproc)La clave key se genera a partir del hash de CMakeLists.txt — al cambiar la lista de dependencias, el caché se invalida automáticamente. El parámetro restore-keys permite restaurar parcialmente el caché si no se encuentra la clave exacta.
2. Matriz de compilación: múltiples compiladores y plataformas
Al desarrollar una aplicación C++ multiplataforma, es importante verificar la compilación con diferentes compiladores. GitHub Actions admite la estrategia de matriz (matrix strategy).
jobs: build: strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] compiler: [gcc, clang, msvc] exclude: - os: ubuntu-latest compiler: msvc - os: windows-latest compiler: clang - os: macos-latest compiler: msvc
runs-on: ${{ matrix.os }}
steps: - uses: actions/checkout@v4
- name: Configuración del compilador (Linux) if: runner.os == 'Linux' run: | if [ "${{ matrix.compiler }}" == "gcc" ]; then echo "CC=gcc" >> $GITHUB_ENV echo "CXX=g++" >> $GITHUB_ENV elif [ "${{ matrix.compiler }}" == "clang" ]; then echo "CC=clang" >> $GITHUB_ENV echo "CXX=clang++" >> $GITHUB_ENV fi
- name: Compilación con CMake run: | cmake -B build -DCMAKE_BUILD_TYPE=Debug cmake --build buildLa matriz genera automáticamente 6 tareas (3 SO × 2 compiladores después de excluir combinaciones no válidas). Esto permite detectar rápidamente problemas específicos de un compilador o plataforma en particular.
3. Análisis estático y linters
La calidad del código C++ es crítica. Incorpore en el pipeline análisis estático con Clang-Tidy, Cppcheck o SonarCloud. Veamos un ejemplo con Clang-Tidy.
jobs: static-analysis: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- name: Instalación de herramientas run: | sudo apt-get install -y clang-tidy cppcheck pip install compiledb
- name: Generación de compile_commands.json run: | cmake -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON compiledb -o build/compile_commands.json make -C build
- name: Ejecución de Clang-Tidy run: | find . -name '*.cpp' -o -name '*.hpp' | xargs clang-tidy -p build --checks='*,-modernize-use