极狐 GitLab

Danger bot

极狐GitLab CI/CD 流水线包含一个 danger-review 作业,它使用 Danger 对被测代码执行各种自动化检查。

Danger 是一个在 CI 环境中运行的 gem,就像其他分析工具一样。 它与(例如 RuboCop)的区别在于,它旨在让你能够 轻松编写任意代码来测试代码或更改的属性。为此, 它提供了一组通用助手,并让你能够访问有关环境中实际更改的信息, 然后运行你的代码!

如果 Danger 要求你更改合并请求中的某些内容,最好 直接进行更改。如果你想了解 Danger 是如何工作的,或者想 修改现有规则,那么本文档就是为你准备的。

合并请求中的 Danger 评论#

Danger 只会发布一条评论,并在后续的 danger-review 运行时更新其内容。鉴于此,它通常是合并请求中最早出现的几条评论之一, 如果不是第一条的话。如果你没有看到它,请尝试从合并请求的开头开始查找。

优点#

  • 每次 danger-review 运行时,你都不会收到电子邮件通知。

缺点#

  • Danger 更新旧评论不太明显,因此你需要 注意它是否已更新。
  • 当 Danger 令牌轮换时,会造成混乱/杂乱(因为旧评论 无法更新)。

本地运行 Danger#

可以使用以下 Rake 任务在本地运行一部分当前检查:

shell
bin/rake danger_local

运行机制#

启动时,Danger 会从项目根目录读取一个 Dangerfile。 极狐GitLab 中的 Danger 代码分解为一组助手 和插件,全部位于 danger/ 子目录中,因此我们的 Dangerfile 只是告诉 Danger 加载所有内容。然后,Danger 会针对合并请求运行每个插件,收集每个插件的输出。插件 可以输出通知、警告或错误,所有这些都会被复制到 CI 作业的日志中。如果发生错误,CI 作业(以及整个流水线)将失败。

在合并请求中,Danger 还会将输出复制到 MR 本身的评论中, 从而提高可见性。

开发指南#

Danger 代码是 Ruby 代码,因此我们所有的常规后端指南 仍然适用。但是,有一些事项需要特别强调。

何时使用 Danger#

Danger 是一个强大且灵活的工具,但并非总是 解决特定问题或工作流的最合适方式。

首先,要了解极狐GitLab 对狗粮化的承诺。 我们为 Danger 编写的代码是特定于极狐GitLab 的,它可能不是解决我们遇到的需求的最合适地方。 我们的用户、客户,甚至我们自己的卫星项目,例如 Gitaly, 毕竟也经常面临类似的挑战。考虑一下你如何能 满足相同的需求,同时确保每个人都能从这项工作中受益,如果可以,就用那种方式替代。

如果存在针对某项任务的标准工具(例如 RuboCop),最好直接使用它,而不是通过 Danger 去调用它。如果不涉及 Danger,在本地运行和调试这些工具的结果会更容易,而且除非你正在使用某些 Danger 特定的功能,否则将其包含在 Danger 运行中没有任何好处。

Danger 非常适合原型设计和快速迭代解决方案,因此如果我们 想要构建的内容不明确,可以将 Danger 中的解决方案视为一次试运行, 以收集有关产品领域的信息。如果你这样做,请确保 随着工作的进行,你试图解决的问题以及原型设计的结果 都记录在议题或史诗中。这有助于我们在未来的极狐GitLab 版本中将此需求作为产品的一部分来解决!

实现细节#

将每个任务作为一个独立的功能来实现,并将其放置 在 danger 下自己的目录中,如 danger/<task-name>/Dangerfile

每个任务应与其他任务隔离,并能够独立运行。 如果有需要在多个任务之间共享的代码,请向 danger/plugins/... 添加一个插件,并在每个需要它的任务中引入它。你还可以 创建特定于单个任务的插件,这是放置与该任务相关的 复杂逻辑的自然场所。

Danger 代码只是 Ruby 代码。它应该遵守我们的编码标准,并且 像我们代码库中的任何其他 Ruby 代码一样需要测试。但是,我们 无法直接测试 Dangerfile!因此,为了最大化测试覆盖率,尽量 减少 danger/ 中的代码行数。一个非平凡的 Dangerfile 应该主要调用插件代码,并使用由 Danger 提供的方法派生的参数。 插件代码本身应该有单元测试。

目前,我们通过将代码放入 tooling/danger/... 的一个模块中, 并将其包含在匹配的 danger/plugins/... 文件中来完成这一点。然后, 可以在 spec/tooling/danger/... 中添加测试。

要确定你的 Dangerfile 是否工作,请将包含它的分支推送到 极狐GitLab。这可能非常令人沮丧,因为它会显著增加开发新任务 或尝试调试现有任务时的周期时间。如果你遵循了上述指南,大部分代码都可以 在 RSpec 中本地执行,从而最大限度地减少你在 CI 中需要经历的周期数。 但是,你可以通过在你的合并请求中清空 .gitlab/ci/rails.gitlab-ci.yml 文件来稍微加快这些周期。只是别忘了 在合并前恢复该更改!

通过 Danger 添加标签#

这适用于所有使用 gitlab-dangerfiles gem 的项目。

Danger 通常用于通过添加标签来改善 MR 规范。与其在你的 Dangerfile 中直接调用 API,不如将标签添加到 helper.labels_to_add 数组(使用 helper.labels_to_add << labelhelper.labels_to_add.concat(array_of_labels))。 在所有规则都有机会添加到 helper.labels_to_add 之后,gitlab-dangerfiles 将通过一次 API 调用负责将标签添加到 MR。

共享规则和插件#

如果你实现的规则或插件对其他项目有用,可以考虑 将它们向上游添加到 gitlab-dangerfiles 项目。

在项目上启用 Danger#

要在另一个现有的极狐GitLab 项目上启用 Dangerfile,请完成以下步骤:

  1. gitlab-dangerfiles 添加到你的 Gemfile 中。

  2. 创建一个包含以下内容的 Dangerfile

    ruby
    require "gitlab-dangerfiles" Gitlab::Dangerfiles.for_project(self, &:import_defaults)
  3. 将以下内容添加到你的 CI/CD 配置中:

    yaml
    include: - component: ${CI_SERVER_FQDN}/gitlab-org/components/danger-review/danger-review@1.2.0 rules: - if: $CI_SERVER_HOST == "jihulab.com"
  4. 创建一个项目访问令牌,该令牌具有 api 范围, Developer 权限(以便它可以添加标签),并且没有到期日期(实际上意味着一年的有效期)。

  5. 将该令牌添加为一个名为 DANGER_GITLAB_API_TOKEN 的 CI/CD 项目变量。

你应该在发送合并请求供审核之前,为其添加 ~"Danger bot" 标签。

当前用途#

以下是到目前为止,极狐GitLab 中 Danger 所用于的各种事务的(非详尽)列表:

  • 编码风格
  • 数据库 review
  • 文档 review
  • 合并请求指标
  • 审核者轮盘
  • 单一代码库工作

已知问题#

当你处理个人复刻时,Danger 会运行,但其输出不会添加到 合并请求评论中,标签也不会被应用。 这是因为来自规范项目的密钥变量未共享 给复刻。

最好且推荐的方法是从社区复刻进行工作, 那里已经配置了 Danger。

为个人复刻配置 Danger#

贡献者可以通过以下步骤为他们的复刻配置 Danger:

  1. 创建一个个人 API 令牌, 该令牌具有 api 范围(别忘了复制到剪贴板)。
  2. 在你的复刻中,添加一个项目 CI/CD 变量, 名为 DANGER_GITLAB_API_TOKEN,其值为上一步复制的令牌。
  3. 将该变量屏蔽, 使其不会出现在作业日志中。该变量不能被保护,因为它需要存在于所有分支。