name: CI on: push: branches: [master] pull_request: branches: [master] env: CMAKE_BUILD_PARALLEL_LEVEL: 0 CCACHE_DIR: ${{ github.workspace }}/.ccache CCACHE_MAXSIZE: 256M jobs: # ── 动态矩阵 ────────────────────────────────────────────── # PR 仅跑 Ubuntu 节省 minutes;push master 跑全矩阵 Ubuntu + Windows matrix: name: Determine matrix runs-on: ubuntu-24.04 outputs: os: ${{ steps.set-matrix.outputs.os }} steps: - id: set-matrix shell: bash run: | if [ "${{ github.event_name }}" = "push" ] && [ "${{ github.ref }}" = "refs/heads/master" ]; then echo "os=[\"ubuntu-24.04\",\"windows-2025\"]" >> "$GITHUB_OUTPUT" else echo "os=[\"ubuntu-24.04\"]" >> "$GITHUB_OUTPUT" fi # ── 构建 & 测试 ─────────────────────────────────────────── build: name: ${{ matrix.os }} / ${{ matrix.build_type }} needs: matrix strategy: fail-fast: false matrix: os: ${{ fromJSON(needs.matrix.outputs.os) }} build_type: [Release] runs-on: ${{ matrix.os }} steps: # ── 1. 源码检出 ────────────────────────────────────── - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 1 # ── 2. 平台编译工具链 ───────────────────────────────── # Ubuntu: clang-18 + Ninja + ccache - name: Install toolchain (Ubuntu) if: runner.os == 'Linux' run: | sudo apt-get update -qq sudo apt-get install -y -qq clang-18 ninja-build ccache echo "CC=clang-18" >> $GITHUB_ENV echo "CXX=clang++-18" >> $GITHUB_ENV # Windows: LLVM (clang-cl) + Ninja + ccache - name: Install toolchain (Windows) if: runner.os == 'Windows' shell: bash run: | choco install -y llvm ninja ccache --no-progress 2>/dev/null || true # Add clang-cl to PATH (both possible locations) # Prefer choco-installed LLVM; fall back to VS-bundled clang-cl if [ -d "/c/Program Files/LLVM/bin" ]; then echo "/c/Program Files/LLVM/bin" >> $GITHUB_PATH elif [ -d "/c/Program Files/Microsoft Visual Studio/2026/Enterprise/VC/Tools/Llvm/x64/bin" ]; then echo "/c/Program Files/Microsoft Visual Studio/2026/Enterprise/VC/Tools/Llvm/x64/bin" >> $GITHUB_PATH elif [ -d "/c/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Tools/Llvm/x64/bin" ]; then echo "/c/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Tools/Llvm/x64/bin" >> $GITHUB_PATH fi echo "CC=clang-cl" >> $GITHUB_ENV echo "CXX=clang-cl" >> $GITHUB_ENV # ── 3. ccache 缓存恢复 ──────────────────────────────── - name: Cache ccache uses: actions/cache@v4 with: path: ${{ env.CCACHE_DIR }} key: ${{ runner.os }}-ccache-${{ matrix.build_type }}-${{ github.run_id }} restore-keys: | ${{ runner.os }}-ccache-${{ matrix.build_type }}- ${{ runner.os }}-ccache- # ── 4. Python + Conan ───────────────────────────────── - name: Setup Python uses: actions/setup-python@v5 with: python-version: '3.12' - name: Install Conan run: pip install conan # ── 5. Conan 依赖缓存 ───────────────────────────────── - name: Cache Conan uses: actions/cache@v4 with: path: | ~/.conan2 ~/.conan2/p key: ${{ runner.os }}-conan-${{ matrix.build_type }}-${{ hashFiles('deps/conanfile.txt') }} restore-keys: | ${{ runner.os }}-conan-${{ matrix.build_type }}- ${{ runner.os }}-conan- # ── 6. Conan 依赖安装 ───────────────────────────────── - name: Install Conan dependencies shell: bash run: | conan profile detect --force conan install deps --build=missing -s build_type=${{ matrix.build_type }} # ── 7. CMake 配置 ───────────────────────────────────── - name: Configure CMake shell: bash run: | cmake --preset ci-release \ -DCMAKE_C_COMPILER_LAUNCHER=ccache \ -DCMAKE_CXX_COMPILER_LAUNCHER=ccache # ── 8. 构建(含计时) ───────────────────────────────── - name: Build id: build shell: bash run: | echo "::group::Build (${{ matrix.os }})" START_NS=$(date +%s%N 2>/dev/null || echo 0) START_S=$(date +%s) cmake --build --preset ci-release --config ${{ matrix.build_type }} END_S=$(date +%s) END_NS=$(date +%s%N 2>/dev/null || echo 0) DURATION=$((END_S - START_S)) echo "::endgroup::" echo "duration=${DURATION}" >> $GITHUB_OUTPUT echo "Build wall time: ${DURATION}s" # ── 9. ccache 统计 ──────────────────────────────────── - name: ccache stats if: always() shell: bash run: | ccache -s || echo "ccache stats unavailable" ccache -z || true # ── 10. 测试 ────────────────────────────────────────── - name: Test shell: bash run: ctest --preset ci-release -C ${{ matrix.build_type }} --output-on-failure # ── 11. 构建时间摘要 ────────────────────────────────── - name: Build time summary if: always() shell: bash run: | DURATION="${{ steps.build.outputs.duration }}" echo "| Platform | Compiler | Build Time |" >> $GITHUB_STEP_SUMMARY echo "|----------|----------|-----------|" >> $GITHUB_STEP_SUMMARY echo "| ${{ matrix.os }} | ${{ (runner.os == 'Linux' && 'clang-18') || 'clang-cl' }} | ${DURATION}s |" >> $GITHUB_STEP_SUMMARY echo "CI build: ${{ matrix.os }} / ${{ (runner.os == 'Linux' && 'clang-18') || 'clang-cl' }} wall time ${DURATION}s" # ── Sanitizer (PR-only, Linux clang-18, no ccache) ─────── sanitize: name: Sanitizer (ASan+UBSan) / ubuntu-24.04 if: github.event_name == 'pull_request' runs-on: ubuntu-24.04 steps: # ── 1. 源码检出 ────────────────────────────────────── - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 1 # ── 2. 工具链 (clang-18) ───────────────────────────── - name: Install toolchain (Ubuntu) run: | sudo apt-get update -qq sudo apt-get install -y -qq clang-18 ninja-build echo "CC=clang-18" >> $GITHUB_ENV echo "CXX=clang++-18" >> $GITHUB_ENV # ── 3. Python + Conan ───────────────────────────────── - name: Setup Python uses: actions/setup-python@v5 with: python-version: '3.12' - name: Install Conan run: pip install conan # ── 4. Conan 依赖缓存 ───────────────────────────────── - name: Cache Conan uses: actions/cache@v4 with: path: | ~/.conan2 ~/.conan2/p key: ${{ runner.os }}-conan-Release-${{ hashFiles('deps/conanfile.txt') }} restore-keys: | ${{ runner.os }}-conan-Release- ${{ runner.os }}-conan- # ── 5. Conan 依赖安装 ───────────────────────────────── - name: Install Conan dependencies shell: bash run: | conan profile detect --force conan install deps --build=missing -s build_type=Release # ── 6. CMake 配置 ───────────────────────────────────── - name: Configure CMake (Sanitizer) shell: bash run: cmake --preset ci-sanitize # ── 7. 构建 ─────────────────────────────────────────── - name: Build (Sanitizer) shell: bash run: cmake --build --preset ci-sanitize # ── 8. 测试 ────────────────────────────────────────── - name: Test (Sanitizer) shell: bash run: ctest --preset ci-sanitize --output-on-failure