65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 GitHub Actions 编写 CI 管道来构建 C++ 项目

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.50/5 (7投票s)

2020年4月20日

CPOL

8分钟阅读

viewsIcon

25130

本文提供了使用 GitHub Actions 自动化 CI 管道来构建使用 CMake 配置的 C++ 项目的实践概述。

关于 GitHub Actions

GitHub Actions(发布日期为 2019 年 11 月 13 日,算不上非常古老)因其易用性、灵活的工作流定制以及对支持所有操作系统的无数编程语言的广泛支持而获得了巨大的社区关注。其宣传语“从想法到生产”就足以说明一切。简单来说,您可以将 GitHub Actions 理解为 GitHub 内置和维护的集成 API,可与您的 GitHub 存储库配合使用。它允许您直接从存储库自动化您的工作流,这些工作流基于不同的事件触发,例如发布时、推送时、拉取时等。GitHub 以一种易于维护的方式管理您的工作流文件(我稍后会解释工作流文件),提供清晰多彩的错误和警告日志,为每个步骤提供丰富的反馈,并保存与相关工作流文件相关的历史记录等。

如果您要编写 CI/CD 管道,GitHub Actions 是一个相当不错的选择,其基本思想是您可以使用工作流文件直接从您的 git 文件夹构建、测试和部署代码。工作流文件是 CI/CD 管道的逻辑/物理表示,它是 GitHub Actions 的核心组成部分。要让 GitHub Actions 发挥作用,您的主存储库中 .github/workflows 目录中至少需要有一个工作流文件。此工作流必须以 YAML 格式编写,并以 .yml.yaml 文件扩展名保存。工作流文件包含根据您的项目类型和依赖项定制的自动化进程。

如前所述,工作流文件中编写的进程会在期望的事件发生时触发。例如,在拉取请求时,首先需要安装依赖项、构建项目、运行一些测试,只有在所有这些检查成功执行后,拉取请求才会被标记为成功。

关于本文

关于 GitHub Actions 的介绍就到这里。如果您现在已经确信可以使用 GitHub Actions 来自动化您的构建管道,那么请继续阅读本文,我将构建一个 C++ 示例项目来演示如何使用 GitHub Actions 自动化您的构建管道。这次演示可以让您了解实际操作过程;然而,除非您亲自尝试自动化不同技术栈上的各种工作流,否则您不会真正熟悉 GitHub Actions。要了解您的工作流如何工作并帮助您构建 CI/CD 管道,请参考此官方指南 – “关于 GitHub Actions”。

项目结构

演示项目是一个简单的“Hello World”C++ 程序,使用 CMake 配置。我将项目保持简单,因为本文的重点是编写工作流文件,而不是让您头疼如何使用 CMake 构建复杂的 C++ 项目。为此,我在 GitHub 上找到了以下存储库。我们先克隆它:Hello World

 

等等,如果您对 C++ 的 CMake 工具不太熟悉,但又要使用它来构建您的 C++ 项目,最好仔细阅读其官方文档 [参考]。

您将使用 Git 版本控制来下载和设置源代码

$ git clone https://github.com/Iiqra/HelloWorldCmakeSample.git
$ cd cmake-hello-world/
$ mkdir build
$ cd build
$ cmake ..

它应该像下面的截图一样成功运行

图 1:配置 CMake 文件

克隆存储库(简单的 Hello World 程序)后,我创建了一个专用文件夹来存放所有构建的文件(在此示例中,这一步不是特别必要。但是,对于大型项目,这是始终推荐的做法)。在 build 文件夹中,我执行了 CMake 命令来生成构建文件,如上图最后三行所示,表明项目文件的配置、生成和构建已成功完成。

因此,我们的构建文件包含一个解决方案文件(.sln),用于构建项目并生成项目二进制文件。我将使用 MSBuild 来构建解决方案,因为我使用的是 Windows VM(您可以在下面的两张图片中看到此构建命令)。您可以根据您的偏好和操作系统使用任何替代方案。

$ ls 
$ msbuild.exe CMakeHelloWorld.sln 
$ cd debug 
$ ./CMakeHelloWorld.exe

现在解决方案已构建完成,我们可以在 debug 文件夹或 release 文件夹中找到二进制文件,具体取决于我们的构建配置。如下图所示,我已经执行了 CMakeHelloWorld.exe 文件,该文件打印出高亮显示的输出消息。然而,提示信息尚未生效,因为提到的依赖项已被注释掉,以便手动执行可执行文件 [图 5]。

图 2:运行可执行文件
cmake_minimum_required (VERSION 2.8)
project (CMakeHelloWorld)

#version number
set (CMakeHelloWorld_VERSION_MAJOR 1)
set (CMakeHelloWorld_VERSION_MINOR 0)

#find dependencies
#find_package(cppzmq REQUIRED)


#include the subdirectory containing our libs
add_subdirectory (Hello)
include_directories(Hello)
#indicate the entry point for the executable
add_executable (CMakeHelloWorld Hello HelloWorld.cpp)

# Indicate which libraries to include during the link process.
target_link_libraries (CMakeHelloWorld Hello)

install (TARGETS CMakeHelloWorld DESTINATION bin)

注释掉此依赖项的原因是 cppzmq 将使用 vcpkg 安装,并且安装过程需要一些时间。因此,最好将此步骤作为 CI 管道的一部分。

编写工作流文件

到目前为止,您已经了解了项目结构,并且还看到了如何手动构建它(不包括安装 vcpkg 依赖项的步骤,这当然最好直接从工作流文件中编写的命令中安装)。因此,您应该能够理解以下工作流文件中描述的概念。

name: CI
# Workflow file for windows
on:
  push:
    branches:
      - master
  pull_request: {}

jobs:
  Windows:
    name: build-windows
    runs-on: [self-hosted, windows]

    steps:
    - name: Checkout
      uses: actions/checkout@v1
      with:
          submodules: recursive

    - name: Installing vcpkg (windows)
      run: |
        cd ..
        git clone https://github.com/Microsoft/vcpkg.git
        cd vcpkg
        git checkout --force 2020.01
        .\bootstrap-vcpkg.bat
        .\vcpkg.exe install cppzmq:x64-windows

    - name: Running cmake (windows)
      run: |
        cd ${{ github.workspace }}
        mkdir build
        cd build
        cmake .. -DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}
                  /../vcpkg/scripts/buildsystems/vcpkg.cmake

    - name: Build Solution (windows)
      run: |
        cd build
        MSBuild.exe CMakeHelloWorld.sln

本文无意详细解释上述工作流文件。我建议为此目的查阅官方文档。但是,为了完整起见,我最好只描述主要步骤。

首先是我的工作流的名称,在本例中为 CI。然后是事件,我设置了“push(在 master 分支上)”作为此工作流将触发的主要事件,也可以设置多个事件,例如 [push, pull_request]。这样,每当从此存储库的 master 分支推送内容时,下面的 build-windows 作业将开始执行。

接下来,我们需要运行作业的机器类型。如果您选择使用 GitHub 托管的 runner,您的作业每次都会在一个新的虚拟机实例上运行;否则,您也可以选择在自托管 runner 上运行您的作业。GitHub runner 提供的标签是 windows -latestubuntu-latest 等。对于自托管 runner,我们使用“self-hosted”作为标签。此外,我们还可以使用标签数组,就像我的情况一样 – self-hosted, windows。

然后是核心组件——steps。Steps 是作业中的顺序任务,类似于执行不同操作的不同命令。Step 有一些属性,如 name、uses 子句和 run 命令。请详细阅读关于 Step 的信息,请参阅 Job Steps

所有步骤都具有说明性。我正在安装 vcpkg(从其 git 存储库克隆后)来安装依赖项,即提供的 CMake 文件中的 cppzmq。然后,我执行了文章前半部分手动执行的所有步骤:配置 CMake、构建解决方案文件,然后运行可执行文件。

现在是时候通过触发我们设置的作业的事件来触发这个工作流了,即 push 事件。

图 3:向 GitHub 存储库推送更改

需要进行修改才能触发推送事件,为此,我添加了注释(参见图 7)。现在切换到您存储库的 Actions 选项卡,并查看您最近一次提交的操作。

图 4:工作流文件视图

操作窗口看起来是这样的;第一次提交失败了,因为在第一次提交时没有 runner 在运行。然而,在 .github/ workflow 文件夹中存在一个带有 push event.yaml 文件,该文件最终在我们的第一次提交时被触发。但是,第二次提交“Added comment in the CI file”已成功执行并通过。在 Actions 的控制台窗口中,您可以查看所有步骤的彩色日志以及您编写的每个命令的详细信息。

下面的屏幕截图显示了工作流控制台窗口,并且具有很好的说明性;每个步骤都已成功执行,并附有其详细的构建输出。此外,您可以通过在此处的存储库 Actions 选项卡访问此控制台文件,以获取更多详细信息和深入了解步骤。

图 5:展开的 vcpkg 日志显示在控制台窗口

总结

在总结之前,有两点您必须了解

  1. 如果您想从您的计算机运行 runner 并让工作流文件在您的存储库中运行,您需要成为存储库的所有者。因此,请确保在克隆我的存储库作为起点后,您可以在您自己的个人存储库中再次执行 init-add-commit-push,然后在您自己的计算机上启动 runner [设置 Runner]。
  2. GitHub marketplace 中有许多现成的、经过测试的操作,可以帮助您在自动化工作流时完成大多数任务,例如 run-cmake actionrun-vcpkg action。然而,为了让您全面了解 GitHub Actions 的功能,我更倾向于编写原始命令而不是使用这些包。

总而言之,我们已经了解了 GitHub Actions 的基础知识。我们编写了一个工作流文件来自动化我们的管道,以构建一个使用 CMake 设置配置的简单 C++ 程序。此外,我们还观察了存储库 Actions 选项卡上工作流文件的执行情况,以了解如何表示构建日志和步骤。

历史

  • 2020 年 4 月 20 日:初始版本
© . All rights reserved.