使用GitHub Actions构建CI/CD流程

GitHub Actions 简介

GitHub Actions 是一种自动化软件开发工作流的方式,与 GitHub.com 深度集成。开发人员可以通过配置 GitHub Actions 来实现基于事件触发的自动工作流,比如,当有任意用户向 master 分支提交代码时,自动执行一遍完整的单元测试流程等。在本文中,我们展示如何通过配置 GitHub Actions 实现 CI/CD 流程。

来自 GitHub Docs 的插图,展示了 GitHub Actions 是基于事件(Event)触发的自动化工作流的抽象

CI/CD,即持续集成(Continuous Integration)持续部署(Continuous Deployment)持续交付(Continuous Delivery),是一种更好地交付高质量软件的工作流程。尤其对于个人和小型开发者而言,从项目初期开始即注重软件的交付方式和质量,对于提升开发者本身以及用户的体验而言帮助甚大。

Why not Jenkins:基于一般习惯,我们可能更愿意使用 Jenkins 等工具协助搭建 CI/CD 流程。但在使用体验 GitHub Actions 的过程中,我们发现无论是从配置文件的简明程度以及部署和使用的易用性来说,我们更愿意推荐 GitHub Actions 作为在 GitHub.com 上托管项目的 CI/CD 框架。

明确需求

本文中,我们计划使用 GitHub Actions 搭建具有如下特性的自动工作流程:

  • 在每个分支提交代码时,均对代码执行一遍预先定义好的单元测试
  • 提供一个"发布到"按钮,以将主分支(master)上的代码部署到测试/生产环境
  • 代码部署在本地私有服务器(而非 GitHub.com 上的服务器)执行

我们的示例代码位于:https://github.com/DGideas/github-actions-cicd-example

.github/workflows

要使用 GitHub Actions,我们需要在项目的 .github/workflows 文件夹中通过添加描述文件的方式定义相关的工作流程。GitHub Actions 使用 .yaml 格式的描述文件。简言之,每个工作流程通过如下方式进行描述:

  • 在何时触发?
    • 每当有代码提交时(push)、新的 Pull Request 创建时(pull_request)、当其他用户星标项目时(star),或者单纯是每隔一段时间(schedule)等
    • 完整的可供触发的时间列表可以在这里看到
  • 在哪里执行?
    • 是在 GitHub.com 提供的临时虚拟环境里执行,还是在自己本地的私有服务器上执行代码
  • 做什么事情?
    • 通过 .yaml 描述文件的方式,指示当任意事件发生时要完成的事情是什么:运行单元测试,或者给某个邮箱发一封电子邮件

比如,在任意用户为项目提交代码时,一个基于 Python 的项目的自动执行单元测试配置可能是这样的:

yaml 复制代码
name: CI
on: push

jobs:
  ci:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repo
        run: |
          rm -rf ${{github.event.repository.name}}
          git clone https://${{github.repository_owner}}:${{github.token}}@github.com/${{github.repository}}
          git -C "${{github.workspace}}/${{github.event.repository.name}}" checkout ${{github.ref}}
      - name: Python unittest
        run: |
          python3 -m venv venv
          source venv/bin/activate
          cd ${{github.event.repository.name}}
          pip3 install -r requirements.txt
          pre-commit run -a
          python3 -m unittest discover -v
      - name: Cleanup
        run: |
          rm -rf venv
          rm -rf ${{github.event.repository.name}}

我们将上述文件提交到项目 .github/workflows/ci.yml 中。

在上述示例中,每当用户向项目的任意分支推送代码时,GitHub Actions 会创建一个运行最新稳定发行版的 Ubuntu 系统的虚拟机,然后在其上运行我们预定义好的操作:检出(checkout)代码、运行单元测试并进行清理操作。清理操作不是必要的,因为由 GitHub.com 托管的虚拟机会在每次执行完任务后自动销毁,但是如果我们在自己托管的本地服务器上运行代码,则每次执行完毕后的清理是有必要的。

配置好 GitHub Actions 后,每个提交后都会附带 GitHub Actions 脚本的执行状态

点击 "Details" 按钮,还可以看到定义的工作流的具体执行情况:

GitHub Actions 页面显示每一次工作流的具体执行情况。如果某个提交为单元测试带来了问题,则可以从这个页面看到具体发生的问题

GitHub Actions 通过获取执行命令的返回值来判断任务是否成功,特别地,在执行命令期间,GitHub Actions 会设置一系列系统环境变量(如 CI),一些开发组件可能依赖这些环境变量,以执行不同的行为。

GitHub Actions 接受的完整配置文件语法请见此处

自己托管主机

在上述示例中,我们使用了来自 GitHub.com 托管的执行器执行 GitHub Actions,但在诸如"将代码发布到服务器"这种场景中,我们需要在自己的主机上执行相应代码。这需要我们将自己的主机添加到 GitHub Actions 中:

  1. 在项目"设置"(Settings)中,点选左侧"Actions",然后选择"Runners"
  2. 点击右上角的"New self-hosted runner",然后选择操作系统,按照提示安装 GitHub Actions Runner 到本地服务器上
  3. 安装过程中,我们需要为本地服务器上的 Runner 进行命名,并添加一系列可选的标签(Labels)。这些标签描述了一组具有相似特征的服务器(如生产环境服务器集群)。

对上述示例(ci.yml)中的配置文件稍作修改,我们即可在自己托管的服务器集群上运行单元测试用例:

yaml 复制代码
# ...
jobs:
  ci:
    strategy:
      matrix:
        servers: [ubuntu-latest, macos-latest]
    runs-on: ${{matrix.servers}}
    steps:
# ...

我们使用 matrix 配置项指示上述 Actions 将在多个服务器上同时执行。这些自我托管的服务器可能安装有不同的操作系统,或具有不同的软件环境,以在多种不同的系统环境下运行单元测试代码。

来自 GitHub.com 的一张截图,展示了在多个主机上同时执行脚本的方法

接收用户输入

有时我们需要用户主动触发一个脚本,并输入一些执行关键信息。比如,用户可能需要将某个特定分支的代码部署到指定服务器上。我们可以通过 inputs 配置项创建输入表单:

yaml 复制代码
name: 线上部署代码
on:
  workflow_dispatch:
    inputs:
      branchname:
        description: '请输入要部署的分支名称:'
        required: true
        default: 'release'
jobs:
# ...

workflow_dispatch 触发器当且仅当用户通过 GitHub.com 的项目页面进入 Actions 控制面板后,手动运行某个任务时触发:

通过手动方式运行 GitHub Actions 的方式,在运行特定任务时,可以要求用户通过表单输入任务关键信息

.yaml 配置文件中,可以通过 ${``{github.event.inputs.branchname}} 的方式在任何位置使用用户对于 branchname 配置项的输入值:

yaml 复制代码
# ...
run: |
  git -C "${{github.workspace}}/${{github.event.repository.name}}" checkout ${{github.event.inputs.branchname}}
# ...

我们同样提供了一个"持续发布"配置文件示例,可以在此处查看。

需要注意的一点是,由于 GitHub Actions Runner 在本地服务器中以独立的用户运行,如果需要更改服务器中的其他文件,可能需要为这些文件或文件夹赋予适当的访问权限,并且可能使用到诸如 setfacl 等命令。

管理秘密变量

在上述 deployment.yml 示例中,每当用户部署成功代码后,我们都会在 Actions 中调用 dawidd6/action-send-mail@v3 以发送电子邮件:

yaml 复制代码
# ...
      - name: Send mail
        uses: dawidd6/action-send-mail@v3
        with:
          server_address: smtp.example.com
          server_port: 587
          username: ${{secrets.MAIL_USERNAME}}
          password: ${{secrets.MAIL_PASSWORD}}
# ...

在 Actions 的每一个执行步骤中使用 uses 而非 run,可以直接复用他人编写的 Actions 而无需重复编写类似命令。如在此示例中,我们使用了 @dawidd6 编写的邮件发送脚本发送电子邮件。我们将发送电子邮件所需的参数通过 with 子句的方式传入到 Actions 中。

细心的读者可能会发现,诸如电子邮箱用户名与密码等信息属于敏感信息,不应该出现在 git 代码库的提交中。GitHub Actions 通过引入**秘密变量(Secrets)**的概念解决该问题:将不适合提交到代码库中的配置项以秘密变量的形式代替,而将这些变量的真实值通过环境配置的方式写入到项目配置中。用户可以在仓库的"设置"(Settings)中进入"Secrets"查看并设置这些秘密变量,以便在 Actions 中使用。

一旦设置秘密变量,便无法在页面中查看该变量的值。在 Actions 的运行日志中,包含秘密变量在内的敏感字段的值也会被隐去。不推荐将秘密变量的值直接当作参数传入要执行的 shell 命令中,因为此时秘密变量的值会被 ps 命令以及安全审计事件机制等获取。需要使用 stdin 输入或者使用目标进程提供的其他安全机制。

无论是在 GitHub.com 托管的环境运行 Actions,还是在本地私有服务器中运行 Actions,请时刻遵循基本的安全原则。GitHub 提供了一系列 GitHub Actions 常见安全注意事项总结,敬请多加留意。

总结

在本文中,我们介绍了将 GitHub Actions 作为 CI/CD 集成时的用例。通过 GitHub Actions 可以实现各种有意思的应用,如有些用户的个人用户页中甚至嵌入了一个网页版口袋妖怪模拟器,允许访客通过点击按键的方式触发 Actions,推动游戏运行。

另一些 CI/CD 配置时所需的功能,比如"部署审核"------一位用户申请执行某些 Actions 时,需要另一位具有相应权限的用户审核通过后才可执行------属于 GitHub Enterprise 中的高级功能,需要配置相应产品后才可使用。

GitHub Actions 官方文档对于 Actions 的各种详尽配置支持比本文介绍的要多得多,感兴趣的读者可以通过下方的参考资料了解更多信息。

参考资料


以上内容已按照 Markdown 格式排版,标题、列表、代码块、链接和插图占位符均已妥善处理,确保结构清晰、易于阅读。插图位置使用 ![插图X]() 表示,具体图片需用户自行替换。

相关推荐
Morpheon1 小时前
Cursor 1.0 版本 GitHub MCP 全面指南:从安装到工作流增强
ide·github·cursor·mcp
LinXunFeng3 小时前
Flutter - GetX Helper 助你规范应用 tag
flutter·github·visual studio code
草梅友仁4 小时前
AI 图片文字翻译与视频字幕翻译工具推荐 | 2025 年第 23 周草梅周报
开源·github·aigc
qianmoQ9 小时前
GitHub 趋势日报 (2025年06月04日)
github
abcnull10 小时前
github中main与master,master无法合并到main
git·github
星哥说事11 小时前
使用VuePress2.X构建个人知识博客,并且用个人域名部署到GitHub Pages中
开源·github
勤劳打代码12 小时前
步步为营 —— Github Connection refused 分层诊断
github
寻月隐君12 小时前
深入解析 Rust 的面向对象编程:特性、实现与设计模式
后端·rust·github
贝塔实验室1 天前
FPGA 动态重构配置流程
驱动开发·fpga开发·硬件架构·硬件工程·射频工程·fpga·基带工程
qianmoQ1 天前
GitHub 趋势日报 (2025年05月31日)
github