34-GitHub与CI自动化GitHubCI

34 · GitHub 与 CI 自动化(GitHub Actions Pipeline)

本节目标(Goals):把项目推到 GitHub,用 Actions 在三大 OS 上自动构建/测试/打包,并学会打 tag 发 Release。
前置知识(Prerequisites):教程 04(Git 基础)、32(ctest)、33(cpack)、01(GitHub 账号)。


1. 先让仓库上云

教程 04 的本地仓库推到 GitHub:

cd ~/Projects/Vicarus
git remote add origin git@github.com:<你的用户名>/vicarus.git
git push -u origin main

顺带在 .gitignore 补齐两款产物,别把 build 垃圾推上去:

build/
dist/
*.user

2. CI 文件 .github/workflows/ci.yml

目标是"一次 push → 三个 OS 构建 + 测试 + 打包"。

name: CI
on:
  push:
    branches: [ main ]
  pull_request:

jobs:
  build:
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4

      - name: Install Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'

      - name: Install deps (Linux)
        if: runner.os == 'Linux'
        run: sudo apt-get update && sudo apt-get install -y libncurses-dev

      - name: Install deps (macOS)
        if: runner.os == 'macOS'
        run: brew install ncurses

      - name: Configure
        run: cmake -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=ON

      - name: Build
        run: cmake --build build --config Release

      - name: Test
        run: ctest --test-dir build --output-on-failure

      - name: Package
        if: runner.os == 'Linux'
        run: cmake --build build --config Release --target package

      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: vicarus-${{ matrix.os }}
          path: |
            build/vicarus
            dist/*

  release:
    needs: build
    if: startsWith(github.ref, 'refs/tags/')
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/download-artifact@v4
      - uses: softprops/action-gh-release@v2
        with:
          files: |
            vicarus-*/vicarus-*.tar.gz
            vicarus-*/vicarus-*.deb

关键行解释:

部分 作用
strategy.matrix 三平台并跑,fail-fast: false 表示一个平台失败不影响另两个出结果
setup-python 保证 find_package(Python3 Development) 可用(教程 25 的可选依赖)
if: runner.os == ... 平台专用依赖安装,只在对应 runner 上执行
target package 调出 CPack 的 package 目标(教程 33)
upload-artifact 把二进制/归档从 runner 机带回工作流
release job 仅当 push 的是 tag 触发,自动挂附件发 Release

教程 31 说的"把修好的跨平台问题沉淀成 CI 矩阵作业"——就是这份文件。


3. 打 tag 发 Release

版本发布流程(版本号单一来源=根 CMakeLists 的 project(Vicarus VERSION ...)):

# 1. 有人改了代码,CI 绿,提交版本号 bump(单一来源)
git commit -am "Bump version to 0.1.0"
git push

# 2. 打 tag 并推送 → release job 自动跑
git tag v0.1.0
git push origin v0.1.0

# 3. 等手段完成后,页面出现 Release + 三平台产物附件

用 gh 验证与手动接管:

gh release list
gh release view v0.1.0 --json assets -q '.assets[].name'

4. 状态徽章贴进 README

# Vicarus

[![CI](https://github.com/<你>/vicarus/actions/workflows/ci.yml/badge.svg)](https://github.com/<你>/vicarus/actions/workflows/ci.yml)
[![GitHub release](https://img.shields.io/github/v/release/<你>/vicarus)](https://github.com/<你>/vicarus/releases)

绿勾/红叉一目了然,协作时省掉"你先自己跑一下"的来回。


5. 让 CI 真正"守门"

  • 分支保护:Settings → Branches → 默认分支要求 ci.yml 的 build job 通过;
  • PR 也跑:on: pull_request 已含——prevent 合并前不看 CI;
  • 性能守卫:把教程 30 的 bench/bench_search 作为第五个 step 跑,附 console 输出,防搜索性能回归;
  • 失败排查姿势:ctest --output-on-failure 已在 workflow 里,点开 Action 日志直接看失败用例。

本节小结(Summary)

  • CI = 一处 push,三点护航(构建/测试/打包 × 三 OS),释放人力做真正的事;
  • matrix + 条件 step 是跨平台 CI 的骨架;release job 用 tag 触发自动挂产物;
  • 版本号单一来源、README 徽章、分支保护,让"持续集成"变成"持续可信";
  • 教程 32/33 的工具(ctest/cpack)在 CI 里自动跑,本地那套即刻原子化。

动手练习(Exercise)

  1. 在你的 GitHub 建 vicarus 仓库,按第 1 节推送,首次运行 CI 并截图你的第一个绿勾;
  2. 加一个 bench step(gist: cmake --build build --target bench-search 后 ./build/bench/bench-search)输出到 Actions 日志;
  3. 写一个有意的回归(比如给 replace_all 下标短路)推上去,看 CI 挂掉→修复→再绿,体会"守门";
  4. 挑战:用 GH API 在 CI 里自动读 PROJECT_VERSION 而不用手写 tag,实现"push tag 即发布"的完全自动化。

下一节 35-项目总结与展望FinalReview.md:站到山顶回看 Vicarus 的 36 节旅程。

posted @ 2026-09-08 13:51  IcarusLee  阅读(21)  评论(0)    收藏  举报