Введение в CI/CD для C++ с GitHub Actions
Современная разработка на C++ немыслима без автоматизации процессов сборки и тестирования. CI/CD (Continuous Integration / Continuous Deployment) позволяет командам быстро выявлять ошибки, автоматически собирать бинарные файлы и развертывать приложения. GitHub Actions — это мощный инструмент, встроенный в GitHub, который идеально подходит для C++ проектов. В этой статье мы разберем, как настроить полный пайплайн CI/CD для C++: от компиляции с CMake до деплоя готовых артефактов.
Мы рассмотрим реальные примеры кода, типичные ошибки и лучшие практики. После прочтения вы сможете самостоятельно внедрить CI/CD в свой C++ проект.
Основы GitHub Actions для C++
Структура workflow-файла
Workflow в GitHub Actions определяется YAML-файлом в директории .github/workflows/. Рассмотрим базовый пример для C++ проекта:
name: C++ CI/CD Pipeline
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y cmake g++ libboost-all-dev
- name: Configure with CMake
run: mkdir build && cd build && cmake ..
- name: Build project
run: cd build && make -j$(nproc)
- name: Run tests
run: cd build && ctest --output-on-failure
Этот workflow запускается при пушах в main и develop, а также при создании pull request. Он устанавливает зависимости, конфигурирует сборку через CMake, компилирует проект и запускает тесты.
Выбор операционной системы и компилятора
GitHub Actions поддерживает Linux (ubuntu), macOS и Windows. Для кроссплатформенных проектов можно использовать матрицу сборок:
jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
compiler: [g++, clang++]
runs-on: ${{ matrix.os }}
steps:
- name: Set compiler
run: |
if [ "${{ matrix.os }}" == "windows-latest" ]; then
echo "CXX=cl.exe" >> $GITHUB_ENV
else
echo "CXX=${{ matrix.compiler }}" >> $GITHUB_ENV
fi
shell: bash
Это позволяет проверить совместимость кода с разными компиляторами и ОС.
Расширенная настройка: тестирование, кэширование и артефакты
Кэширование зависимостей
Каждая сборка в GitHub Actions начинается с чистого окружения. Чтобы ускорить процесс, кэшируйте скачанные пакеты и библиотеки:
- name: Cache CMake build directory
uses: actions/cache@v3
with:
path: build
key: ${{ runner.os }}-cmake-${{ hashFiles('**/CMakeLists.txt') }}
restore-keys: |
${{ runner.os }}-cmake-
- name: Configure CMake
run: cmake -B build -S . -DCMAKE_BUILD_TYPE=Release
Кэш восстанавливается, если файлы CMakeLists.txt не изменились, что экономит время при повторных сборках.
Запуск unit-тестов с Google Test
Для C++ часто используют Google Test. Добавим этап тестирования с генерацией отчета в формате JUnit:
- name: Build and run tests
run: |
cmake --build build --target all_tests
cd build && ctest --output-junit test-results.xml
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results-${{ runner.os }}
path: build/test-results.xml
Флаг if: always() гарантирует загрузку отчета даже при падении тестов.
Создание и публикация артефактов
После успешной сборки можно сохранить бинарные файлы:
- name: Build release binary
run: cmake --build build --config Release
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: myapp-${{ runner.os }}-${{ github.sha }}
path: build/bin/
Артефакты доступны для скачивания в интерфейсе GitHub Actions и могут быть использованы в последующих джобах.
Деплой C++ приложения: от бинарника до Docker образа
Автоматический релиз на GitHub Releases
При пуше тега можно создавать релиз и загружать собранные бинарники:
jobs:
release:
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build
run: |
cmake -B build -S . -DCMAKE_BUILD_TYPE=Release
cmake --build build
- name: Create Release
uses: softprops/action-gh-release@v1
with:
files: build/bin/myapp
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Теперь каждый новый тег v1.0.0 автоматически создает релиз с бинарным файлом.
Сборка и публикация Docker образа
Если ваше C++ приложение работает в контейнере, можно автоматизировать сборку Docker образа:
- name: Build Docker image
run: docker build -t myapp:${{ github.sha }} .
- name: Push to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Push image
run: |
docker tag myapp:${{ github.sha }} myrepo/myapp:latest
docker push myrepo/myapp:latest
Не забудьте добавить секреты DOCKER_USERNAME и DOCKER_PASSWORD в настройках репозитория.
Заключение
GitHub Actions предоставляет все необходимые инструменты для построения полноценного CI/CD пайплайна для C++ проектов. Мы рассмотрели базовую сборку с CMake, кэширование для ускорения, запуск тестов с Google Test, создание артефактов и деплой через GitHub Releases и Docker.
Ключевые рекомендации:
- Используйте матрицу сборок для проверки на разных ОС и компиляторах.
- Кэшируйте директории сборки и зависимости.
- Загружайте результаты тестов как