---
title: 你好，GitHub Actions
date: 2023-06-06
author: Wxh16144
zhihu_url: https://zhuanlan.zhihu.com/p/639266855
---

大家好，我是 [Wxh16144](https://github.com/Wxh16144)，通过学习 Ant Design 的组件库和参与社区贡献，我发现了一些提高开发效率和代码质量的工具。借此机会，希望与大家分享我的经验，帮助大家更好地了解 Ant Design，并将这些技巧应用到自己的项目中。

# 前言

Ant Design 以开源的形式托管在 GitHub，方便更好的与全球开发者进行交流和合作，也方便开发者提交 issue 和 PR。同时借助 [GitHub Actions](https://github.com/features/actions) 和 CI/CD 能力，使得我们更好的管理代码仓库和自动化测试、部署等工作流程，本文将着重介绍 Actions 提供的能力。

## 什么是 GitHub Actions

GitHub Actions 是一个自动化软件开发工作流程的平台，从想法构建到生成，开发者只需在`.github/workflows` 目录中添加 `yml` 格式文件，定义 Workflow（工作流程） 去实现 CI（持续集成）通过 [了解 GitHub Actions](https://docs.github.com/zh/actions/learn-github-actions/understanding-github-actions)，我们可以掌握 Workflow 中一些概念。

- **Event(触发事件)**：触发运行事件，例如，有人创建了 issue、PR 或者推送了代码到某个分支。
- **Job(作业)**：一个 Workflow 包含一个或多个 **Job**，默认情况下并行运行，我们可以设置让其按顺序执行，每个 **Job** 可以包含多个 **Step**。
- **Step(步骤)**：定义每一个部分的工作内容，每一个 **Step** 都是一个单独的进程运行。该部分下每个项目都是一个单独操作或者 shell 脚本。

引用官方文档的 Workflow 图，我们可以直观的看懂 **Event**、**Job** 和 **Step** 之间的关系：

![overview-actions-simple](https://docs.github.com/assets/cb-25535/mw-1000/images/help/actions/overview-actions-simple.webp)

# 如何使用

通过上述了解，我们可以知道 Ant Design 的所有 Workflow 都放置在 [`.github/workflows`](https://github.com/ant-design/ant-design/tree/master/.github/workflows) 目录中进行管理。

Ant Design 的 CI 覆盖了以下几个方面：

- **社区管理**：使用 GitHub Actions 进行 issue/PR 质量检查，通过评论和标签来提高 issue/PR 的质量，提高协作效率。
- **代码质量**：使用 ESLint 和 Prettier 进行代码规范检查，以确保代码质量和一致性。
- **测试**：使用 Jest 和 testing-library 进行单元测试和快照测试，以确保代码的正确性和稳定性。
- **构建**：构建 ES5 和 ES6 两种模块规范的文件，以确保库能在不同的环境下使用。
- **部署**：使用 [dumi](https://d.umijs.org/) 自动生成文档并发布到 GitHub Pages 上。

## Issue

issue 作为 GitHub 平台上的一个功能，它像一个信息汇总中心一样，收集社区反馈的问题。允许 `Collaborator` 添加标签、里程碑、指派人员等信息，以便更好地组织任务和项目。

### 保证 issue 质量

为了确保 issue 包含足够的信息，帮助 Ant Design 团队对 issue 进行分析和优先级排序，我们提供了 [issue 助手](http://new-issue.ant.design) 来规范创建 issue 的流程。同时，利用 GitHub Actions 对创建的 issue 进行检查。未通过助手创建的 issue 将会被关闭，并打上 [Invalid](https://github.com/ant-design/ant-design/issues?q=label%3AInvalid) 标签，然后以评论的形式提醒创建者需要如何进行提问。就像这样：

![invalid-issue-preview](https://user-images.githubusercontent.com/32004925/231660945-509cf97c-43eb-4a1c-acd2-81eeedfe4a73.png)

但即便有时候使用了 issue 助手，团队成员可能也无法从提供的内容中得到有效的信息，这时候会选择手动对 issue 添加 [🤔 Need Reproduce](https://github.com/ant-design/ant-design/issues?q=label%3A%22%F0%9F%A4%94+Need+Reproduce%22+) 、 [needs-more-info](https://github.com/ant-design/ant-design/issues?q=label%3A%22%F0%9F%A4%94+Need+Reproduce%22+) 或 [help wanted](https://github.com/ant-design/ant-design/issues?q=label%3A%22help+wanted%22+) 等标签进一步把控 issue 质量，在 [issue-labeled.yml](https://github.com/ant-design/ant-design/blob/da83561f9cb57b0eb03d18543d96393689f799be/.github/workflows/issue-labeled.yml) 文件中，记录了不同的标签触发对应的评论回复 Job：

![need-reproduce-auto-comment-preview](https://user-images.githubusercontent.com/32004925/231673201-c7376eeb-010b-46d0-a7d0-4c115d58f58c.png)

![help-wanted-auto-comment-preview](https://user-images.githubusercontent.com/32004925/231673404-60b248cd-823f-4d31-8fff-d95b02b35fee.png)

### 常见 issue 答疑

对于一些常见的 issue，团队提供了详细的解答，以帮助开发者更快地解决问题。例如 issue 的 title 中包含有 `官网`、`网站`、`挂了`、`IE` 等类似关键词时，在 [issue-open-check.yml#L43-L94](https://github.com/ant-design/ant-design/blob/da83561f9cb57b0eb03d18543d96393689f799be/.github/workflows/issue-open-check.yml#L43-L94) Job 中详细记录了标准回复格式，并且将自动关闭 issue。

### 定期清理 issue

使用 GitHub Actions 定时任务来帮助管理和关闭 issue，这些自动化操作可以有效避免过多的未处理 issue 堆积。

- [issue-close-require.yml](https://github.com/ant-design/ant-design/blob/01a475af6d8ff4943fe4c91d04582120bf9b3a84/.github/workflows/issue-close-require.yml)：定时检查被标记为 `🤔 Need Reproduce` 或 `needs-more-info` 的 issue，如果超过 3 天没有移除这些标签，则会自动评论并关闭 issue。
- [issue-check-inactive.yml](https://github.com/ant-design/ant-design/blob/01a475af6d8ff4943fe4c91d04582120bf9b3a84/.github/workflows/issue-check-inactive.yml) ：每隔 15 天定时检查 30 天内没有任何活动的 issue，并将其添加 `Inactive` 标签，但不会关闭 issue。如果被修改或有新评论，则会自动移除 `Inactive` 和 `needs-more-info` 标签。

![inactive-issue-preview](https://user-images.githubusercontent.com/32004925/234459079-db813907-503d-4405-801d-38e133c85996.png)

## Pull Request

Ant Design 团队非常鼓励社区参与 Pull Request (PR)，可以先阅读 [《贡献者开发维护指南》](./contributor-development-maintenance-guide-cn) 文档，注意 PR 提交时需要遵守一些规范以确保质量和沟通。同时，也会利用 GitHub Action 对 PR 进行一些要求和审核，以保证代码质量和项目的长期维护。

### PR 预检

发起一个 PR 时，通过 PR 模板会自动生成描述内容，其中就包括更新日志这栏，需要开发者进行填写。[pr-open-check.yml](https://github.com/ant-design/ant-design/blob/3d627eb475e32daf3a47731140685124d568a495/.github/workflows/pr-open-check.yml) 这个 Job 将会对其进行检查，倘若未填，CI 将会以评论的方式进行提醒。就像这样：

![pr-non-changelog-comment-preview](https://user-images.githubusercontent.com/32004925/231672871-32689c30-1e0a-40fc-9237-9b9b4312f15c.png)

同时如果 PR 描述中提及的 issue 带有 `🎱 Collaborate PR only`（只允许核心成员维护）标签时，也将会关闭 PR 并评论提醒。

[verify-files-modify.yml](https://github.com/ant-design/ant-design/blob/3d627eb475/.github/workflows/verify-files-modify.yml) 这个 Job 将会检查 PR 修改内容，如果包含特定目录（如：`./github/` 和 `scripts/`）或特定文件（如：`CHANGELOG.md`）则谢绝社区贡献，将自动关闭 PR 且指定给核心成员。

### 代码规范检查

在 [lint](https://github.com/ant-design/ant-design/blob/dedbdfddafc0134219e391473c109c14766f413d/.github/workflows/test.yml#L52-L75) Job 中，总是遵循着对每一位开发者提交的代码进行 lint 检查的流程。

![eslint-ci-preview](https://user-images.githubusercontent.com/32004925/234477805-5cf3cf89-6654-4329-882d-47b35964f6fc.png)

### PR 部署预览

每创建一个 PR 时，利用 GitHub Action 自动尝试构建和部署该 PR。这样既可以确保文档正常，又可以预览该 PR 是否会对文档或者组件 Demo 产生影响。PR 部署分为多个 Job，具体流程如下：

- 首先触发 [preview-start.yml](https://github.com/ant-design/ant-design/blob/c6a7dbc09e709a8905aaa6c073593a1fed6bea14/.github/workflows/preview-start.yml) Job 对 PR 进行一个占位评论，告知开发者正在进行预览构建。也就是大家经常看到的 Preview Preparing...

![preview-preparing..](https://user-images.githubusercontent.com/32004925/231686636-eef933e6-2678-4e49-9552-babc50687644.png)

- 同时 [preview-build.yml](https://github.com/ant-design/ant-design/blob/b7d1d7cdbd888a1d73b3a3bf87bf4977e9b9bf91/.github/workflows/preview-build.yml#L52-L77) Job 会对 site 进行构建操作。
- 最后 [preview-deploy.yml](https://github.com/ant-design/ant-design/blob/c6a7dbc09e709a8905aaa6c073593a1fed6bea14/.github/workflows/preview-deploy.yml) Job 会等待 `preview-build.yml` 运行完成后进行对应的操作，如果构建成功则利用 [Surge](https://surge.sh/) 进行部署，部署地址规则：`https://preview-{PR-id}-ant-design.surge.sh`， 并将之前评论中占位图片修改为构建成功样式（点击该图片即可跳转具体地址）反之则标记为构建失败的图片。

### 其他审查

- [size-limit.yml](https://github.com/ant-design/ant-design/blob/5dfce5443744271f778313c23eb8ec3a5af481f8/.github/workflows/size-limit.ym) Job 则是对 PR 的一个产物大小进行一个检查。
- 最近比较火热的 chatGPT，团队也将它添加到 GitHub Action 中，用 AI 先对代码进行审查，具体 Job 可以参考 [chatgpt-cr.yml](https://github.com/ant-design/ant-design/blob/f7fd474cf8792ea01d03461d407c0edc11828a1c/.github/workflows/chatgpt-cr.yml) 文件。

## 单元测试

单元测试作为组件库质量保证最重要的一环，当任何提交推送时都将触发该 CI 进行自动化测试，包括每位开发者发起的 PR，或者主分支更新。

### 构建测试

团队希望每次代码更新后，都能正常构建打包产物， Ant Design 在 test.yml 文件中添加了 [Dist Job](https://github.com/ant-design/ant-design/blob/master/.github/workflows/test.yml#L104-L138) 和 [Compile Job](https://github.com/ant-design/ant-design/blob/40fb753349c4f2be314c91dbb7e6f1a960097c19/.github/workflows/test.yml#L254-L288) 以保证仓库可以进行正常打包构建。

### 功能测试

大家可能有留意到每次仅运行测试相关的 Job 就有多达 30 个。

![test-jobs-preview](https://user-images.githubusercontent.com/32004925/234482326-7c1074b5-e75a-494e-b1c7-c8ccc482ba7c.png)

团队对于单元测试的态度非常谨慎，需要考虑组件在 React 的各个主要版本上的运行情况（通常为 16、17 和 18 这三个版本）如果是主分支的更新，还需要考虑项目构建产物（通常为 `dist`、`es` 以及 `lib`）在三个 React 版本上的运行情况。目前已知 Ant Design 所有组件共有 4000 多个测试用例。为了进一步提高测试效率，我们还搭建了分布式测试环境。

所有这些功能都得益于 GitHub Action 的 [Job 矩阵策略](https://docs.github.com/zh/actions/using-jobs/using-a-matrix-for-your-jobs) ，使得我们可以一次性配置多个 Job 来执行测试任务，[Normal test](https://github.com/ant-design/ant-design/blob/40fb753349c4f2be314c91dbb7e6f1a960097c19/.github/workflows/test.yml#L141-L223) 和 [Module test](https://github.com/ant-design/ant-design/blob/40fb753349c4f2be314c91dbb7e6f1a960097c19/.github/workflows/test.yml#L294-L357) 是 Ant Design 利用矩阵策略测试相关的 Job。

## 网站部署

这里的部署构建部分和前面提到的 PR 预览部署构建行为一致，只不过构建后产物部署目标有所差异。

### 官网部署

[https://ant.design](https://ant.design) 官网使用 GitHub 提供的免费 [GitHub Pages](https://pages.github.com/) 功能，利用 Actions [Deploy to GitHub Pages](https://github.com/ant-design/ant-design/blob/dedbdfddafc0134219e391473c109c14766f413d/.github/workflows/site-deploy.yml#L73-L78) Job 直将构建的文档产物推送到[gh-pages](https://github.com/ant-design/ant-design/tree/gh-pages)分支实现。

### 独立版本

大家都知道 [https://ant.design](https://ant.design) 官网永远保持最新版本，但有时候仍还是需要查阅具体版本的文档，[Deploy to Surge](https://github.com/ant-design/ant-design/blob/5aad29d937baeba43ca8acde7f86450e9aec99f1/.github/workflows/site-deploy.yml#L80-L90) Job 则是每次发布新版本后将站点部署到 Surge， URL 规则为 `https://ant-design-{major}-{minor}-{patch}.surge.sh` 并将 url 评论在每一个发版 commit 上：

![everyone-version-preview](https://user-images.githubusercontent.com/32004925/234485713-4e93154c-d5a4-4cad-87b0-e76667ff237f.png)

## 其他

上面的篇幅已经讲述了 Ant Design 利用 CI/CD 完成的大部分核心内容，但实际上还有一些 Job 没有具体介绍，这里再补充一些。

### 接入 IM 通知

为保证开发者和社区成员可以第一时间了解到相关信息，利用 Action 提供的 Event 实现 IM 接入：

- [issue-notice](https://github.com/ant-design/ant-design/blob/master/.github/workflows/issue-open-check.yml#L96-L105)、[discussion-notice](https://github.com/ant-design/ant-design/blob/dedbdfddafc0134219e391473c109c14766f413d/.github/workflows/disscustion-open-check.yml#L16-L25) Job 表示每当创建了 Issue 、Discussion 通知到钉钉社区群中。

- [release-helper.yml](https://github.com/ant-design/ant-design/blob/dedbdfddaf/.github/workflows/release-helper.yml) CI 文件表示每当 antd 发布版本且创建 Release 时，将更新日志发布到钉钉社区群中。

- 其他未提及到的 Job 等待着大家去探索与发现...

## 接入自己项目

前面向大家介绍了 Ant Design 使用 GitHub Action 的诸多场景，我们不妨实际动手尝试一下，运用到自己项目中，提高生产效率。下面通过一个简单的 Demo 进行演示。

### 创建项目

通过命令行 `pnpm create vite@latest my-react-app --template react-ts` 创建一个 Vite + React 项目。

### 配置 CI Workflow

在项目根目录里 `.github/workflows` 文件夹中新建 `ci.yml` ，代码如下：

```yml
name: CI

# en: Set the event to pull request event and push event of the master branch
# zh: Event 设置为 master 分支的 pull request 事件和 push 事件
on:
  push:
    branches: [master]
  pull_request:
    branches: [master]

permissions:
  contents: write

jobs:
  CI:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code (检出代码)
        uses: actions/checkout@v4

      - name: Setup Node.js (设置 node 版本)
        uses: oven-sh/setup-bun@v2
        with:
          node-version: 16

      - name: Install pnpm (安装 pnpm)
        uses: pnpm/action-setup@v2
        with:
          version: 7.0.0

      - name: Install dependencies (安装依赖)
        run: pnpm install

      - name: lint (代码检查)
        run: pnpm run lint

      # en: The template does not contain test cases. If you need to use test cases, you can uncomment it
      # zh: 初始化模板中不包含测试用例，如需使用测试用例，可取消注释
      # - name: Test (测试)
      #   run: pnpm run test

      - name: Build (构建)
        run: pnpm run build

      - name: Upload build artifacts (上传构建产物)
        uses: actions/upload-artifact@v3
        with:
          name: dist
          path: ./dist

      - name: Deploy to GitHub Pages (部署到 GitHub Pages)
        uses: peaceiris/actions-gh-pages@v3
        # en: Only deploy when the push event of the master branch is triggered
        # zh: 仅在触发 master 分支的 push 事件时部署
        if: github.ref == 'refs/heads/master'
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./dist
```

上述 Workflow 中包含了一个 CI Job，当我们推送到 master 分支时， CI 触发后将依次运行 lint、build 以及 deploy，如下所示：

![test-CI-preview](https://user-images.githubusercontent.com/32004925/234609284-ec7b40f5-a221-4c8b-9093-ce68a1a545bb.png)

### 添加缓存

为了进一步优化安装依赖速度，我们可以添加 pnpm 缓存，然后发起一个 Pull Request 验证上一个步骤：

```yml
# ...
- name: create pnpm-lock.yaml (创建 pnpm-lock.yaml)
  run: pnpm install --frozen-lockfile --ignore-scripts

- name: Get pnpm store directory (获取 pnpm store 目录)
  id: pnpm-cache
  shell: bash
  run: |
    echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT

- name: Setup pnpm cache (设置 pnpm 缓存)
  uses: actions/cache@v4
  with:
    path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
    key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
    restore-keys: |
      ${{ runner.os }}-pnpm-store-

# ...
```

可以发现，发起的 PR 也正确触发了 CI Job，并且我们的 pnpm store 也被缓存了起来，之后每次触发 CI 都会根据 `pnpm-lock.yaml` 内容判断是否直接读取缓存。

![pr-CI-preview](https://user-images.githubusercontent.com/32004925/234617748-8bc4f0fd-b29a-4b01-b416-1c16eed03acb.png)

![restore-cache](https://user-images.githubusercontent.com/32004925/234621854-dbfc565c-26e0-4e48-862d-8dde8ab22627.png)

关于上面的 `Setup pnpm cache` 步骤中，7 天内未被访问的任何缓存条目将会被删除。可以存储的缓存数没有限制，但存储库中所有缓存的总大小限制为 10 GB，更多内容请阅读 [缓存依赖项以加快工作流程](https://docs.github.com/zh/actions/using-workflows/caching-dependencies-to-speed-up-workflows)。

![cache-pnpm-store](https://user-images.githubusercontent.com/32004925/234618808-46137b0d-27a0-4b01-b1a6-6e4931f6d388.png)

## 总结

本次文章到这里就结束了，希望可以帮助大家更进一步了解 Ant Design，也欢迎大家前往 [讨论区](https://github.com/ant-design/ant-design/discussions) 参与讨论和建设。
