任务说明

我上次用来把所有个人仓库的 CI 从 Travis CI 迁移到 GitHub Actions 的时候还叫 “Sourcegraph Campaigns”,现在已经升级改名成为 Sourcegraph Batch Changes。如果你之前没有听说过这个东西的话,用我的话来说,就是用于创建和管理对海量仓库的内容变更,可以是十几个仓库,也可以是上千个仓库。

这次我想要做的事情是让所有 Flamego 仓库的 CI 同时运行包括 Go 1.16 和 Go 1.17 版本的测试(当前创建这些仓库的时候 Go 1.17 还没发布)。

准备工作

Batch Changes 的文档写的非常详尽,我就懒得在这里重复了,主要指出几个关键性的链接,即我需要:

  1. 一个正常运行的 Sourcegraph 实例
  2. 安装 Sourcegraph CLI

编写变更说明

Batch Changes 使用一个 YAML 格式的文件来说明如何实现规模化、自动化地创建内容变更,下面这个文件是根据我的需求编写好的版本:

# File: add-go-1.17-to-flamego-ci.batch.yaml

name: add-go-1.17-to-flamego-ci
description: This batch change adds Go 1.17 to CI for all Flamego repositories

# 查找所有需要进行 CI 变更的 Flamego 仓库
on:
  - repositoriesMatchingQuery: "repo:github.com/flamego/ file:go.yml go-version: [ 1.16.x ]"

# 在每个仓库中执行以下步骤
steps:
  - run: "sed -i 's/go-version: \\[ 1.16.x \\]/go-version: \\[ 1.16.x, 1.17.x \\]/' .github/workflows/go.yml"
    container: alpine:3

# 描述 GitHub pull request 的分支、标题和内容
changesetTemplate:
  title: 'ci: add Go 1.17'
  body: Updates CI to include Go 1.17
  branch: batch-changes/add-go-1.17 # 变更将会被推送到这个分支
  commit:
    message: Add Go 1.17 to CI
  published: false

这个文件的大体意思就是先通过 repo:github.com/flamego/ file:go.yml go-version: [ 1.16.x ] 这个搜索查询锁定仓库列表,然后在每个仓库的 .github/workflows/go.yml 文件中把所有 go-version: [ 1.16.x ] 的字符串替换为 go-version: [ 1.16.x, 1.17.x ]

预览、应用并发布

执行以下命令就可以生成预览:

$ src batch preview -f add-go-1.17-to-flamego-ci.batch.yaml

src batch preview

如果该命令执行成功,还会直接在终端打印 Web 界面预览的 URL,非常方便!

src batch preview on web

然后我可以点击每个部分查看生成的变更是否符合预期:

src batch preview on web with diff

看起来都没问题的话,就可以单击应用(Apply):

apply src batch preview

出于谨慎,我先尝试发布其中一个变更,看看会发生什么:

publish changesets

果然,挂了。 😂

publish changesets failed

好吧,我需要移除说明文件里的最后一行 published: false,然后重新再来一遍。

不过又因为别的原因挂了 😇 排查之后发现是我的 GitHub Personal Access Token 没有获得操作 workflow 的权限,所以没有办法修改与 CI 相关的文件,也就是我正好需要修改的文件。在我把权限给到之后,貌似可以用了。

GitHub pull request

焦急等待检查通过:

GitHub pull request checks passed

是时候表演真正的技术了

在我把所有的变更都发布了之后,对在 Batch Changes UI 和 GitHub.com 上的 Pull Request 列表进行了对比:

side-by-side pull request comparison

其中一个 CI 还挂了…

pull request check failed

不过总体来讲是成功的!

some pull requests merged

Batch Changes 向仓库提交的就是最普通的 Pull Request,所以我可以直接向这个分支手动推送一些修复:

push fixes to the pull request

任务完成。

closed batch changes

最后几句话

并没有最后几句话