使用 Danger 提高 Code Review 体验

Danger

本文将介绍 Danger 是什么以及如何使用、配置。Demo 地址 DangerDemo (opens new window)

在 Code Review 时,我们可能经常要去检查各种事情,比如 pr 是否提到了 develop 分支、commit 中是否有毒(存在 merge commit)、禁止某些文件在 pr 中有修改、pr 的描述是否正常等等各种事情。有时我们会忘记检查这些事情,merge 之后才发现,这个就非常尴尬了。

Danger 可以友好地完成上述需求,而且 Danger 配置非常简单,很容易集成到现有 CI (如 Jenkins 、Travis)中。

比如,pr 标题添加[WIP]表示这个 pr 未完成,添加如下代码即可在 pr 中提示我们,这是一个未完成的 pr 。

warn("PR is classed as Work in Progress") if github.pr_title.include? "[WIP]"

# 集成 Danger 到你的项目

集成 Danger 的指导在 https://danger.systems/guides/getting_started.html (opens new window)

一共 6 步。

# 集成 Danger 到工程中

创建 Gemfiles :

bundle init

在 Gemfiles 中添加 Danger ,示例如下:

source 'https://rubygems.org'

gem 'danger'

执行:

bundle install

接下来你可以直接执行bundle exec danger init根据指导进行一步一步操作,当然你也可以继续阅读后面的集成步骤。

=。= 你也可以执行后一路回车继续看下面的内容。这一步执行除了添加 Dangerfile ,剩下的都是每一步的指导。

# 创建 Dangerfile

在根目录创建一个 Dangerfile ,示例文件如下:

# Sometimes it's a README fix, or something like that - which isn't relevant for
# including in a project's CHANGELOG for example
declared_trivial = github.pr_title.include? "#trivial"

# Make it more obvious that a PR is a work in progress and shouldn't be merged yet
warn("PR is classed as Work in Progress") if github.pr_title.include? "[WIP]"

# Warn when there is a big PR
warn("Big PR") if git.lines_of_code > 500

# Don't let testing shortcuts get into master by accident
fail("fdescribe left in tests") if `grep -r fdescribe specs/ `.length > 1
fail("fit left in tests") if `grep -r fit specs/ `.length > 1

事实上 Dangerfile 内容是一段 Ruby 代码。

# 创建一个 GitHub 账户(可选)

这一步是可选的,你可以为你的项目创建一个机器人账户,你也可以使用自己的账户,更推荐使用一个机器人账户,注册过程和注册一个正常的账号没有区别。

这里我们使用自己的账户。

# 配置一个 Access Token

创建完 GitHub 账户后,我们需要为该账户添加一个 Access Token 提供给 Danger 使用(读写 GitHub Repo,评论 PR 等功能)。

使用该链接创建对应一个新的 Token https://github.com/settings/tokens/new (opens new window)

如果你的项目是开源项目,你只需要提供 public_repo 权限,如果你的项目是个私有项目,你可能需要提供完整的 repo 权限(即 repo:status repo_deployment public_repo)。

# 将 Token 添加到 CI 中

在 Travis CI 中添加环境变量非常容易。添加 DANGER_GITHUB_API_TOKEN 变量即可,对应 Value 是在上一步得到的 Token 。

如果你的项目是一个开源项目,你可能需要打开 Display value in build log 选项确保一个 fork 项目的 PR 可以正常的工作。

对于其他 CI 你可能需要在 GETTING SET UP (opens new window) 中了解更多。

你还需要在你的 Travis 配置中添加 Danger 的运行:

osx_image: xcode8.2
language: objective-c
before_install:
  - bundle install
script:
  - xcodebuild build -project DangerDemo.xcodeproj -scheme DangerDemo -sdk iphonesimulator10.2
  - bundle exec danger

完成以上步骤,你可以创建一个新的 PR 验证 Danger 是否正常运行。

你可以创建一个带 [WIP] 标题的 PR ,此时你应该会在该 PR 中得到如下评论:

# 配置 Danger

事实上配置的过程就是在 Danger 中加一些你需要的 Ruby 代码。

你可以在https://danger.systems/reference.html (opens new window)中找到完整的 API 。

对 PR 的评论可以添加三种表述,warn fail message ,你可以根据情况去调用,fail 会设置对应的 PR status 为 fail 。

我在这里列出几个比较实用的例子,你可以直接添加进去:

PR 需要提到 develop :

warn("Please target PRs to `develop` branch") if github.branch_for_base != "develop"

将 warn 改为 fail ,并在 repo 上设置好对应的权限,就可以更好地保证未提到 develop 的代码不小心 merge 了。

一定要为 PR 添加相应的描述:

fail "Please provide a summary in the Pull Request description" if github.pr_body.length < 5

某些配置文件被修改是添加 Message :

if git.modified_files.include? "config/*.js"
  config_files = git.modified_files.select { |path| path.include? "config/" }
  message "This PR changes #{ github.html_link(config_files) }"
end

保证 commit 历史是清晰的,没有 merge commit 存在:

if git.commits.any? { |c| c.message =~ /^Merge branch '#{github.branch_for_base}'/ }
  fail('Please rebase to get rid of the merge commits in this PR')
end

Danger 支持插件,你可以自己创建需要的插件,这里还有一些为 iOS 项目提供的插件供添加:

注意 Dangerfile 只是一段 Ruby 代码,你可以添加任何你需要的需求。

这里还有一些已有项目的 Dangerfile :