如何在 GitHub Actions 中使用 Bencher
根据您的使用场景,您可以在GitHub Actions中为您的以下项目设置持续基准测试:
- 基础分支
- 拉取请求
- 来自分叉的拉取请求
- ⛑️ 更安全:从默认分支对分叉PR进行基准测试并上传
- ⚠️ 风险更高:从目标分支对分叉PR进行基准测试并要求审查者
🐰 在继续之前,请确保您已创建一个API令牌 并将其设置为名为
BENCHER_API_TOKEN
的仓库秘密! 导航至您的仓库 -> 设置 -> 秘密和变量 -> 操作 -> 新仓库秘密
。 将秘密命名为BENCHER_API_TOKEN
,并将秘密值设置为您的API令牌。
基础分支
统计持续基准化的基石是为你的基础分支建立历史基线。 然后,可以使用这个历史基线来检测拉取请求中的性能回归。
- 创建一个 GitHub Actions
workflow
文件。 (例如:.github/workflows/base_benchmarks.yml
) - 对
main
分支的push
事件运行。 查看 GitHub Actionson
文档 和 GitHub Actionspush
文档 以获取完整概述。 (例如:on: push: branches: main
) - 创建一个 GitHub Actions
job
。 (例如:jobs: benchmark_base_branch
) - 设置作业将在其上运行的机器类型。
查看 GitHub Actions
runs-on
文档 以获取完整概述。 (例如:runs-on: ubuntu-latest
) - 检出你的基础分支源代码。
(例如:
uses: actions/checkout@v4
) - 使用 GitHub Action 安装 Bencher CLI。
(例如:
uses: bencherdev/bencher@main
) - 使用
bencher run
CLI子命令 运行你的main
分支基准测试。 查看 thebencher run
CLI子命令 以获取完整概述。 (例如:bencher run
) - 设置
--project
选项为项目标识符。 查看 the--project
文档 获取更多详情。 (例如:--project save-walter-white-1234abcd
) - 设置
--token
选项为BENCHER_API_TOKEN
仓库 密钥。 查看 the--token
文档 获取更多详情。 (例如:--token '${{ secrets.BENCHER_API_TOKEN }}'
) - 设置
--branch
选项为分支名称。 查看 分支选择 以获取完整概述。 (例如:--branch main
) - 设置
--testbed
选项为测试床名称。 这应该与runs-on
中选择的机器相匹配。 查看 the--tested
文档 获取更多详情。 (例如:--testbed ubuntu-latest
) - 设置
--adapter
选项为所需的基准测试适配器。 查看 基准测试适配器 以获取完整概述。 (例如:--adapter json
) - 如果生成警报,则设置
--err
标志以使命令失败。 查看 阈值与警报 以获取完整概述。 (例如:--err
) - 指定基准测试命令参数。
查看 基准测试命令 以获取完整概述。
(例如:
bencher mock
)
拉取请求
为了在拉取请求中捕获性能回归,您需要在 PR 上运行您的基准测试。
如果您只期望从同一个仓库的分支中收到 PR,
那么您只需创建另一个工作流来on
来自同一个仓库的 pull_request
事件即可。
⚠️ 此方案仅适用于所有 PR 都来自同一个仓库的情况! 参见下文的来自 Fork 的拉取请求。
-
创建一个 GitHub Actions
workflow
文件。 (例如:.github/workflows/pr_benchmarks.yml
) -
针对
pull_request
事件运行:opened
- 创建了一个拉取请求。reopened
- 重新打开了之前关闭的拉取请求。edited
- 编辑了拉取请求的标题或正文,或者更改了拉取请求的基础分支。synchronize
- 更新了拉取请求的头分支。 例如,从基础分支更新了头分支,或者向头分支推送了新的提交。
参见 GitHub Actions 的
on
文档 和 GitHub Actions 的pull_request
文档 以获得完整概述。 (例如:on: pull_request: types: [opened, reopened, edited, synchronize]
) -
创建一个 GitHub Actions
job
。 (例如:jobs: benchmark_pr_branch
) -
仅当拉取请求来自同一个仓库时在
pull_request
事件上运行。 ⚠️ 不要删除此行! 对于处理 Fork 中的 PR,请参见下文的来自 Fork 的拉取请求。 (例如:if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
) -
将
GITHUB_TOKEN
的权限设置 为对pull-requests
的write
。 根据您的 GitHub 设置,这可能不是必需的。 但是对于所有组织和 2023年2月2日之后创建的个人库, 这是默认行为。 参见 GitHub 文档 以获得完整概述。 (例如:permissions: pull-requests: write
) -
设置任务将在哪种类型的机器上运行。 参见 GitHub Actions 的
runs-on
文档 以获得完整概述。 (例如:runs-on: ubuntu-latest
) -
检出 PR 分支的源代码。 (例如:
uses: actions/checkout@v4
) -
使用 GitHub Action 安装 Bencher CLI。 (例如:
uses: bencherdev/bencher@main
) -
使用
bencher run
CLI 子命令 运行您的拉取请求分支基准测试。 参见bencher run
CLI 子命令 以获得完整概述。 (例如:bencher run
) -
将
--project
选项设置为项目的别名。 参见--project
文档 获取更多细节。 (例如:--project save-walter-white-1234abcd
) -
将
--token
选项设置为BENCHER_API_TOKEN
仓库密钥。 参见--token
文档 获取更多细节。 (例如:--token '${{ secrets.BENCHER_API_TOKEN }}'
) -
使用 GitHub Actions
github
上下文 将--branch
选项设置为 PR 分支名称。 参见 分支选择 获取完整概述。 (例如:--branch '${{ github.head_ref }}'
) -
使用 GitHub Actions
github
上下文 将--branch-start-point
选项设置为 PR 基础分支开始点。 参见 分支选择 获取完整概述。 (例如:--branch-start-point '${{ github.base_ref }}'
) -
使用 GitHub Actions
pull_request
事件 将--branch-start-point-hash
选项设置为 PR 基础分支开始点的哈希值。 参见 分支选择 获取完整概述。 (例如:--branch-start-point-hash '${{ github.event.pull_request.base.sha }}'
) -
将
--testbed
选项设置为测试床名称。 这应该与runs-on
中选择的机器相匹配。 参见--tested
文档 获取更多细节。 (例如:--testbed ubuntu-latest
) -
将
--adapter
选项设置为所需的基准测试适配器。 参见 基准测试适配器 获取完整概述。 (例如:--adapter json
) -
如果生成了警报,则设置
--err
标志以使命令失败。 参见 阈值与警报 获取完整概述。 (例如:--err
) -
将
--github-actions
选项设置为 GitHub API 认证令牌,使用 GitHub ActionsGITHUB_TOKEN
环境变量 在拉取请求上发布结果作为评论。 参见--github-actions
文档 获取更多细节。 (例如:--github-actions '${{ secrets.GITHUB_TOKEN }}'
) -
指定基准测试命令参数。 参见 基准测试命令 获取完整概述。 (例如:
bencher mock
)
来自 Fork 的 Pull Requests
如果您计划接受来自 fork 的 pull requests,这在公开的开源项目中经常是这种情况,
那么您需要稍微不同地处理这些请求。
出于安全原因,像 BENCHER_API_TOKEN
和 GITHUB_TOKEN
这样的秘密在 GitHub Actions 中对 fork PRs 是不可用的。
也就是说,如果一个外部贡献者从 fork 提交了一个 PR,以上的例子将不会起作用。
对于 fork PRs 有两个选项:
- ⛑️ 更安全:从默认分支对 Fork PR 进行基准测试并上传
- ⚠️ 更有风险:从目标分支对 Fork PR 进行基准测试,且需要审阅者
请参阅 GitHub 安全实验室撰写 和 这篇博客文章 以获得完整的概述,了解如何防止 pwn 请求。
基准测试 Fork PR 并从默认分支上传
这是向 fork 拉取请求添加[持续基准测试][continuous benchmarking]的安全和建议方式。
它需要两个独立的工作流。
第一个工作流在 pull_request
上下文中运行并缓存基准测试结果。
此处不可用任何秘密,如您的 BENCHER_API_TOKEN
和 GITHUB_TOKEN
。
然后第二个工作流在 workflow_run
上下文中下载缓存的基准测试结果并上传到 Bencher。
这是因为 workflow_run
在仓库的默认分支的上下文中运行,
其中可用秘密,如您的 BENCHER_API_TOKEN
和 GITHUB_TOKEN
。
在初始 pull_request
工作流中使用的拉取请求号、头分支和基分支
也必须显式传递给 workflow_run
工作流,因为在那里不可用。
这些工作流只会在 default 分支上存在时运行。
请参见[使用触发工作流的数据][github actions trigger workflow]以获取完整概览。
-
创建一个 GitHub Actions
workflow
文件。 (例如:.github/workflows/run_fork_pr_benchmarks.yml
) -
命名此工作流以便能被第二个工作流引用。 (例如:
name: Run and Cache Benchmarks
) -
在
pull_request
事件上运行:opened
- 创建了一个拉取请求。reopened
- 重新打开了之前关闭的拉取请求。edited
- 编辑了拉取请求的标题或正文,或者改变了拉取请求的基分支。synchronize
- 更新了拉取请求的头分支。 例如,从基分支更新了头分支或者向头分支推送了新的提交。
请参见 [GitHub Actions
on
文档][github actions on] 和 [GitHub Actionspull_request
文档][github action pull_request] 以获取完整概览。 (例如:on: pull_request: types: [opened, reopened, edited, synchronize]
) -
创建一个 GitHub Actions
job
。 (例如:jobs: benchmark_fork_pr_branch
) -
设置任务将在哪种类型的机器上运行。 请参见 [GitHub Actions
runs-on
文档][github actions runs-on] 以获取完整概览。 (例如:runs-on: ubuntu-latest
) -
检出 fork PR 分支的源代码。 (例如:
uses: actions/checkout@v4
) -
运行您的基准测试并将结果保存到文件中。 (例如:
/bin/echo '{ ... }' > benchmark_results.json
) -
将基准测试结果文件作为构件上传。 (例如:
uses: actions/upload-artifact@v4
) -
将
pull_request
事件对象作为构件上传。 (例如:uses: actions/upload-artifact@v4
)
- 创建一个 GitHub Actions
workflow
文件。 (例如:.github/workflows/track_fork_pr_benchmarks.yml
) - 命名此工作流为第二个工作流。
(例如:
name: Track Benchmarks with Bencher
) - 使用
[the
workflow_run
事件][github actions workflow_run]. 链接两个工作流。 (例如:on: workflow_run: ...
) - 创建一个 GitHub Actions
job
。 (例如:jobs: track_fork_pr_branch
) - 仅当前一个工作流的结论为成功时运行此任务,
使用 [GitHub Actions
workflow_run
事件][github actions workflow_run]。 (例如:if: github.event.workflow_run.conclusion == 'success'
) - 设置任务将在哪种类型的机器上运行。
请参见 [GitHub Actions
runs-on
文档][github actions runs-on] 以获取完整概览。 (例如:runs-on: ubuntu-latest
) - 将基准测试结果和
pull_request
事件对象文件名称设置为环境变量。 (例如:env: ...
) - 下载缓存的基准测试结果和
pull_request
事件。 (例如:uses: actions/github-script@v6
) - 提取缓存的基准测试结果和
pull_request
事件。 (例如:unzip ...
) - 将
pull_request
事件中必要的数据作为环境变量导出。 (例如:core.exportVariable(...)
) - 使用 [the GitHub Action][bencher cli github action] 安装 Bencher CLI。
(例如:
uses: bencherdev/bencher@main
) - 使用
bencher run
CLI 子命令 跟踪您的 fork 拉取分支基准测试。 请参见 [thebencher run
CLI 子命令][bencher run] 以获取完整概览。 (例如:bencher run
) - 将
--project
选项设置为项目别名。 请参见 [the--project
文档][project option] 以获取更多详情。 (例如:--project save-walter-white-1234abcd
) - 将
--token
选项设置为BENCHER_API_TOKEN
仓库秘密。 请参见 [the--token
文档][token option] 以获取更多详情。 (例如:--token '${{ secrets.BENCHER_API_TOKEN }}'
) - 使用
[the GitHub Actions
pull_request
事件][github action pull_request] 将--branch
选项设置为格式化后的 fork PR 号码。 请参见 [branch selection][branch selection branch] 以获取完整概览。 (例如:--branch '${{ env.PR_HEAD }}'
) - 使用
[the GitHub Actions
pull_request
事件][github action pull_request] 将--branch-start-point
选项设置为 fork PR 基分支开始点。 请参见 [branch selection][branch selection start point] 以获取完整概览。 (例如:--branch-start-point '${{ env.PR_BASE }}'
) - 使用
[the GitHub Actions
pull_request
事件][github action pull_request] 将--branch-start-point-hash
选项设置为 fork PR 基分支开始点的哈希值。 请参见 [branch selection][branch selection start point hash] 以获取完整概览。 (例如:--branch-start-point-hash '${{ env.PR_BASE_SHA }}'
) - 将
--testbed
选项设置为测试床名称。 这应与runs-on
中选择的机器匹配。 请参见 [the--tested
文档][testbed option] 以获取更多详情。 (例如:--testbed ubuntu-latest
) - 将
--adapter
选项设置为所需的基准测试框架适配器。 请参见 [benchmark harness adapters][adapters] 以获取完整概览。 (例如:--adapter json
) - 如果生成了警告,则设置
--err
标志以使命令失败。 请参见 [Threshold & Alerts][alerts] 以获取完整概览。 (例如:--err
) - 使用
[the GitHub Actions
GITHUB_TOKEN
环境变量][github token] 将--github-actions
选项设置为 GitHub API 认证令牌,以在拉取请求上发表评论。 请参见 [the--github-actions
文档][github actions option] 以获取更多详情。 (例如:--github-actions '${{ secrets.GITHUB_TOKEN }}'
) - 将
--ci-number
选项设置为拉取请求号码。 请参见 [the--ci-number
文档][ci number option] 以获取更多详情。 (例如:--ci-number '${{ env.PR_NUMBER }}'
) - 将
--file
选项设置为基准测试结果文件路径。 请参见 [benchmark command][command argument] 以获取完整概览。 (例如:--file "$BENCHMARK_RESULTS"
)
使用要求审阅者的目标分支基准测试分支 PR
为了保证一个分支的 PR (Pull Request,即拉取请求) 代码是安全的,这个 GitHub Action 会检查该分支是否来自其他仓库。如果该分支来自其他仓库,则需要进行审阅。
⚠️ 在批准之前彻底审阅每一个分支的 PR 是非常、非常重要的! 如果不这么做,可能会导致一个 pwn 请求!
如果你不想有这种压力,参考上面的 [默认分支基准测试和上传][benchmark fork pr and upload from default branch]。
为了配置这个工作流,你需要创建两个 GitHub Actions 环境。导航到 Your Repo -> Settings -> Environments -> New environment
。创建两个新环境,internal
和 external
。internal
环境不应该有 Deployment protection rules
。然而,external
环境应该设置 Required reviewers
,以确保信任的审阅者在基准测试之前审阅分支 PR。参考 这篇博客 以获得完整概述。
这个设置之所以有效,是因为 pull_request_target
在拉取请求的目标分支上下文中运行,诸如 BENCHER_API_TOKEN
和 GITHUB_TOKEN
的机密是可用的。因此,这个工作流将只会在 目标 分支上存在时运行。避免将任何机密设置为环境变量,例如 GITHUB_TOKEN
和 BENCHER_API_TOKEN
。相反,应该明确地将你的机密传递给 bencher run
。
-
创建一个 GitHub Actions
workflow
文件。 (例如:.github/workflows/pr_target_benchmarks.yml
) -
在
pull_request
事件上运行:opened
- 创建了一个拉取请求。reopened
- 一个之前关闭的拉取请求被重新打开。edited
- 拉取请求的标题或正文被编辑,或者拉取请求的基本分支被更改。synchronize
- 拉取请求的头部分支被更新。 例如,头部分支从基本分支更新或新的提交被推送到头部分支。
参考 GitHub Actions
on
文档 和 GitHub Actionspull_request
文档 以获得完整概述。 (例如:on: pull_request: types: [opened, reopened, edited, synchronize]
) -
创建第一个 GitHub Actions
job
来检查工作流是否需要审阅。 (例如:jobs: fork_pr_requires_review
) -
如果且仅当拉取请求来自同一仓库时,将
environment
设置为internal
。否则,设置environment
为external
,这将需要审阅者的批准才能继续进行。 ⚠️ 别删除这行! (例如:environment: ${{ (github.event.pull_request.head.repo.full_name == github.repository && 'internal') || 'external' }}
) -
创建第二个 GitHub Actions
job
来运行你的基准测试。 (例如:benchmark_fork_pr_branch
) -
让
benchmark_fork_pr_branch
任务需要fork_pr_requires_review
任务才能运行。 ⚠️ 别删除这行! 参考 GitHub Actionsneeds
文档 以获得完整概述。 (例如:needs: fork_pr_requires_review
) -
设置作业运行的机器类型。 参考 GitHub Actions
runs-on
文档 以获得完整概述。 (例如:runs-on: ubuntu-latest
) -
签出分支 PR 源代码。 由于
pull_request_target
在拉取请求的目标分支上下文中运行,你仍然需要签出拉取请求分支。 (例如:uses: actions/checkout@v4
)- 指定分支 PR 仓库(例如:
repository: ${{ github.event.pull_request.head.repo.full_name }}
) - 指定分支 PR 哈希(例如:
ref: ${{ github.event.pull_request.head.sha }}
) - 不要持久化你的
git
凭证(例如:persist-credentials: false
)
- 指定分支 PR 仓库(例如:
-
使用 GitHub Action 安装 Bencher CLI。 (例如:
uses: bencherdev/bencher@main
) -
使用
bencher run
CLI 子命令 运行你的分支拉取基准测试。 参考 thebencher run
CLI 子命令 以获得完整概述。 (例如:bencher run
) -
将
--project
选项设置为项目别名。 参考 the--project
文档 了解更多详情。 (例如:--project save-walter-white-1234abcd
) -
将
--token
选项设置为BENCHER_API_TOKEN
仓库机密。 参考 the--token
文档 了解更多详情。 (例如:--token '${{ secrets.BENCHER_API_TOKEN }}'
) -
使用 GitHub Actions
pull_request
事件 格式化分支 PR 编号, 将--branch
选项设置为分支号。 参考 分支选择 以获得完整概述。 (例如:--branch '${{ github.event.number }}/merge'
) -
使用 GitHub Actions
github
上下文 将--branch-start-point
选项设置为分支 PR 基础分支起点。 参考 分支选择 以获得完整概述。 (例如:--branch-start-point '${{ github.base_ref }}'
) -
使用 GitHub Actions
pull_request
事件 将--branch-start-point-hash
选项设置为分支 PR 基础分支起点哈希。 参考 分支选择 以获得完整概述。 (例如:--branch-start-point-hash '${{ github.event.pull_request.base.sha }}'
) -
将
--testbed
选项设置为测试床名称。 这应当与runs-on
中选定的机器匹配。 参考 the--testbed
文档 了解更多详情。 (例如:--testbed ubuntu-latest
) -
将
--adapter
选项设置为希望的基准测试工具适配器。 参考 基准测试工具适配器 以获得完整概述。 (例如:--adapter json
) -
设置
--err
标志以在生成警报时使命令失败。 参考 阈值与警报 以获得完整概述。 (例如:--err
) -
使用 GitHub Actions
GITHUB_TOKEN
环境变量 将--github-actions
选项设置为 GitHub API 认证令牌,以便在拉取请求上以评论形式发布结果。 参考 the--github-actions
文档 了解更多详情。 (例如:--github-actions '${{ secrets.GITHUB_TOKEN }}'
) -
指定基准测试命令参数。 参考 基准测试命令 以获得完整概述。 (例如:
bencher mock
)
🐰 恭喜你!你已经学会了如何在 GitHub Actions 中使用 Bencher!🎉