发布于 2026-01-06 0 阅读
0

GitHub Actions 工作流,极致懒人体验 DiffCpp

GitHub Actions 工作流,极致懒人必备

DiffCpp

目录


我的工作流程


工作流程背后的动机

我们都同意,作为人类,我们大多数时候都更喜欢懒惰。我们喜欢每天早上把闹钟多关五分钟,我们更喜欢给坐在隔壁房间的兄弟姐妹发短信,有时我们甚至懒得检查试卷就直接交卷。

除了懒惰之外,我们通常也很容易感到无聊,从工作中枯燥乏味的任务到在超市排队等候,都可能让我们感到厌倦。我们的大脑对过于可预测和重复的体验反应不佳。这种缺乏乐趣的感觉,就是我们所说的无聊
图片替代文字

这就是我们发明机器并改进整体自动化流程的原因。一切都是为了让一切变得更好,从提高生产力到打造更高效、更完美的产品。

在软件工程领域,我们也需要每天重复一些繁琐的任务来维护最终产品。这时,GitHub,更准确地说是GitHub Actions,就派上了用场,它能帮助我们自动化处理各种重复性任务,只需轻轻点击鼠标即可启动!是不是很厉害?准备好,你即将被它震撼!
图片替代文字


GitHub Actions 如何帮助了我?

让我以第三人称视角来讲述我的故事。Shehab 是一位开源爱好者,大约一年前创建了一个名为DiffCpp的 GitHub 代码库。目前,DiffCpp 已经拥有大量的用户、fork 和 star(虽然现在还不是这样,但希望不久的将来会是这样)。无论如何,这个 GitHub 代码库需要定期维护和更新才能保持活力。由于 Shehab 是个懒人,不喜欢做单调乏味的工作,他决定利用现有的GitHub Actions构建一个完美的流程,自动化所有必要的维护工作,以确保代码库在发布前不会出现任何损坏。

于是,他决定集思广益,列出完成这项工作所需的所有可能任务组合。他发现这些任务可以归纳为以下几类:

  • 文档

    • 检查代码库的 格式
    • 生成文档
      • 由于这是一个 C++ 项目,因此将使用Doxygen 。
    • 生成发行说明,以通知用户变更内容。
  • 测试

    • 检查构建是否成功,并在此基础上进行:
      • Linux(Ubuntu)
      • 视窗
    • 使用Google Test进行以下操作:
      • 单元测试:分别测试每个 API 的逻辑。
      • 块测试:测试整个软件包的逻辑。
    • 使用Google Benchmark检查软件包 API 的基准测试结果

显然,这工作量很大,但要谨慎!剧透预警!我只想告诉你,GitHub 不仅让我毫不费力地完成了之前列出的所有任务,还在流程结束时为我提供了这个漂亮的流程可视化图表。
可视化图


我是如何创建这个工作流程的?

为了简单起见,我们考虑以下场景。今天早上我醒来,喝了杯咖啡,然后查看我的 GitHub 帐户,发现有人在 DiffCpp 代码库中创建了一个 issue,其中提到了以下内容:

Input = 🔵
Expected Output = 🔴
Actual Output = ⚪
Enter fullscreen mode Exit fullscreen mode

这个问题需要立即解决。因此,我决定悬赏1000 万美元(真希望现实生活中我有这么多钱)奖励第一个解决这个问题的人。你可能觉得这样就能解决问题,但你有没有想过我每分钟会收到多少个 pull request? 除了数量之外,我甚至都没时间一个个检查,找出哪些解决了问题,这得花多少时间啊!多亏了 Google Test,我只需两行简单的代码就能添加一个新的测试:
图片替代文字

Output = Input(🔵);
EXPECT_EQ(Output, 🔴);
Enter fullscreen mode Exit fullscreen mode

所以,GitHub Actions(与 Google Test 合作)应运而生,解决了这个问题。我决定构建一个工作流,检查每个提交的拉取请求是否包含以下内容:

  1. 构建成功🔧

    YAML 代码片段(点击展开)
    build-linux:
      name: Linux
      runs-on: ubuntu-latest
      steps:
      - name: Checkout Repository
        uses: actions/checkout@v2
    
      - name: Build
        run: cmake .
    
      - name: Make
        run: make
    
      - name: Upload Linux Artifact
        uses: actions/upload-artifact@v2
        with:
          name: DiffCpp-Linux
          path: ./DiffCpp
    


    对于 Windows 构建,将使用 Windows 特有的 CMake 命令执行相同的步骤。

    已执行的操作:

  2. 代码格式化📝

    YAML 代码片段(点击展开)
    clang-format-check:
      name: Format Check
      runs-on: ubuntu-latest
      steps:
      - name: Checkout Repository
        uses: actions/checkout@v2
    
      - name: Check Codebase Format
        uses: RafikFarhad/clang-format-github-action@v1.0.1
        with:
          sources: "src/*.cpp,include/*.h,test/*.cpp"
    


    已执行的操作:

  3. 单元测试和模块测试📋

    YAML 代码片段(点击展开)
    verification:
      name: Unit and Block Testing
      needs:
        - build
      runs-on: ubuntu-latest
      steps:
      - name: Checkout Repository
        uses: actions/checkout@v2
    
      - name: Cache GoogleTest Package
        id: cached-gtest
        uses: actions/cache@v2
        env:
          cache-name: cache-gtest-repo
        with:
          path: googletest
          key: ${{ runner.os }}-build-${{ env.cache-name }}
    
      - name: Install GoogleTest
        if: steps.cached-gtest.outputs.cache-hit != 'true'
        run: mkdir googletest &&
             git clone https://github.com/google/googletest.git
    
      - name: Build
        run: cmake -DBUILD_TESTS=ON .
    
      - name: Make
        run: make
    
      - name: Run Unit Tests
        run: ./DiffCpp_tst
    


    已执行的操作:

    • actions/cache@v2用于缓存指定步骤的输出。这样,如果指定的操作之前已经执行过,GitHub 就可以跳过该操作。

    缓存

    注意:如果您使用除 GoogleTest 之外的任何验证方法,可以直接使用构建作业上传的工件并将其传递给此方法。GitHub 真棒,不是吗?总之,对于 C++ 项目,GoogleTest 是完美的验证工具。您甚至可以从 GitHub Actions 日志中查看测试结果,如下所示👇

    GoogleTest

当这些检查成功通过时,以下内容将显示在拉取请求本身中,以便于直接合并。
拉取请求检查

此外,您还可以欣赏一下这个流程的精美可视化图,它展示了代码审查的完整流程👇
拉取请求管道

我们还没完呢!此外,GitHub 还能在有人提交有效的 pull request 解决问题时通知我。这样,我就可以轻松地检查数百万个 pull request 了。

通知

好了,现在该发布版本了,但我又没心情也没精力去做其他工作(好像我之前做过什么似的)。所以,我决定在之前那个工作流程的基础上,再建一个新工作流程,负责从头到尾生成版本,而且只需点击一下鼠标就能触发。

图片替代文字

首先,我的策略将基于 DRY(Don't Repeat Yourself,不要重复自己)原则。因此,我决定使用可复用工作流。没错!它正如你所读到的那样令人着迷,GitHub 刚刚推出了工作流复用的新功能,非常感谢@blackgirlbytes撰写了关于该功能的精彩博文。

因此,我需要添加以下任务:

  1. 为代码库生成文档📜

    YAML 代码片段(点击展开)
    doxygen-doc:
      environment:
        name: Doxygen Documentation
        url: https://shehab7osny.github.io/DiffCpp/include/
      name: Generate Documentation
      needs:
        - codebase
      runs-on: ubuntu-latest
      steps:
      - name: Checkout Repository
        uses: actions/checkout@v2
    
      - name: Run Doxygen
        uses: mattnotmitt/doxygen-action@v1
        with:
            working-directory: 'include/'
    
      - name: Deploy to GitHub Pages
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./include/html
          destination_dir: ./include
    


    已执行的操作:

    这里指定的环境包含一个 Doxygen 输出的 URL,该 URL 会直接显示在工作流可视化图中。

    URL 文档

    这项工作只有一个依赖项代码库格式化

    生成的 URL 将包含如下详细的代码文档:

    Doxygen 文档

  2. 计算基准测试📈 对于那些不了解的人来说,基准测试是指衡量某个程序随时间推移的性能。
    图片替代文字

    YAML 代码片段(点击展开)
    benchmarking:
      environment:
        name: Benchmark Results
        url: https://shehab7osny.github.io/DiffCpp/dev/bench
      name: Benchmark (Performance)
      needs:
        - verification
      runs-on: ubuntu-latest
      steps:
      - name: Checkout Repository
        uses: actions/checkout@v2
    
      - name: Cache Google Benchmark Package
        id: cached-benchmark
        uses: actions/cache@v2
        env:
          cache-name: cache-gbench-repo
        with:
          path: benchmark
          key: ${{ runner.os }}-build-${{ env.cache-name }}
    
      - name: Install Google Benchmark
        if: steps.cached-benchmark.outputs.cache-hit != 'true'
        run: mkdir benchmark &&
            git clone https://github.com/google/benchmark.git benchmark
    
      - name: Build
        run: cmake -DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON -DCMAKE_BUILD_TYPE=Release -DBUILD_BENCH=ON .
    
      - name: Make
        run: make
    
      - name: Run Benchmark
        run: ls && ./DiffCpp_BENCH --benchmark_format=json | tee benchmark_result.json
    
      - name: Store benchmark result
        uses: benchmark-action/github-action-benchmark@v1
        with:
          tool: 'googlecpp'
          output-file-path: benchmark_result.json
          github-token: ${{ secrets.GITHUB_TOKEN }}
          fail-on-alert: true
          comment-on-alert: true
          auto-push: true
    


    已执行的操作:

  3. 此工作只有一个依赖项➡️验证

    生成的 URL 将包含如下基准测试图表:

    基准

  4. 创建新版本(附带版本说明)📭

    YAML 代码片段(点击展开)
    release-project:
      name: Release Project
      needs:
        - benchmarking
        - doxygen-doc
      runs-on: ubuntu-latest
      steps:
      - name: Download Linux Artifact
        uses: actions/download-artifact@v2
        with:
          name: DiffCpp-Linux
    
      - name: Download Windows Artifact
        uses: actions/download-artifact@v2
        with:
          name: DiffCpp-Windows
    
      - name: Create GitHub Release
        id: create-new-release
        uses: actions/github-script@v4.0.2
        with:
          github-token: ${{secrets.GITHUB_TOKEN}}
          script: |
            await github.request(`POST /repos/${{ github.repository }}/releases`, {
              tag_name: "${{ github.event.inputs.release_ver }}",
              generate_release_notes: true
            });
    


    已执行的操作:

    这项工作有两个依赖项
    :➡️基准测试
    ➡️ doxygen-doc

    如果您是第一次使用自动生成发布说明功能,不妨看看@mishmanners制作的这段精彩视频,非常感谢她。总之,我决定将这项功能提升到一个新的层次,并将其集成到自动化操作中。所以,我实际上是在自动化一个自动化任务!

    以下是自动生成的发行说明的截图:

    发行说明

    此外,构建好的工件将可供下载(Linux 和 Windows 版本均适用)。

    文物

最后,完成所有这些任务后,我们可以看看这张精美的管道可视化图,它展示了完整的发布流程👇
可视化图


提交类别:

维护人员必备技能

总之,我想指出的是,将这种工作流程与懒惰联系起来仅仅是为了便于说明。然而,在现实生活中,开发人员通常会避免这类单调乏味的任务,以便专注于开发本身,而不是处理大量的验证和发布工作。因此,在我看来,在任何项目中使用这种工作流程都是必要的,它能帮助开发人员更专注于为项目引入新功能,同时确保代码库不会出现问题。


YAML 文件或代码链接

这是 DiffCpp 代码库

GitHub 标志 Shehab7osny / DiffCpp

用 C++ 实现的适用于 Windows/Linux 的差异比较工具

构建状态 构建状态 覆盖范围 许可证:MIT

DiffCpp

该软件包用于逐行比较两个文件并显示差异。

建造和安装

Linux

mkdir build
cd build
cmake ..
make

视窗

mkdir build
cd build
cmake ..
cmake --build .
cd Debug/

用法

Linux

./DiffCpp File_1_Path File_2_Path [/N] [/A] [/W]

视窗

DiffCpp File_1_Path File_2_Path [/N] [/A] [/W]

主要论点

争论 描述
文件1路径 这代表文件的旧版本。
文件路径 这代表文件的新版本。

可选参数

争论 描述
/N 可选择在显示的输出中添加行号
/一个 可以选择仅显示更新内容并忽略重复项
/W 比较文件时可以选择忽略空格差异

示例用例

文件 1 (recursion_Old.py)

def tri_recursion(k):
  if(k > 0):
    result = k + tri_recursion(k - 1)
  else:
    result = 1
  return result
Enter fullscreen mode Exit fullscreen mode

文件 2 (recursion_New.py)

def tri_recursion(
Enter fullscreen mode Exit fullscreen mode

其他资源

文章来源:https://dev.to/shehab7osny/github-actions-workflow-for-ultimate-laziness-af5