学习一下Github仓库的工作流语法,希望在Github仓库中自动执行测试。
重点关注两类项目所需要的基本测试工作流,分别是跨平台CMake项目和LaTex项目。
概述
Github仓库提供工作流来自动化执行应用的部署,测试和发布等流程。工作流的实质是在Github服务器上提供了几个临时的虚拟环境(Docker),让用户在提交或其他Git行为后触发工作流,然后在虚拟机环境中自动执行相关的指令。
例如,可以使用一个工作流来构建和测试拉取请求,使用另一个工作流在每次创建版本时部署应用程序,
还有另一个工作流程在每次有人打开新问题时添加标签。
注意:
- Github仓库支持多个工作流,它们可以同时触发或分别触发。
- Github对公开仓库提供的这类服务是无限制的,但是对私有仓库是受限的,每个月提供免费的时间额度和存储额度,超额需要付费。
- 如果在仓库中触发的一个工作流运行失败了,Github可能通过邮件通知。
一个典型的工作流(workflow)包含:
- 触发工作流的一个或多个事件
- 一个或多个作业(job),每个作业都将在运行器机器上执行并运行一系列的一个或多个步骤(step),每个步骤都可以运行指定的脚本或操作(action)
触发工作流的事件通常是:
- Git仓库中发生的事件,例如推送到默认分支时、创建版本时
- 定时触发或手动触发
- 其他Github支持的触发行为
工作流的配置文件是yaml
格式文件,存储在.github/workflows/
文件夹中,语法规则如下
示例如下
learn-github-actions.yml1 2 3 4 5 6 7 8 9 10 11 12 13
| name: learn-github-actions run-name: ${{ github.actor }} is learning GitHub Actions on: [push] jobs: check-bats-version: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '20' - run: npm install -g bats - run: bats -v
|
这个工作流会在代码推送事件发生时自动触发。它定义了一个名为
"check-bats-version" 的任务,将在最新的 Ubuntu
环境上运行,具体行为依次为:
- Checkout:将代码从你的仓库检出到运行环境中。
- Setup Node:指定 Node.js 的版本为20。
- Install Bats:使用 npm 全局安装 Bats,它是一个用于测试 Bash
脚本的测试框架。
- Run Bats:最后执行
bats -v
命令。这个命令用于显示系统中安装的 Bats 版本。
触发工作流
常见的工作流触发逻辑是推送到main或者release,以及合并请求时触发,例如
1 2 3 4 5
| on: push: branches: [ main, release/** ] pull_request: branches: [ main, release/** ]
|
有时我们只需要在某些路径或文件发生更改时,才触发工作流,例如
1 2 3 4 5 6
| on: push: branches: - 'main' paths: - 'src/utils/**'
|
这里同时使用了 branches 筛选器和 paths
筛选器,只在这两个筛选器都满足条件时触发工作流。
有时我们只需要在推送形如v1.**
的标签时,触发工作流,例如
1 2 3 4
| on: push: tags: - v1.**
|
有时我们只是进行文档的更新,可以使用下面的格式来避免对应的修改触发测试工作流
1 2 3 4 5 6
| on: push: paths-ignore: - 'doc/**' - 'docs/**' - '**.md'
|
Cpp 项目
CMake跨平台工作流
下面是Github官方推荐的,针对跨平台CMake项目,在最新系统的三大编译器环境中进行编译测试的工作流配置
(基于系统默认的编译器版本)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| name: CMake on multiple platforms
on: push: branches: [ "main" ] pull_request: branches: [ "main" ]
jobs: build: runs-on: ${{ matrix.os }}
strategy: fail-fast: false
matrix: os: [ubuntu-latest, windows-latest] build_type: [Release] c_compiler: [gcc, clang, cl] include: - os: windows-latest c_compiler: cl cpp_compiler: cl - os: ubuntu-latest c_compiler: gcc cpp_compiler: g++ - os: ubuntu-latest c_compiler: clang cpp_compiler: clang++ exclude: - os: windows-latest c_compiler: gcc - os: windows-latest c_compiler: clang - os: ubuntu-latest c_compiler: cl
steps: - uses: actions/checkout@v3
- name: Set reusable strings id: strings shell: bash run: | echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT"
- name: Configure CMake run: > cmake -B ${{ steps.strings.outputs.build-output-dir }} -DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }} -DCMAKE_C_COMPILER=${{ matrix.c_compiler }} -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -S ${{ github.workspace }}
- name: Build run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config ${{ matrix.build_type }}
- name: Test working-directory: ${{ steps.strings.outputs.build-output-dir }} run: ctest --build-config ${{ matrix.build_type }}
|
上面的就是默认提供的配置文件,其实啥也不用改,只是清理了注释,当然也可以修改一下触发条件。
这个配置模板使用了矩阵,看起来比较高级,但是缺点是并没有指定具体的编译器版本,始终使用的是系统默认版本,这也意味着不能使用C++20的部分特性。
CMake跨平台工作流(最新版)
下面提供的是基于最新版编译器(VS2022
,gcc13
和clang18
)的测试工作流(已经足够支持C++20的基础使用)
- pipeline-ci.yml,依次调用了三个具体的测试工作流
- bvt-msvc14.yml
- bvt-gcc13.yml
- bvt-clang18.yml
配置文件是参考微软的proxy库的,将编译器版本修改为最新版。 这里
pipeline-ci 指持续集成(Continuous
Integration)中的一个流水线(Pipeline),bvt 指基本验证测试(Basic
Verification Test)。
配置文件 pipeline-ci.yml 具体如下
pipeline-ci.yml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| name: Test-CI
on: push: branches: [ "main" ] paths: - 'src/**' - 'test/**' pull_request: branches: [ "main" ] paths: - 'src/**' - 'test/**'
env: BUILD_TYPE: Release
jobs: run-bvt-gcc13: uses: ./.github/workflows/bvt-gcc13.yml name: run bvt with g++ 13
run-bvt-clang15: uses: ./.github/workflows/bvt-clang18.yml name: run bvt with clang 18
run-bvt-msvc14: uses: ./.github/workflows/bvt-msvc14.yml name: run bvt with msvc14 (vs2022)
|
三个工作流是在不同编译器和环境下的基本测试,除了运行环境不同,以及预先下载配置指定的编译器,核心步骤都是一样的:生成,编译,进入构建目录,执行测试。
1 2 3 4 5 6 7 8 9
| - name: build with cmake run: | cmake . -B build cmake --build ./build -j8
- name: run tests run: | cd ./build ctest -j8
|
需要注意的是对于MSVC,在ctest时需要明确构建类型,添加-C Release
选项。
完整的工作流配置文件依次为
bvt-msvc14.yml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| name: bvt-msvc14
on: workflow_call: inputs: branch: type: string required: false
jobs: bvt-msvc14: runs-on: windows-2022 steps: - uses: actions/checkout@v3 with: ref: ${{ inputs.branch }}
- name: build with cmake run: | cmake . -B build cmake --build ./build -j8
- name: run tests run: | cd ./build ctest -j8 -C Release
|
bvt-gcc13.yml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| name: bvt-gcc13
on: workflow_call: inputs: branch: type: string required: false
jobs: bvt-gcc13: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 with: ref: ${{ inputs.branch }}
- name: install gcc 13 run: | sudo apt update sudo apt install -y gcc-13 g++-13 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 13 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 13
- name: check compiler version run: g++ --version
- name: build with cmake run: | cmake . -B build cmake --build ./build -j8
- name: run tests run: | cd ./build ctest -j8
|
bvt-clang18.yml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| name: bvt-clang18
on: workflow_call: inputs: branch: type: string required: false
jobs: bvt-clang18: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v3 with: ref: ${{ inputs.branch }}
- name: install clang 18 run: | wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - sudo apt-add-repository "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-18 main" -y sudo apt update sudo apt install -y clang-18 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/clang-18 18 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/clang++-18 18
- name: check compiler version run: g++ --version
- name: build with cmake run: | cmake . -B build cmake --build ./build -j8
- name: run tests run: | cd ./build ctest -j8
|
为了复用工作流,可以将上面的文件全部存放在某一个公开仓库中(fenglielie/cmakezero.git
),然后在其它仓库就可以直接调用它,只需要写一个test-ci.yml,例如
test-ci.yml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| name: Test-CI
on: push: branches: - 'main' paths: - 'src/utils/**' - 'test/utils/**'
env: BUILD_TYPE: Release
jobs: run-bvt-gcc13: uses: fenglielie/cmakezero/.github/workflows/bvt-gcc13.yml@main name: run bvt with g++ 13
run-bvt-clang15: uses: fenglielie/cmakezero/.github/workflows/bvt-clang18.yml@main name: run bvt with clang 18
run-bvt-msvc14: uses: fenglielie/cmakezero/.github/workflows/bvt-msvc14.yml@main name: run bvt with msvc14 (vs2022)
|
LaTeX 项目
编译测试
如果只需要保证LaTex项目可以顺利编译,可以参考下面的配置模板,这里使用XeLaTeX编译main.tex,并且设置工作目录为./latex/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| name: Build LaTeX document
on: push: branches: [ main, release/** ] pull_request: branches: [ main, release/** ]
jobs: build_release_latex: runs-on: ubuntu-latest
steps: - uses: actions/checkout@v3
- name: Compile LaTeX document uses: xu-cheng/latex-action@v2 with: working_directory: ./latex root_file: main.tex args: -pdf -xelatex -file-line-error -halt-on-error -interaction=nonstopmode
|
编译测试与发布
如果对LaTeX项目有更多的需求:
- 将编译生成的PDF文件保留在Git仓库的指定分支(gh_actions_builds)中
- 将编译生成的PDF文件添加到Release中
配置示例如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| name: Build and Release LaTeX document
on: push: branches: [ main ] tags: - 'v*' pull_request: branches: [ main ]
workflow_dispatch:
jobs: build_release_latex: runs-on: ubuntu-latest
steps: - uses: actions/checkout@v3
- name: Compile LaTeX document uses: xu-cheng/latex-action@v2 with: root_file: main.tex args: -pdf -xelatex -file-line-error -halt-on-error -interaction=nonstopmode
- name: Stash PDF run: | mv main.pdf $HOME # cache the file
- name: Create Branch uses: peterjgrainger/action-create-branch@v2.0.1 env: GITHUB_TOKEN: ${{ secrets.GH_LATEX_TEST_TOKEN }} with: branch: gh_actions_builds
- name: Checkout gh_actions_builds Branch uses: actions/checkout@v3 with: ref: gh_actions_builds
- name: Commit PDF run: | git config --local user.email "fenglielie@gmail.com" git config --local user.name "fenglielie" mv $HOME/main.pdf $(pwd) # bring it back git add -f main.pdf git commit -m "Updated by GitHub Action Automatically"
- name: Push PDF uses: ad-m/github-push-action@master with: branch: gh_actions_builds force: false github_token: ${{ secrets.GH_LATEX_TEST_TOKEN }}
- name: Release uses: softprops/action-gh-release@v1 if: startsWith(github.ref, 'refs/tags/') with: files: main.pdf env: GITHUB_TOKEN: ${{ secrets.GH_LATEX_TEST_TOKEN }}
|
注意:由于需要提交,这里需要配置用户名和邮箱,创建和切换分支,并且需要在Github中设置并提供一个GITHUB_TOKEN
,否则在虚拟环境中默认是没有权限对仓库进行任何修改操作的。