如何在 GitHub Actions 中使用 Bencher
根据您的使用场景,您可以在GitHub Actions中为您的以下项目设置持续基准测试:
- 基础分支
- 拉取请求
- 来自分叉的拉取请求
- ⛑️ 更安全:从默认分支对分叉PR进行基准测试并上传
- ⚠️ 风险更高:从目标分支对分叉PR进行基准测试并要求审查者
在继续之前,请确保您已创建一个API令牌
并将其设置为名为BENCHER_API_TOKEN
的仓库秘密!
导航至您的仓库 -> 设置 -> 秘密和变量 -> 操作 -> 新仓库秘密
。
将秘密命名为BENCHER_API_TOKEN
,并将秘密值设置为您的API令牌。
在 GitHub Actions 中,
当工作流程从分叉的存储库触发时,秘密不会传递给运行器。
因此,当将以下任何工作流程添加到您的存储库并提交拉取请求时,您需要使用_相同_存储库中的分支。
如果您尝试从一个分叉提交拉取请求来添加 Bencher,那么 BENCHER_API_TOKEN
秘密将不可用。
${{ secrets.BENCHER_API_TOKEN }}
将会是一个空字符串。
基础分支
统计持续基准化的基石是为你的基础分支建立历史基线。 然后,可以使用这个历史基线来检测拉取请求中的性能回归。
- 创建一个 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
)
拉取请求
为了在拉取请求中捕获性能回归,您需要在拉取请求上运行基准测试。
如果您只期望有来自同一存储库的分支的拉取请求,
那么您可以简单地创建另一个工作流程来处理来自同一存储库的 pull_request
事件。
⚠️ 此解决方案仅适用于所有拉取请求都来自同一存储库的情况! 请参阅下面的 从派生库的拉取请求。
-
创建一个 GitHub Actions
workflow
文件 (例如.github/workflows/pr_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: benchmark_pr_branch
) -
仅在拉取请求来自同一存储库的情况下触发
pull_request
事件。 ⚠️ 不要删除此行! 关于处理派生库拉取请求,请参阅下面的 从派生库的拉取请求。 (例如if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
) -
将
GITHUB_TOKEN
的权限 设置为write
以处理pull-requests
。 根据您的 GitHub 设置,这可能不是必须的。 但对于 2023 年 2 月 2 日之后创建的所有组织和个人仓库, 这是默认行为。 请参阅 GitHub 文档 以了解完整概述。 (例如permissions: pull-requests: write
) -
设置工作将运行的机器类型。 请参阅 GitHub Actions
runs-on
文档 以了解完整概述。 (例如runs-on: ubuntu-latest
) -
签出拉取请求分支的源代码。 (例如
uses: actions/checkout@v4
) -
使用 GitHub Action 安装 Bencher CLI。 (例如
uses: bencherdev/bencher@main
) -
使用
bencher run
CLI 子命令运行您的拉取请求分支基准测试。 请参阅bencher run
CLI 子命令 以了解完整概述。 (例如bencher run
) -
将
--project
选项设置为项目 slug。 有关详细信息,请参阅--project
文档。 (例如--project save-walter-white-1234abcd
) -
将
--token
选项设置为 Repository 秘密的BENCHER_API_TOKEN
。 有关详细信息,请参阅--token
文档。 (例如--token '${{ secrets.BENCHER_API_TOKEN }}'
) -
使用 GitHub Actions
github
上下文 将--branch
选项设置为拉取请求分支名称。 请参阅 分支选择 以了解完整概述。 (例如--branch '${{ github.head_ref }}'
) -
使用 GitHub Actions
github
上下文 将--branch-start-point
选项设置为拉取请求基线分支起点。 请参阅 分支选择 以了解完整概述。 (例如--branch-start-point '${{ github.base_ref }}'
) -
使用 GitHub Actions
pull_request
事件 将--branch-start-point-hash
选项设置为拉取请求基线分支起点哈希值。 请参阅 分支选择 以了解完整概述。 (例如--branch-start-point-hash '${{ github.event.pull_request.base.sha }}'
) -
设置
--branch-reset
标志以始终将分支重置为起点。 这将防止基准数据漂移。 请参阅 分支选择 以了解完整概述。 (例如--branch-reset
) -
将
--testbed
选项设置为 Testbed 名称。 这应该与runs-on
中选择的机器相匹配。 有关详细信息,请参阅--testbed
文档。 (例如--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 拉取请求添加持续基准测试的安全且建议的方法。
它需要两个单独的工作流。
第一个工作流在 pull_request
上下文中运行并缓存基准测试结果。
在那里无法访问您的 BENCHER_API_TOKEN
和 GITHUB_TOKEN
等机密。
然后第二个工作流将下载缓存的基准测试结果,并在 workflow_run
上下文中将其上传到 Bencher。
这是可行的,因为 workflow_run
运行在存储库的默认分支上下文中,
在这里可以访问 BENCHER_API_TOKEN
和 GITHUB_TOKEN
等机密。
初始 pull_request
工作流中使用的拉取请求编号、头部分支和基本分支
必须明确传递到 workflow_run
工作流中,因为在那里无法访问这些信息。
这些工作流仅在 默认 分支上存在时才会运行。
有关完整概述,请参见使用触发工作流的数据。
-
创建第一个 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 Actionspull_request
文档。 (例如:on: pull_request: types: [opened, reopened, edited, synchronize]
) -
创建一个 GitHub Actions
job
。 (例如:jobs: benchmark_fork_pr_branch
) -
设置作业运行的机器类型。 有关完整概述,请参见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
) - 使用
workflow_run
事件 链接两个工作流。 (例如:on: workflow_run: ...
) - 创建一个 GitHub Actions
job
。 (例如:jobs: track_fork_pr_branch
) - 仅当上一个工作流的结论为成功时运行此作业,使用
GitHub Actions
workflow_run
事件。 (例如:if: github.event.workflow_run.conclusion == 'success'
) - 设置作业运行的机器类型。
有关完整概述,请参见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(...)
) - 使用 GitHub Action 安装 Bencher CLI。
(例如:
uses: bencherdev/bencher@main
) - 使用
bencher run
CLI 子命令 来跟踪您的 fork 拉取分支基准测试。 有关完整概述,请参见bencher run
CLI 子命令。 (例如:bencher run
) - 将
--project
选项设置为项目 slug。 有关更多详细信息,请参见--project
文档。 (例如:--project save-walter-white-1234abcd
) - 将
--token
选项设置为 存储库 机密中的BENCHER_API_TOKEN
。 有关更多详细信息,请参见--token
文档。 (例如:--token '${{ secrets.BENCHER_API_TOKEN }}'
) - 使用 GitHub Actions
pull_request
事件 将--branch
选项设置为格式化的 fork PR 号。 有关完整概述,请参见 分支选择。 (例如:--branch '${{ env.PR_HEAD }}'
) - 使用 GitHub Actions
pull_request
事件 将--branch-start-point
选项设置为 fork PR 基本分支的起点。 有关完整概述,请参见 分支选择。 (例如:--branch-start-point '${{ env.PR_BASE }}'
) - 使用 GitHub Actions
pull_request
事件 将--branch-start-point-hash
选项设置为 fork PR 基本分支的起点哈希。 有关完整概述,请参见 分支选择。 (例如:--branch-start-point-hash '${{ env.PR_BASE_SHA }}'
) - 设置
--branch-reset
标志以始终将分支重置为起点。 这将防止基准测试数据漂移。 有关完整概述,请参见 分支选择。 (例如:--branch-reset
) - 将
--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 }}'
) - 将
--ci-number
选项设置为拉取请求编号。 有关更多详细信息,请参见--ci-number
文档。 (例如:--ci-number '${{ env.PR_NUMBER }}'
) - 将
--file
选项设置为基准测试结果文件路径。 有关完整概述,请参见 基准测试命令。 (例如:--file "$BENCHMARK_RESULTS"
)
基准从目标分支创建的 Fork PR 并需要审核
为了保证来自 fork 拉取请求的代码是安全的, 这个 GitHub Action 会检查 fork 是否来自其他仓库。 如果 fork 是来自其他仓库,那么它需要审核。
⚠️ 非常、非常重要的是在批准之前彻底审核每个 fork PR! 否则可能会导致被恶意请求攻击!
如果你不愿意承担这个风险,请参见上面的 基准默认分支的 Fork PR 并上传。
要配置这个工作流,你需要创建两个
GitHub Actions 环境。
导航到 Your Repo -> Settings -> Environments -> New environment
。
创建两个新环境,internal
和 external
。
internal
环境不应有任何 Deployment protection rules
。
但是,external
环境需要设置 Required reviewers
,这些审核者需要在基准测试之前审核 fork 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
job 需要fork_pr_requires_review
job 之前才能运行。 ⚠️ 不要移除此行! 参见 GitHub Actionsneeds
文档 以获得完整概述。 (例如:needs: fork_pr_requires_review
) -
设置作业运行的机器类型。 参见 GitHub Actions
runs-on
文档 以获得完整概述。 (例如:runs-on: ubuntu-latest
) -
检出 fork PR 源代码。 由于
pull_request_target
在拉取请求的目标分支上下文中运行, 仍然需要检查拉取请求分支。 (例如:uses: actions/checkout@v4
)- 指定 fork PR 存储库(例如:
repository: ${{ github.event.pull_request.head.repo.full_name }}
) - 指定 fork PR 哈希(例如:
ref: ${{ github.event.pull_request.head.sha }}
) - 不要持续保留你的
git
凭证(例如:persist-credentials: false
)
- 指定 fork PR 存储库(例如:
-
使用 GitHub Action 的 Bencher CLI 安装 Bencher CLI。 (例如:
uses: bencherdev/bencher@main
) -
使用
bencher run
CLI 子命令运行你的 fork 拉取分支基准测试。 参见 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
选项为格式化的 fork PR 号,使用 GitHub Actionspull_request
事件。 参见 分支选择 以获得完整概述。 (例如:--branch '${{ github.event.number }}/merge'
) -
设置
--branch-start-point
选项为 fork PR 基准分支起点,使用 GitHub Actionsgithub
上下文。 参见 分支选择 以获得完整概述。 (例如:--branch-start-point '${{ github.base_ref }}'
) -
设置
--branch-start-point-hash
选项为 fork PR 基准分支起点哈希,使用 GitHub Actionspull_request
事件。 参见 分支选择 以获得完整概述。 (例如:--branch-start-point-hash '${{ github.event.pull_request.base.sha }}'
) -
设置
--branch-reset
标志以始终将分支重置为起点。 这将防止基准数据漂移。 参见 分支选择 以获得完整概述。 (例如:--branch-reset
) -
设置
--testbed
选项为测试床名称。 这可能应与runs-on
中选择的机器匹配。 参见 the--testbed
文档 以了解更多详情。 (例如:--testbed ubuntu-latest
) -
设置
--adapter
选项为所需的基准测试工具适配器。 参见 基准测试工具适配器 以获得完整概述。 (例如:--adapter json
) -
设置
--err
标志以在生成警告时使命令失败。 参见 阈值和警报 以获得完整概述。 (例如:--err
) -
设置
--github-actions
选项为 GitHub API 认证令牌,以将结果作为评论发布在拉取请求上,使用 GitHub ActionsGITHUB_TOKEN
环境变量。 参见 the--github-actions
文档 以了解更多详情。 (例如:--github-actions '${{ secrets.GITHUB_TOKEN }}'
) -
指定基准命令参数。 参见 基准命令 以获得完整概述。 (例如:
bencher mock
)
🐰 恭喜你!你已经学会了如何在 GitHub Actions 中使用 Bencher!🎉