弃用通知:虽然我仍会合并提供的错误修复,但不会接受新功能。 如果你想实现类似的工作流程,请使用GitHub的内置合并队列。更多信息请参见TMIB 76。
Bors-NG实现了一个持续测试工作流程,确保主分支永不中断。 它将GitHub拉取请求与类似GitHub Actions的工具集成,以运行你的测试。
其他资源:
大多数CI系统,如Jenkins和GitHub Actions,都会在每个分支被推送和每个拉取请求被打开时运行测试套件,如果测试失败,GitHub可以阻止拉取请求。要理解为什么这还不足以保持主分支始终可用,请想象以下情况:
bifurcate()重命名为bifurcateCrab()更改这个函数的名称,以及当前主分支中所有调用它的地方。我考虑过将它作为Crab的方法而不是Sword的方法,但那样就会变成bifurcateWithSword(),这似乎并没有什么改进。
bifurcate()增加另一个对bifurcate()的调用,以确保即使我们跳过预着陆程序也能完成。
当这两个拉取请求都在待处理列表中开放时,它们都将与主分支一起测试。假设它们都通过了,GitHub会愉快地显示大绿色合 并按钮。一旦它们都被合并,主分支就会变红(找不到方法bifurcate())。
除了测试要求外,GitHub还可以设置为阻止与主分支不"最新"的拉取请求,这意味着像这样的问题不会出现。这解决了问题,通过要求主分支只包含已通过测试的代码快照,但它需要维护者手动:
而且必须对每个拉取请求一次一个地进行。
这与bors自动化的过程类似,但效率较低。bors不是直接合并,而是将已审核的拉取请求添加到一个"合并队列"中,这些请求通过将主分支复制到暂存分支并合并到其中来测试。当确定暂存的状态(通过或失败)时,bors以评论的形式报告结果,如果通过则将暂存合并到主分支。然后继续处理下一个。 基于测试通常在r+后会通过的假设,bors实际上是批量测试它们(如果批次失败则进行二分法)。
请注意,bors不是你的CI系统的替代品。它只是实现了这个工作流程。
Bors是一个[GitHub应用程序],所以(假设你已经设置好了GitHub Actions),设置bors需要三个步骤:
在GitHub中将应用添加到你的仓库。点击这里使用公开托管的实例。
提交一个包含以下内容的bors.toml文件:
status = ["ci"]
设置一个同名的工作流步骤。例如:
ci-success:
name: ci
if: ${{ success() }}
needs:
- exfmt
- test
runs-on: ubuntu-latest
steps:
- name: CI succeeded
run: exit 0
要使用它,你需要停止点击大绿色合并按钮,而是在任何你认为不错的拉取请求上留下包含以下内容的评论:
bors r+
随着提交被审核,bors将它们归入一个批次队列。如果一切顺利,只会有两个批次;一个正在运行,另一个正在等待运行(并不断累积更多的拉取请求,直到有机会运行)。
要运行一个批次,bors创建一个合并提交,将主分支与构成该批次的所有拉取请求合并。然而,它不会立即推送合并提交,而是将其推送到staging分支。它们看起来像这样:
Merge #5 #7 #8
5: 将`bifurcate()`重命名为`bifurcateCrab()`
7: 在`onland`事件处理程序中调用`bifurcate()`
8: 修复`drive()`中的崩溃
如果构建通过,主分支会快进到与暂存分支相匹配。由于主分支包含刚刚测试过的完全相同的内容,逐位相同,它就不会被破坏。(至少,不会以自动化测试能够检测到的方式被破坏)
如果构建失败,bors将采用一种称为"二分法"的策略。即,它将批次分成两个批次,并将它们推送到队列中。在这个例子中,第一个批次看起来像这样:
Merge #5 #7
5: 将`bifurcate()`重命名为`bifurcateCrab()`
7: 在`onland`事件处理程序中调用`bifurcate()`
这个批次仍然会失败,因为第二个补丁插入了对第一个补丁删除的函数的调用。结果,它会再次被二分。
第二个批次仍然会通过。
Merge #8
8: 修复`drive()`中的崩溃
这个批次会成功,导致它被合并到主分支,剩下前两个仍在待处理列表中。
Merge #5
5: 将`bifurcate()`重命名为`bifurcateCrab()`
这个会通过,因为与之冲突的PR(#7)在队列中排在它后面。
合并 #7
7: 在 onland 事件处理程序中调用 bifurcate()
当一个批次无法被二分(因为它只包含一个PR)时,它会被踢回给创建者以便修复。
注意,如果你想的话,可以在仪表板页面上观看这个过程的运行。
为了方便,你也可以运行 bors try,它会像 r+ 一样启动构建,但即使成功也不会真正推送到主分支。为了帮助区分,r+ 合并提交会进入 staging,而 try 构建会进入 trying。
原始的bors使用了一个更简单的系统(它一次只测试一个PR)。 一次一个的策略是O(N),其中N是拉取请求的总数。 批处理策略是O(E log N),其中N仍然是拉取请求的总数,E是失败的拉取请求数。
如果你使用带有Docker的macOS或Linux命令行,
./script/setup && ./script/server 将设置一个本地实例,
使用模拟的GitHub实例,并通过Docker引入所有底层依赖。
Web服务器最终会在 http://localhost:8000/ 上运行。
你可以通过运行 repl 而不是 server 来在与Web服务器相同的上下文中运行Elixir REPL。要运行测试,请运行 test 而不是 server。
如果你登录,它会以"space"用户身份登录你。 不会有任何仓库,space也不会有管理员权限。 你可以使用User模型来给space管理员权限, 并使用WebhookController和GitHub ServerMock来创建仓库。
在你的笔记本电脑上运行Bors主要需要:
esl-erlang包就足够了)我使用Portable PostgreSQL, Elixir、Git和NodeJS的Chocolatey包, 以及来自Microsoft的Visual C++构建工具。
然后你可以使用mix来运行它:
$ mix ecto.create
$ mix ecto.migrate
$ mix phx.server
如果你想使用MySQL,添加-r标志:
$ mix ecto.create -r BorsNG.Database.RepoMysql
它将在模拟的GitHub API环境下运行。
要运行测试,执行:
$ mix test
$ mix dogma
$ mix dialyzer
第一步是在GitHub网站上注册一个新的GitHub App。
GitHub App名称、描述和主页URL不相关,不过我建议将主页指向仪表板页面。
用户授权回调URL应该设置为<仪表板URL>/auth/github/callback。
将设置URL留空。
webhook URL应该设置为<仪表板URL>/webhook/github。
webhook密钥应该是一个随机生成的字符串。mix phx.gen.secret命令非常适合这个用途。记住这个值,以便在bors配置中指定相同的值(你也可以稍后编辑这个值,如果需要的话)。
对于以下每个部分,设置以下整体部分权限并勾选以下webhook事件复选框。bors-ng需要这些权限的解释如下。
存储库元数据将为只读。必须设置为接收存储库事件,以便在存储库被删除时自动从 我们的数据库中移除条目。
提交状态必须设置为读写以报告测试状态(这是旧版本)。还必须获取状态事件以便与通过GitHub报告状态的CI系统集成。
问题必须设置为读写,因为拉取请求也是问题。必须启用问题评论事件以获取"bors r+"评论。如果问题设置为只读,存储库最终会出现同时被标记为已合并和已打开的拉取请求。
拉取请求必须设置为读写以能够发布拉取请求评论。还必须接收拉取请求事件以保持仪表板正常工作,并且必须获取拉取请求审查和拉取请求审查评论事件以获取这些类型的评论。
存储库内容必须设置为读写以能够创建合并提交。
检查必须设置为读写以报告测试状态(这是新版本)。还必须获取检查运行事件以与通过GitHub报告状态的CI系统集成。
组织成员必须设置为只读以同步存储库贡献者和bors审核员。
GitHub将向您的webhook端点发送"ping"通知。由于bors尚未实际运行,这将失败。这是预期的。
您需要从GitHub App获取以下值来配置bors-ng:
GitHub Apps可以设置为"内部"或"外部"。 当应用程序设置为内部时, 只有它所属的组织/用户才允许安装它。
这个设置可以在首次创建应用程序时选择,也可以之后在以下URL之一更改(开关位于页面底部):
https://github.com/organizations/<组织>/settings/apps/<应用程序名称>/advancedhttps://github.com/settings/apps/<应用程序名称>/advanced如果"外部"应用程序安装在任何外部存储库上, 则"设为内部"按钮将呈灰色。
bors-ng是用Elixir编程语言编写的, 它使用PostgreSQL作为后端数据库。 无论您计划在哪台机器上运行它,都需要安装这两个。
bors-ng是基于Phoenix Web框架构建的,他们已经有有关如何部署phoenix应用程序的文档。您部署的位置将决定仪表板URL,这在前面的步骤中是必需的,所以在设置GitHub App之前需要做出这个决定。
您需要编辑配置文件,添加一些bors特定的变量。
存储库中的配置文件已经设置为从环境中提取所需的信息,因此您可以通过设置正确的环境变量并将应用程序从此存储库部署到Heroku来配置bors:
您可以使用Heroku的一键部署系统:
或者您可以手动操作:
注意:GITHUB_INTEGRATION_ID现在在GitHub上称为App ID。
$ heroku create --buildpack "https://github.com/HashNuke/heroku-buildpack-elixir.git" bors-app
$ heroku buildpacks:add https://github.com/gjaldon/heroku-buildpack-phoenix-static.git
$ heroku addons:create heroku-postgresql:hobby-dev
$ heroku config:set \
MIX_ENV=prod \
POOL_SIZE=18 \
PUBLIC_HOST=bors-app.herokuapp.com \
ALLOW_PRIVATE_REPOS=true \
COMMAND_TRIGGER=bors \
SECRET_KEY_BASE=<SECRET1> \
GITHUB_CLIENT_ID=<OAUTH_CLIENT_ID> \
GITHUB_CLIENT_SECRET=<OAUTH_CLIENT_SECRET> \
GITHUB_INTEGRATION_ID=<ISS> \
GITHUB_INTEGRATION_PEM=`base64 -w0 priv.pem` \
GITHUB_WEBHOOK_SECRET=<SECRET2> \
[BORS_LOG_LEVEL=<debug|info|warn|...>]
$ git push heroku master
$ heroku run POOL_SIZE=1 mix ecto.migrate
警告:bors-ng将一些短期状态存储在web dyno内(它使用休眠进程来实现延迟,具体来说)。
它可以在重启后恢复信息,但无法与Heroku的复制系统正常工作。
如果您需要的吞吐量超过一个dyno所能提供的,应该使用允许Erlang集群工作的系统进行部署。
当前master分支的预构建Docker镜像可在Docker Hub上获得(作为bors-ng:latest)。
项目根目录中的Dockerfile可用于自行构建镜像。 它依赖于Docker 17.05中引入的多阶段构建, 以生成不包含Erlang、Elixir和NodeJS开发工具的精简镜像。
大多数重要的配置选项应该在运行时使用环境变量设置,与Heroku说明类似。 所有相同的建议都适用,还有一些额外的注意事项:
ELIXIR_VERSION 可以作为构建时参数设置。其默认值在 Dockerfile 中定义。
ALLOW_PRIVATE_REPOS 必须在构建和运行时都设置才能生效。默认设置为 true。
DATABASE_URL 必须包含数据库端口,因为它将在容器启动时用于等待数据库可达。格式在此处有文档说明。要在 Docker 镜像中使用 MySQL,请使用 mysql 方案 URL:-e DATABASE_URL="mysql://root:<secret>@db:3306/bors_ng",并与 BORS_DATABASE=mysql 一起使用。
DATABASE_TIMEOUT 可以设置为高于默认值 15_000(毫秒)。对于成员数量非常多的仓库,这可能是必要的。
DATABASE_PREPARE_MODE 可以设置为 unnamed 以禁用预处理语句,在使用事务/语句池(如 pgbouncer)时这是必要的。默认设置为 named。
BORS_DATABASE 可以设置为 mysql 以将 Docker 容器切换到 MySQL。
除非 DATABASE_AUTO_MIGRATE 环境变量设置为 false,否则数据库架构将在容器启动时自动创建和迁移。如果数据库状态由外部管理,或者您使用的数据库无法安全处理并发架构更改(如较旧的 MariaDB/MySQL 版本),请进行该更改。
可以使用 migrate 发布命令从容器手动应用数据库迁移。示例:docker run borsng/bors-ng:latest /app/bors/bin/bors migrate。
不幸的是,其他 mix 任务不可用,因为它们无法从编译的发布版本运行。
PORT 环境变量默认设置为 4000。
GITHUB_URL_ROOT_API 和 GITHUB_URL_ROOT_HTML 应该允许您将 bors-ng 连接到 GitHub Enterprise 实例。
注意:我从未实际使用过 GitHub Enterprise,所以我只是在猜测这里需要什么。
BORS_LOG_LEVEL 允许您在运行时为 bors-ng 设置日志级别。
允许的值是常用的 Elixir Logger 级别,例如 info、debug、warn 等。
如果未设置,默认为 info。
docker create --name bors --restart=unless-stopped
-e PUBLIC_HOST=app.bors.tech
-e SECRET_KEY_BASE=<secret>
-e GITHUB_CLIENT_ID=<secret>
-e GITHUB_CLIENT_SECRET=<secret>
-e GITHUB_INTEGRATION_ID=<secret>
-e GITHUB_INTEGRATION_PEM=<secret>
-e GITHUB_WEBHOOK_SECRET=<secret>
-e DATABASE_URL="postgresql://postgres:<secret>@db:5432/bors_ng"
-e DATABASE_USE_SSL=false
-e DATABASE_AUTO_MIGRATE=true
-e COMMAND_TRIGGER=bors
[-e BORS_LOG_LEVEL=<debug|info|warn|...>]
borsng/bors-ng
docker start bors
您可以通过修改 config/prod.secret.exs 来完成配置。
bors-ng 为"管理员"用户提供了许多特殊功能,包括诊断和无需成为审阅者即可打开仓库仪表板的能力。
然而,没有用于添加管理员的 UI;您必须自己进入 Postgres 来完成此操作。有两种方法可以做到这一点:
您可以从 iex 提示符下进行操作,如下所示:
shell$ iex -S mix # 或 `heroku run bash -c "POOL_SIZE=1 iex -S mix"`
iex> me = BorsNG.Database.Repo.get_by! BorsNG.Database.User, login: "<your login>"
iex> BorsNG.Database.Repo.update! BorsNG.Database.User.changeset(me, %{is_admin: true})
您可以从 PostgreSQL 提示符下进行操作,如下所示:
postgres=# \c bors_dev -- 或 bors_prod
bors_dev=# update users set is_admin = true where login = '<your login>';
bors-ng 根据 Apache 许可证 2.0 版获得许可。 它应该包含在源代码分发的 LICENSE-APACHE 文件中。 如果缺失,可以在 http://www.apache.org/licenses/LICENSE-2.0 找到。


企业专属的AI法律顾问
iTerms是法大大集团旗下法律子品牌,基于最先进的大语言模型(LLM)、专业的法律知识库和强大的智能体架构,帮助企业扫清合规障碍,筑牢风控防线,成为您企业专属的AI法律顾问。


稳定高效的流量提升解决方案,助力品牌曝光
稳定高效的流量提升解决方案,助力品牌曝光


最新版Sora2模型免费使用,一键生成无水印视频
最新版Sora2模型免费使用,一键生成无水印视频


实时语音翻译/同声传译工具
Transly是一个多场景的AI大语言模型驱动的同声传译、专业翻译助手,它拥有超精准的音频识别翻译能力,几乎零延迟的使用体验和支持多国语言可以让你带它走遍全球,无论你是留学生、商务人士、韩剧美剧爱好者,还是出国游玩、多国会议、跨国追星等等,都可以满足你所有需要同传的场景需求,线上线下通用,扫除语言障碍,让全世界的语言交流不再有国界。


选题、配图、成文,一站式创作,让内容运营更高效
讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。


AI辅助编程,代码自动修复
Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。


最强AI数据分析助手
小浣熊家族Raccoon,您的AI智能助手,致力于通过先进的人工智能技术,为用户提供高效、便捷的智能服务。无论是日常咨询还是专业问题解答,小浣熊都能以快速、准确的响应满足您的需求,让您的生活更加智能便捷。


像人一样思考的AI智能体
imini 是一款超级AI智能体,能根据人类指令,自主思考、自主完成、并且交付结果的AI智能体。


AI数字人视频创作平台
Keevx 一款开箱即用的AI数字人视频创作平台,广泛适用于电商广告、企业培训与社媒宣传,让全球企业与个人创作者无需拍摄剪辑,就能快速生成多语言、高质量的专业视频。


一站式AI创作平台
提供 AI 驱动的图片、视频生成及数字人等功能,助力创意创作
最新AI工具、AI资讯
独家AI资源、AI项目落地

微信扫一扫关注公众号