基于 GitHub Actions 的 C++ 项目高级 CI/CD
当简单的“构建 - 运行测试 - 部署”流水线无法满足需求时,就该采用高级技术了。在本文中,我们将探讨如何在专业级别上为 C++ 项目配置 GitHub Actions:依赖缓存、针对不同编译器的构建矩阵、代码静态分析、制品以及智能触发器。所有示例均使用 C++ 和 CMake 给出。
1. 依赖缓存与加速构建
每次工作流程运行都始于一个干净的虚拟机。没有缓存,您将每次下载并构建相同的库(例如 Boost 或 Google Test)。解决方案是使用 GitHub Actions 内置的缓存功能。
name: C++ CI (高级)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