Danger

Danger title image

Referencea project from orta therox, Juanito Fatas and and others.

vsts

Handles interacting with VSTS inside a Dangerfile. Provides a few functions which wrap pr_json and also through a few standard functions to simplify your code.

Reference

Methods

The hash that represents the PR's JSON. For an example of what this looks like see the Danger Fixture'd one.

pr_json Hash

The title of the Pull Request.

pr_title String

The body text of the Pull Request.

pr_description String

The body text of the Pull Request.

pr_body String

The username of the author of the Pull Request.

pr_author String

The branch to which the PR is going to be merged into.

branch_for_base String

A href that represents the current PR

pr_link String

The branch to which the PR is going to be merged from.

branch_for_head String

The base commit to which the PR is going to be merged as a parent.

base_commit String

The head commit to which the PR is requesting to be merged from.

head_commit String

Returns a list of Markdown links for a file, or files in the head repository. It returns a string of multiple links if passed an array.

markdown_link (paths: String or Array, full_path=true: Bool)String

Examples

Warn when a PR is classed as work in progress

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

Declare a PR to be simple to avoid specific Danger rules

declared_trivial = (vsts.pr_title + vsts.pr_body).include?("#trivial")

Ensure there is a summary for a PR

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

Only accept PRs to the develop branch

failure "Please re-submit this PR to develop, we may have already fixed your issue." if vsts.branch_for_base != "develop"

Highlight when a celebrity makes a pull request

message "Welcome, Danger." if vsts.pr_author == "dangermcshane"

Ensure that all PRs have an assignee

warn "This PR does not have any assignees yet." unless vsts.pr_json["reviewers"].length == 0

Send a message with links to a collection of specific files

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

Highlight with a clickable link if a Package.json is changed

warn "#{vsts.markdown_link("Package.json")} was edited." if git.modified_files.include? "Package.json"

Note an issue with a particular line on a file using the #L[num] syntax, e.g. `#L23`

linter_json = `my_linter lint "file"`
results = JSON.parse linter_json
unless results.empty?
  file, line, warning = result.first
  warn "#{vsts.markdown_link("#{file}#L#{line}")} has linter issue: #{warning}."
end

local_repo

Handles interacting with local only plugin inside a Dangerfile. It is support pluggin for dry_run command and does not expose any methods. But you can still use other plugins like git

Reference

Examples

Check that added lines contains agreed form of words

git.diff.each do |chunk|
  chunk.patch.lines.grep(/^+/).each do |added_line|
    if added_line.gsub!(/(?<cancel>cancel)(?<rest>[^l[[:space:]][[:punct:]]]+)/i, '>>\k<cancel>-l-\k<rest><<')
      fail "Single 'L' for cancellation-alike words in '#{added_line}'" 
    end
  end
end

bitbucket_cloud

Handles interacting with Bitbucket Cloud inside a Dangerfile. Provides a few functions which wrap pr_json and also through a few standard functions to simplify your code.

Reference

Methods

The hash that represents the PR's JSON. For an example of what this looks like see the Danger Fixture'd one.

pr_json Hash

The title of the Pull Request.

pr_title String

The body text of the Pull Request.

pr_description String

The body text of the Pull Request.

pr_body String

The username of the author of the Pull Request.

pr_author String

The branch to which the PR is going to be merged into.

branch_for_base String

A href that represents the current PR

pr_link String

The branch to which the PR is going to be merged from.

branch_for_head String

The base commit to which the PR is going to be merged as a parent.

base_commit String

The head commit to which the PR is requesting to be merged from.

head_commit String

Examples

Warn when a PR is classed as work in progress

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

Declare a PR to be simple to avoid specific Danger rules

declared_trivial = (bitbucket_cloud.pr_title + bitbucket_cloud.pr_body).include?("#trivial")

Ensure that labels have been used on the PR

failure "Please add labels to this PR" if bitbucket_cloud.pr_labels.empty?

Ensure there is a summary for a PR

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

Only accept PRs to the develop branch

failure "Please re-submit this PR to develop, we may have already fixed your issue." if bitbucket_cloud.branch_for_base != "develop"

Highlight when a celebrity makes a pull request

message "Welcome, Danger." if bitbucket_cloud.pr_author == "dangermcshane"

Ensure that all PRs have an assignee

warn "This PR does not have any assignees yet." if bitbucket_cloud.pr_json[:reviewers].length == 0

Send a message with links to a collection of specific files

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

Highlight with a clickable link if a Package.json is changed

warn "#{bitbucket_cloud.html_link("Package.json")} was edited." if git.modified_files.include? "Package.json"

github

Handles interacting with GitHub inside a Dangerfile. Provides a few functions which wrap pr_json and also through a few standard functions to simplify your code.

Reference

Methods

In Beta. Provides access to creating a GitHub Review instead of a typical GitHub comment.

To use you announce the start of your review, and the end via the start and submit functions, for example:

github.review.start github.review.fail(message) github.review.warn(message) github.review.message(message) github.review.markdown(message) github.review.submit

review ReviewDSL

The title of the Pull Request.

pr_title String

The body text of the Pull Request.

pr_body String

The username of the author of the Pull Request.

pr_author String

The labels assigned to the Pull Request.

pr_labels String

The branch to which the PR is going to be merged into.

branch_for_base String

The branch to which the PR is going to be merged from.

branch_for_head String

The base commit to which the PR is going to be merged as a parent.

base_commit String

The head commit to which the PR is requesting to be merged from.

head_commit String

The hash that represents the PR's JSON. For an example of what this looks like see the Danger Fixture'd one.

pr_json Hash

Provides access to the GitHub API client used inside Danger. Making it easy to use the GitHub API inside a Dangerfile.

api Octokit::Client

The unified diff produced by Github for this PR see Unified diff

pr_diff String

Returns a list of HTML anchors for a file, or files in the head repository. An example would be: <a href='https://github.com/artsy/eigen/blob/561827e46167077b5e53515b4b7349b8ae04610b/file.txt'>file.txt</a>. It returns a string of multiple anchors if passed an array.

html_link (paths: String or Array, full_path=true: Bool)String

Use to ignore inline messages which lay outside a diff's range, thereby not posting them in the main comment. You can set hash to change behavior per each kinds. (ex. {warning: true, error: false})

dismiss_out_of_range_messages (dismiss=true: Bool)

Examples

Warn when a PR is classed as work in progress

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

Declare a PR to be simple to avoid specific Danger rules

declared_trivial = (github.pr_title + github.pr_body).include?("#trivial")

Ensure that labels have been used on the PR

failure "Please add labels to this PR" if github.pr_labels.empty?

Check if a user is in a specific GitHub org, and message them if so

unless github.api.organization_member?('danger', github.pr_author)
  message "@#{github.pr_author} is not a contributor yet, would you like to join the Danger org?"
end

Ensure there is a summary for a PR

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

Only accept PRs to the develop branch

failure "Please re-submit this PR to develop, we may have already fixed your issue." if github.branch_for_base != "develop"

Note when PRs don't reference a milestone, which goes away when it does

has_milestone = github.pr_json["milestone"] != nil
warn("This PR does not refer to an existing milestone", sticky: false) unless has_milestone

Note when a PR cannot be manually merged, which goes away when you can

can_merge = github.pr_json["mergeable"]
warn("This PR cannot be merged yet.", sticky: false) unless can_merge

Highlight when a celebrity makes a pull request

message "Welcome, Danger." if github.pr_author == "dangermcshane"

Ensure that all PRs have an assignee

warn "This PR does not have any assignees yet." unless github.pr_json["assignee"]

Send a message with links to a collection of specific files

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

Highlight with a clickable link if a Package.json is changed

warn "#{github.html_link("Package.json")} was edited." if git.modified_files.include? "Package.json"

Note an issue with a particular line on a file using the #L[num] syntax, e.g. `#L23`

linter_json = `my_linter lint "file"`
results = JSON.parse linter_json
unless results.empty?
  file, line, warning = result.first
  warn "#{github.html_link("#{file}#L#{line}")} has linter issue: #{warning}."
end

gitlab

Handles interacting with GitLab inside a Dangerfile. Provides a few functions which wrap mr_json and also through a few standard functions to simplify your code.

Reference

Methods

The title of the Merge Request

mr_title String

The body text of the Merge Request

mr_body String

The username of the author of the Merge Request

mr_author String

The labels assigned to the Merge Request

mr_labels String

The unified diff produced by GitLab for this MR see Unified diff

mr_diff String

The branch to which the MR is going to be merged into

branch_for_merge String

The branch to which the MR is going to be merged into.

branch_for_base String

The branch to which the MR is going to be merged from.

branch_for_head String

The base commit to which the MR is going to be merged as a parent

base_commit String

The head commit to which the MR is requesting to be merged from

head_commit String

The hash that represents the MR's JSON. See documentation for the structure here

mr_json Hash

Provides access to the GitLab API client used inside Danger. Making it easy to use the GitLab API inside a Dangerfile. See the gitlab gem's documentation for accessible methods.

api GitLab::Client

Returns a list of HTML anchors for a file, or files in the head repository. An example would be: <a href='https://gitlab.com/artsy/eigen/blob/561827e46167077b5e53515b4b7349b8ae04610b/file.txt'>file.txt</a>. It returns a string of multiple anchors if passed an array.

html_link (paths: String or Array, full_path=true: Bool)String

Examples

Warn when an MR is classed as work in progress.

warn "MR is classed as Work in Progress" if gitlab.mr_title.include? "[WIP]"

Declare a MR to be simple to avoid specific Danger rules.

declared_trivial = (gitlab.mr_title + gitlab.mr_body).include?("#trivial")

Ensure that labels have been applied to the MR.

failure "Please add labels to this MR" if gitlab.mr_labels.empty?

Ensure that all MRs have an assignee.

warn "This MR does not have any assignees yet." unless gitlab.mr_json["assignee"]

Ensure there is a summary for a MR.

failure "Please provide a summary in the Merge Request description" if gitlab.mr_body.length < 5

Only accept MRs to the develop branch.

failure "Please re-submit this MR to develop, we may have already fixed your issue." if gitlab.branch_for_merge != "develop"

Note when MRs don't reference a milestone, make the warning stick around on subsequent runs

has_milestone = gitlab.mr_json["milestone"] != nil
warn("This MR does not refer to an existing milestone", sticky: true) unless has_milestone

Note when a MR cannot be manually merged

can_merge = gitlab.mr_json["mergeable"]
warn("This MR cannot be merged yet.") unless can_merge

Highlight when a celebrity makes a merge request.

message "Welcome, Danger." if gitlab.mr_author == "dangermcshane"

Send a message with links to a collection of specific files.

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

Highlight with a clickable link if a Package.json is changed.

warn "#{gitlab.html_link("Package.json")} was edited." if git.modified_files.include? "Package.json"

bitbucket_server

Handles interacting with Bitbucket Server inside a Dangerfile. Provides a few functions which wrap pr_json and also through a few standard functions to simplify your code.

Reference

Methods

The hash that represents the PR's JSON. For an example of what this looks like see the Danger Fixture'd one.

pr_json Hash

The title of the Pull Request.

pr_title String

The body text of the Pull Request.

pr_description String

The body text of the Pull Request.

pr_body String

The username of the author of the Pull Request.

pr_author String

The branch to which the PR is going to be merged into.

branch_for_base String

A href that represents the current PR

pr_link String

The branch to which the PR is going to be merged from.

branch_for_head String

The base commit to which the PR is going to be merged as a parent.

base_commit String

The head commit to which the PR is requesting to be merged from.

head_commit String

Returns a list of Markdown links for a file, or files in the head repository. It returns a string of multiple anchors if passed an array.

html_link (paths: String or Array, full_path=true: Bool)String

Returns a list of Markdown links for a file, or files in the head repository. It returns a string of multiple links if passed an array.

markdown_link (paths: String or Array, full_path=true: Bool)String

Examples

Warn when a PR is classed as work in progress

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

Declare a PR to be simple to avoid specific Danger rules

declared_trivial = (bitbucket_server.pr_title + bitbucket_server.pr_body).include?("#trivial")

Ensure that labels have been used on the PR

failure "Please add labels to this PR" if bitbucket_server.pr_labels.empty?

Ensure there is a summary for a PR

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

Only accept PRs to the develop branch

failure "Please re-submit this PR to develop, we may have already fixed your issue." if bitbucket_server.branch_for_base != "develop"

Highlight when a celebrity makes a pull request

message "Welcome, Danger." if bitbucket_server.pr_author == "dangermcshane"

Ensure that all PRs have an assignee

warn "This PR does not have any assignees yet." if bitbucket_server.pr_json[:reviewers].length == 0

Send a message with links to a collection of specific files

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

Highlight with a clickable link if a Package.json is changed

warn "#{bitbucket_server.html_link("Package.json")} was edited." if git.modified_files.include? "Package.json"

danger

A way to interact with Danger herself. Offering APIs to import plugins, and Dangerfiles from muliple sources.

Reference

Methods

Download a local or remote plugin and make it usable inside the Dangerfile.

import_plugin (path_or_url: String)

Import a Dangerfile.

import_dangerfile (opts: Hash)

Returns the name of the current SCM Provider being used.

scm_provider Symbol

Examples

Import a plugin available over HTTP

device_grid = "https://raw.githubusercontent.com/fastlane/fastlane/master/danger-device_grid/lib/device_grid/plugin.rb"
danger.import_plugin(device_grid)

Import from a local file reference

danger.import_plugin("danger/plugins/watch_plugin.rb")

Import all files inside a folder

danger.import_plugin("danger/plugins/*.rb")

Run a Dangerfile from inside a sub-folder

danger.import_dangerfile(path: "path/to/Dangerfile")

Run a Dangerfile from inside a gem

danger.import_dangerfile(gem: "ruby-grape-danger")

Run a Dangerfile from inside a repo

danger.import_dangerfile(gitlab: "ruby-grape/danger")

Run a Dangerfile from inside a repo branch and path

danger.import_dangerfile(github: "ruby-grape/danger", branch: "custom", path: "path/to/Dangerfile")

messaging

Provides the feedback mechanism for Danger. Danger can keep track of messages, warnings, failure and post arbitrary markdown into a comment.

The message within which Danger communicates back is amended on each run in a session.

Each of message, warn and fail have a sticky flag, false by default, which when true means that the message will be crossed out instead of being removed. If it's not called again on subsequent runs.

Each of message, warn, fail and markdown support multiple passed arguments message 'Hello', 'World', file: "Dangerfile", line: 1 warn ['This', 'is', 'warning'], file: "Dangerfile", line: 1 failure 'Ooops', 'bad bad error', sticky: false markdown '# And', '# Even', '# Markdown', file: "Dangerfile", line: 1

By default, using failure would fail the corresponding build. Either via an API call, or via the return value for the danger command. Older code examples use fail which is an alias of failure, but the default Rubocop settings would have an issue with it.

You can optionally add file and line to provide inline feedback on a PR in GitHub, note that only feedback inside the PR's diff will show up inline. Others will appear inside the main comment.

It is possible to have Danger ignore specific warnings or errors by writing Danger: Ignore "[warning/error text]".

Sidenote: Messaging is the only plugin which adds functions to the root of the Dangerfile.

Reference

Methods

Print markdown to below the table

markdown (*markdowns: String, **options: String)

Print out a generate message on the PR

message (*messages: String, **options: Boolean)

Specifies a problem, but not critical

warn (*warnings: String, **options: Boolean)

Declares a CI blocking error

fail (*failures: String, **options: Boolean)

Declares a CI blocking error

failure

A list of all messages passed to Danger, including the markdowns.

status_report Hash

A list of all violations passed to Danger, we don't anticipate users of Danger needing to use this.

violation_report Hash

Examples

Failing a build

failure "This build didn't pass tests"
failure "Ooops!", "Something bad happend"
failure ["This is example", "with array"]

Failing a build, and note that on subsequent runs

failure("This build didn't pass tests", sticky: true)

Passing a warning

warn "This build didn't pass linting"
warn "Hm...", "This is not really good"
warn ["Multiple warnings", "via array"]

Displaying a markdown table

message = "### Proselint found issues\n\n"
message << "Line | Message | Severity |\n"
message << "| --- | ----- | ----- |\n"
message << "20 | No documentation | Error \n"
markdown message

markdown "### First issue", "### Second issue"
markdown ["### First issue", "### Second issue"]

Adding an inline warning to a file

warn("You shouldn't use puts in your Dangerfile", file: "Dangerfile", line: 10)

git

Handles interacting with git inside a Dangerfile. Providing access to files that have changed, and useful statistics. Also provides access to the commits in the form of Git::Log objects.

Reference

Methods

Paths for files that were added during the diff

added_files FileList

Paths for files that were removed during the diff

deleted_files FileList

Paths for files that changed during the diff

modified_files FileList

List of renamed files

renamed_files Array

Whole diff

diff Git::Diff

The overall lines of code added/removed in the diff

lines_of_code Fixnum

The overall lines of code removed in the diff

deletions Fixnum

The overall lines of code added in the diff

insertions Fixnum

The log of commits inside the diff

commits Git::Log

Details for a specific file in this diff

diff_for_file Git::Diff::DiffFile

Statistics for a specific file in this diff

info_for_file Hash

List of remote tags

tags String

Examples

Do something to all new and edited markdown files

markdowns = (git.added_files + git.modified_files)
do_something markdowns.select{ |file| file.end_with? "md" }

Don't allow a file to be deleted

deleted = git.deleted_files.include? "my/favourite.file"
failure "Don't delete my precious" if deleted

Fail really big diffs

failure "We cannot handle the scale of this PR" if git.lines_of_code > 50_000

Warn when there are merge commits in the diff

if git.commits.any? { |c| c.message =~ /^Merge branch 'master'/ }
  warn 'Please rebase to get rid of the merge commits in this PR'
end

Warn when somebody tries to add nokogiri to the project

diff = git.diff_for_file("Gemfile.lock")
if diff && diff.patch =~ "nokogiri"
  warn 'Please do not add nokogiri to the project. Thank you.'
end