CI/CD для C++ проектов: GitHub Actions продвинутый уровень

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Продвинутый CI/CD для C++ проектов на GitHub Actions

Когда простой пайплайн «собрал — запустил тесты — задеплоил» перестаёт справляться, наступает время продвинутых техник. В этой статье мы рассмотрим, как настроить GitHub Actions для C++ проектов на профессиональном уровне: кэширование зависимостей, матрица сборок под разные компиляторы, статический анализ кода, артефакты и умные триггеры. Все примеры даны на C++ с использованием CMake.

1. Кэширование зависимостей и ускорение сборки

Каждый запуск workflow начинается с чистой виртуальной машины. Без кэширования вы будете каждый раз скачивать и собирать одну и ту же библиотеку (например, Boost или Google Test). Решение — использовать встроенное кэширование GitHub Actions.

name: CI для C++ (продвинутый)
on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Кэширование зависимостей
        uses: actions/cache@v3
        with:
          path: |
            ~/.cache
            build/_deps
          key: ${{ runner.os }}-c++-${{ hashFiles('CMakeLists.txt', '**/*.cmake') }}
          restore-keys: |
            ${{ runner.os }}-c++-

      - name: Установка системных зависимостей
        run: sudo apt-get update && sudo apt-get install -y libboost-all-dev

      - name: Сборка
        run: |
          cmake -B build -DCMAKE_BUILD_TYPE=Release
          cmake --build build -j$(nproc)

Ключ key формируется на основе хеша CMakeLists.txt — при изменении списка зависимостей кэш автоматически инвалидируется. Параметр restore-keys позволяет частично восстановить кэш, если точный ключ не найден.

2. Матрица сборок: несколько компиляторов и платформ

При разработке кроссплатформенного C++ приложения важно проверять сборку под разными компиляторами. GitHub Actions поддерживает матрицу стратегий (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: Настройка компилятора (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: Сборка с CMake
        run: |
          cmake -B build -DCMAKE_BUILD_TYPE=Debug
          cmake --build build

Матрица автоматически порождает 6 задач (3 ОС × 2 компилятора после исключения невалидных комбинаций). Это позволяет быстро обнаружить проблемы, специфичные для конкретного компилятора или платформы.

3. Статический анализ и линтеры

Качество C++ кода критично. Внедрите в пайплайн статический анализ с помощью Clang-Tidy, Cppcheck или SonarCloud. Рассмотрим пример с Clang-Tidy.

jobs:
  static-analysis:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Установка инструментов
        run: |
          sudo apt-get install -y clang-tidy cppcheck
          pip install compiledb

      - name: Генерация compile_commands.json
        run: |
          cmake -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
          compiledb -o build/compile_commands.json make -C build

      - name: Запуск Clang-Tidy
        run: |
          find . -name '*.cpp' -o -name '*.hpp' | xargs clang-tidy -p build --checks='*,-modernize-use-trailing-return-type' --warnings-as-errors='*'

      - name: Cppcheck
        run: |
          cppcheck --enable=all --suppress=missingIncludeSystem --error-exitcode=1 .

Флаг --warnings-as-errors='*' превращает все предупреждения Clang-Tidy в ошибки — пайплайн упадёт, если код не соответствует стандартам. Cppcheck дополнительно проверит на утечки памяти и неопределённое поведение.

4. Артефакты и автоматическая публикация релизов

После успешной сборки полезно сохранить бинарные файлы как артефакты. А при создании тега — автоматически формировать релиз на GitHub.

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Сборка
        run: |
          cmake -B build -DCMAKE_BUILD_TYPE=Release
          cmake --build build
      - name: Загрузка артефактов
        uses: actions/upload-artifact@v4
        with:
          name: myapp-linux
          path: build/bin/

  release:
    needs: build
    if: startsWith(github.ref, 'refs/tags/v')
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Скачать артефакты
        uses: actions/download-artifact@v4
        with:
          name: myapp-linux
          path: ./release
      - name: Создать релиз
        uses: softprops/action-gh-release@v2
        with:
          files: ./release/*
          generate_release_notes: true

Артефакты хранятся 90 дней по умолчанию. Их можно скачать вручную из интерфейса GitHub Actions или использовать в следующих джобах. Релиз создаётся только при пуше тега, начинающегося с v (например, v1.2.3).

Заключение

Продвинутый CI/CD для C++ на GitHub Actions — это не просто сборка и тесты. Это кэширование, ускоряющее пайплайн в 2-3 раза, матрица сборок, проверяющая совместимость с разными компиляторами, статический анализ, повышающий качество кода, и автоматическая публикация релизов. Внедрение этих практик превращает ваш репозиторий в профессиональную среду разработки, где каждая ошибка отлавливается до того, как попад

Блоги

Рекомендаций по книгам