danger 0.8.5 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +4 -1
- data/bin/danger +2 -2
- data/lib/danger.rb +13 -13
- data/lib/danger/ci_source/buildkite.rb +5 -5
- data/lib/danger/ci_source/ci_source.rb +3 -3
- data/lib/danger/ci_source/circle.rb +13 -13
- data/lib/danger/ci_source/circle_api.rb +4 -4
- data/lib/danger/ci_source/drone.rb +5 -5
- data/lib/danger/ci_source/jenkins.rb +4 -4
- data/lib/danger/ci_source/local_git_repo.rb +13 -13
- data/lib/danger/ci_source/semaphore.rb +5 -5
- data/lib/danger/ci_source/surf.rb +24 -0
- data/lib/danger/ci_source/teamcity.rb +4 -4
- data/lib/danger/ci_source/travis.rb +6 -6
- data/lib/danger/ci_source/xcode_server.rb +2 -2
- data/lib/danger/commands/init.rb +93 -82
- data/lib/danger/commands/init_helpers/interviewer.rb +15 -15
- data/lib/danger/commands/local.rb +13 -13
- data/lib/danger/commands/plugins/plugin_lint.rb +11 -8
- data/lib/danger/commands/plugins/plugin_readme.rb +15 -11
- data/lib/danger/commands/runner.rb +31 -20
- data/lib/danger/core_ext/string.rb +3 -3
- data/lib/danger/danger_core/dangerfile.rb +31 -31
- data/lib/danger/danger_core/dangerfile_dsl.rb +1 -1
- data/lib/danger/danger_core/environment_manager.rb +6 -6
- data/lib/danger/danger_core/plugins/dangerfile_git_plugin.rb +5 -5
- data/lib/danger/danger_core/plugins/dangerfile_github_plugin.rb +2 -2
- data/lib/danger/danger_core/plugins/dangerfile_import_plugin.rb +9 -9
- data/lib/danger/danger_core/plugins/dangerfile_messaging_plugin.rb +3 -3
- data/lib/danger/danger_core/standard_error.rb +6 -6
- data/lib/danger/plugin_support/plugin.rb +1 -1
- data/lib/danger/plugin_support/plugin_file_resolver.rb +6 -6
- data/lib/danger/plugin_support/plugin_parser.rb +75 -31
- data/lib/danger/request_source/request_source.rb +4 -4
- data/lib/danger/scm_source/git_repo.rb +3 -3
- data/lib/danger/version.rb +2 -2
- metadata +17 -4
- data/lib/danger/commands/plugins/plugin_abstract.rb +0 -11
- data/lib/danger/commands/plugins/plugin_new.rb +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 730a6b52e123cb69852704e92867526da77dcaa3
|
4
|
+
data.tar.gz: c48c217b428923652f446788107c0d140074e967
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e722f6688e5a65281c751a762fb3f8df5342080a404b15b7ca62c7ec6dcf3ff501dafc4a9f9881c75a5661ca5b64f3aec4309a3dcdcd693a607d24d241c970c9
|
7
|
+
data.tar.gz: 4a205ad49112adbb1980182cabebecb6c79eabdab0da89f70cabd7a58b2cd669c304e9dafa26b107aab6924f09f7700203bdaeac7a0d5a0026bf27ebbe97b5aa
|
data/README.md
CHANGED
@@ -102,9 +102,12 @@ end
|
|
102
102
|
#### Pinging people when a specific file has changed
|
103
103
|
|
104
104
|
```ruby
|
105
|
-
|
105
|
+
markdown("@orta something changed in elan!") if modified_files.include? "/components/lib/variables/colors.json"
|
106
106
|
```
|
107
107
|
|
108
|
+
If you wish to ping a person on a PR you'll need to use the `markdown` method rather than the `message`, `warn` or `fail` methods.
|
109
|
+
This is because the HTML generated by the latter methods doesn't trigger GitHub's notification detection.
|
110
|
+
|
108
111
|
#### Exposing aspects of CI logs into the PR discussion
|
109
112
|
|
110
113
|
```ruby
|
data/bin/danger
CHANGED
data/lib/danger.rb
CHANGED
@@ -1,25 +1,25 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
1
|
+
require "danger/version"
|
2
|
+
require "danger/danger_core/dangerfile"
|
3
|
+
require "danger/danger_core/environment_manager"
|
4
|
+
require "danger/commands/runner"
|
5
|
+
require "danger/plugin_support/plugin"
|
6
|
+
require "danger/core_ext/string"
|
7
7
|
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
8
|
+
require "claide"
|
9
|
+
require "colored"
|
10
|
+
require "pathname"
|
11
|
+
require "terminal-table"
|
12
|
+
require "cork"
|
13
13
|
|
14
14
|
# Import all the Sources (CI, Request and SCM)
|
15
|
-
Dir[File.expand_path(
|
15
|
+
Dir[File.expand_path("danger/*source/*.rb", File.dirname(__FILE__))].each do |file|
|
16
16
|
require file
|
17
17
|
end
|
18
18
|
|
19
19
|
module Danger
|
20
20
|
# @return [String] The path to the local gem directory
|
21
21
|
def self.gem_path
|
22
|
-
gem_name =
|
22
|
+
gem_name = "danger"
|
23
23
|
unless Gem::Specification.find_all_by_name(gem_name).any?
|
24
24
|
raise "Couldn't find gem directory for 'danger'"
|
25
25
|
end
|
@@ -5,16 +5,16 @@ module Danger
|
|
5
5
|
module CISource
|
6
6
|
class Buildkite < CI
|
7
7
|
def self.validates?(env)
|
8
|
-
return false unless env[
|
9
|
-
return false unless env[
|
10
|
-
return false unless env[
|
8
|
+
return false unless env["BUILDKITE"]
|
9
|
+
return false unless env["BUILDKITE_PULL_REQUEST_REPO"] && !env["BUILDKITE_PULL_REQUEST_REPO"].empty?
|
10
|
+
return false unless env["BUILDKITE_PULL_REQUEST"]
|
11
11
|
|
12
12
|
return true
|
13
13
|
end
|
14
14
|
|
15
15
|
def initialize(env)
|
16
|
-
self.repo_url = env[
|
17
|
-
self.pull_request_id = env[
|
16
|
+
self.repo_url = env["BUILDKITE_PULL_REQUEST_REPO"]
|
17
|
+
self.pull_request_id = env["BUILDKITE_PULL_REQUEST"]
|
18
18
|
|
19
19
|
repo_matches = self.repo_url.match(%r{([\/:])([^\/]+\/[^\/.]+)(?:.git)?$})
|
20
20
|
self.repo_slug = repo_matches[2] unless repo_matches.nil?
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "set"
|
2
2
|
|
3
3
|
module Danger
|
4
4
|
module CISource
|
@@ -16,7 +16,7 @@ module Danger
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def supported_request_sources
|
19
|
-
raise
|
19
|
+
raise "CISource subclass must specify the supported request sources"
|
20
20
|
end
|
21
21
|
|
22
22
|
def supports?(request_source)
|
@@ -28,7 +28,7 @@ module Danger
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def initialize(_env)
|
31
|
-
raise
|
31
|
+
raise "Subclass and overwrite initialize"
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
@@ -1,14 +1,14 @@
|
|
1
1
|
# https://circleci.com/docs/environment-variables
|
2
|
-
require
|
3
|
-
require
|
2
|
+
require "uri"
|
3
|
+
require "danger/ci_source/circle_api"
|
4
4
|
|
5
5
|
module Danger
|
6
6
|
module CISource
|
7
7
|
class CircleCI < CI
|
8
8
|
def self.validates?(env)
|
9
|
-
return false unless env[
|
10
|
-
return false unless env[
|
11
|
-
return false unless env[
|
9
|
+
return false unless env["CIRCLE_BUILD_NUM"]
|
10
|
+
return false unless env["CIRCLE_PROJECT_USERNAME"]
|
11
|
+
return false unless env["CIRCLE_PROJECT_REPONAME"]
|
12
12
|
|
13
13
|
return true
|
14
14
|
end
|
@@ -27,11 +27,11 @@ module Danger
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def pull_request_url(env)
|
30
|
-
url = env[
|
30
|
+
url = env["CI_PULL_REQUEST"]
|
31
31
|
|
32
|
-
if url.nil? && !env[
|
33
|
-
repo_slug = env[
|
34
|
-
url = fetch_pull_request_url(repo_slug, env[
|
32
|
+
if url.nil? && !env["CIRCLE_PROJECT_USERNAME"].nil? && !env["CIRCLE_PROJECT_REPONAME"].nil?
|
33
|
+
repo_slug = env["CIRCLE_PROJECT_USERNAME"] + "/" + env["CIRCLE_PROJECT_REPONAME"]
|
34
|
+
url = fetch_pull_request_url(repo_slug, env["CIRCLE_BUILD_NUM"])
|
35
35
|
end
|
36
36
|
|
37
37
|
url
|
@@ -40,13 +40,13 @@ module Danger
|
|
40
40
|
def initialize(env)
|
41
41
|
self.repo_url = GitRepo.new.origins # CircleCI doesn't provide a repo url env variable :/
|
42
42
|
|
43
|
-
@circle_token = env[
|
43
|
+
@circle_token = env["CIRCLE_CI_API_TOKEN"]
|
44
44
|
url = pull_request_url(env)
|
45
45
|
|
46
|
-
if URI.parse(url).path.split(
|
47
|
-
paths = URI.parse(url).path.split(
|
46
|
+
if URI.parse(url).path.split("/").count == 5
|
47
|
+
paths = URI.parse(url).path.split("/")
|
48
48
|
# The first one is an extra slash, ignore it
|
49
|
-
self.repo_slug = paths[1] +
|
49
|
+
self.repo_slug = paths[1] + "/" + paths[2]
|
50
50
|
self.pull_request_id = paths[4]
|
51
51
|
end
|
52
52
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "faraday"
|
2
2
|
|
3
3
|
module Danger
|
4
4
|
class CircleAPI
|
@@ -9,13 +9,13 @@ module Danger
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def client
|
12
|
-
@client ||= Faraday.new(url:
|
12
|
+
@client ||= Faraday.new(url: "https://circleci.com/api/v1")
|
13
13
|
end
|
14
14
|
|
15
15
|
def fetch_build(repo_slug, build_number)
|
16
16
|
url = "project/#{repo_slug}/#{build_number}"
|
17
|
-
params = {
|
18
|
-
response = client.get url, params, accept:
|
17
|
+
params = { "circle-token" => circle_token }
|
18
|
+
response = client.get url, params, accept: "application/json"
|
19
19
|
json = JSON.parse(response.body, symbolize_names: true)
|
20
20
|
json
|
21
21
|
end
|
@@ -4,9 +4,9 @@ module Danger
|
|
4
4
|
module CISource
|
5
5
|
class Drone < CI
|
6
6
|
def self.validates?(env)
|
7
|
-
return false unless env[
|
8
|
-
return false unless env[
|
9
|
-
return false unless env[
|
7
|
+
return false unless env["DRONE"]
|
8
|
+
return false unless env["DRONE_REPO"]
|
9
|
+
return false unless env["DRONE_PULL_REQUEST"].to_i > 0
|
10
10
|
|
11
11
|
return true
|
12
12
|
end
|
@@ -16,8 +16,8 @@ module Danger
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def initialize(env)
|
19
|
-
self.repo_slug = env[
|
20
|
-
self.pull_request_id = env[
|
19
|
+
self.repo_slug = env["DRONE_REPO"]
|
20
|
+
self.pull_request_id = env["DRONE_PULL_REQUEST"]
|
21
21
|
self.repo_url = GitRepo.new.origins # Drone doesn't provide a repo url env variable :/
|
22
22
|
end
|
23
23
|
end
|
@@ -5,8 +5,8 @@ module Danger
|
|
5
5
|
module CISource
|
6
6
|
class Jenkins < CI
|
7
7
|
def self.validates?(env)
|
8
|
-
return false unless env[
|
9
|
-
return false unless env[
|
8
|
+
return false unless env["ghprbPullId"].to_i > 0
|
9
|
+
return false unless env["GIT_URL"]
|
10
10
|
|
11
11
|
return true
|
12
12
|
end
|
@@ -16,8 +16,8 @@ module Danger
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def initialize(env)
|
19
|
-
self.repo_url = env[
|
20
|
-
self.pull_request_id = env[
|
19
|
+
self.repo_url = env["GIT_URL"]
|
20
|
+
self.pull_request_id = env["ghprbPullId"]
|
21
21
|
|
22
22
|
repo_matches = self.repo_url.match(%r{([\/:])([^\/]+\/[^\/.]+)(?:.git)?$})
|
23
23
|
self.repo_slug = repo_matches[2] unless repo_matches.nil?
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# For more info see: https://github.com/schacon/ruby-git
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "git"
|
4
|
+
require "uri"
|
5
5
|
|
6
6
|
module Danger
|
7
7
|
module CISource
|
@@ -9,7 +9,7 @@ module Danger
|
|
9
9
|
attr_accessor :base_commit, :head_commit
|
10
10
|
|
11
11
|
def self.validates?(env)
|
12
|
-
return !env[
|
12
|
+
return !env["DANGER_USE_LOCAL_GIT"].nil?
|
13
13
|
end
|
14
14
|
|
15
15
|
def git
|
@@ -25,21 +25,21 @@ module Danger
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def initialize(env = {})
|
28
|
-
github_host = env[
|
28
|
+
github_host = env["DANGER_GITHUB_HOST"] || "github.com"
|
29
29
|
|
30
30
|
# get the remote URL
|
31
31
|
remote = run_git "remote show origin -n | grep \"Fetch URL\" | cut -d ':' -f 2-"
|
32
32
|
if remote
|
33
33
|
remote_url_matches = remote.match(%r{#{Regexp.escape github_host}(:|/)(?<repo_slug>.+/.+?)(?:\.git)?$})
|
34
|
-
if !remote_url_matches.nil? and remote_url_matches[
|
35
|
-
self.repo_slug = remote_url_matches[
|
34
|
+
if !remote_url_matches.nil? and remote_url_matches["repo_slug"]
|
35
|
+
self.repo_slug = remote_url_matches["repo_slug"]
|
36
36
|
else
|
37
|
-
puts
|
37
|
+
puts "Danger local requires a repository hosted on GitHub.com or GitHub Enterprise."
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
-
specific_pr = env[
|
42
|
-
pr_ref = specific_pr ? "##{specific_pr}" :
|
41
|
+
specific_pr = env["LOCAL_GIT_PR_ID"]
|
42
|
+
pr_ref = specific_pr ? "##{specific_pr}" : ""
|
43
43
|
pr_command = "log --merges --oneline | grep \"Merge pull request #{pr_ref}\" | head -n 1"
|
44
44
|
|
45
45
|
# get the most recent PR merge
|
@@ -49,13 +49,13 @@ module Danger
|
|
49
49
|
if specific_pr
|
50
50
|
raise "Could not find the pull request (#{specific_pr}) inside the git history for this repo."
|
51
51
|
else
|
52
|
-
raise
|
52
|
+
raise "No recent pull requests found for this repo, danger requires at least one PR for the local mode."
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
self.pull_request_id = pr_merge.match(
|
57
|
-
sha = pr_merge.split(
|
58
|
-
parents = run_git("rev-list --parents -n 1 #{sha}").strip.split(
|
56
|
+
self.pull_request_id = pr_merge.match("#([0-9]+)")[1]
|
57
|
+
sha = pr_merge.split(" ")[0]
|
58
|
+
parents = run_git("rev-list --parents -n 1 #{sha}").strip.split(" ")
|
59
59
|
self.base_commit = parents[0]
|
60
60
|
self.head_commit = parents[1]
|
61
61
|
end
|
@@ -4,9 +4,9 @@ module Danger
|
|
4
4
|
module CISource
|
5
5
|
class Semaphore < CI
|
6
6
|
def self.validates?(env)
|
7
|
-
return false unless env[
|
8
|
-
return false unless env[
|
9
|
-
return false unless env[
|
7
|
+
return false unless env["SEMAPHORE"]
|
8
|
+
return false unless env["SEMAPHORE_REPO_SLUG"]
|
9
|
+
return false unless env["PULL_REQUEST_NUMBER"].to_i > 0
|
10
10
|
|
11
11
|
return true
|
12
12
|
end
|
@@ -16,8 +16,8 @@ module Danger
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def initialize(env)
|
19
|
-
self.repo_slug = env[
|
20
|
-
self.pull_request_id = env[
|
19
|
+
self.repo_slug = env["SEMAPHORE_REPO_SLUG"]
|
20
|
+
self.pull_request_id = env["PULL_REQUEST_NUMBER"]
|
21
21
|
self.repo_url = GitRepo.new.origins # Semaphore doesn't provide a repo url env variable :/
|
22
22
|
end
|
23
23
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# http://github.com/surf-build/surf
|
2
|
+
|
3
|
+
module Danger
|
4
|
+
module CISource
|
5
|
+
class Surf < CI
|
6
|
+
def self.validates?(env)
|
7
|
+
return ["SURF_REPO", "SURF_NWO"].all? { |x| env[x] }
|
8
|
+
end
|
9
|
+
|
10
|
+
def supported_request_sources
|
11
|
+
@supported_request_sources ||= [Danger::RequestSources::GitHub]
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(env)
|
15
|
+
self.repo_slug = env["SURF_NWO"]
|
16
|
+
if env["SURF_PR_NUM"].to_i > 0
|
17
|
+
self.pull_request_id = env["SURF_PR_NUM"]
|
18
|
+
end
|
19
|
+
|
20
|
+
self.repo_url = env["SURF_REPO"]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -2,7 +2,7 @@ module Danger
|
|
2
2
|
module CISource
|
3
3
|
class TeamCity < CI
|
4
4
|
def self.validates?(env)
|
5
|
-
env.key?
|
5
|
+
env.key? "TEAMCITY_VERSION"
|
6
6
|
end
|
7
7
|
|
8
8
|
def supported_request_sources
|
@@ -13,9 +13,9 @@ module Danger
|
|
13
13
|
# NB: Unfortunately TeamCity doesn't provide these variables
|
14
14
|
# automatically so you have to add these variables manually to your
|
15
15
|
# project or build configuration
|
16
|
-
self.repo_slug = env[
|
17
|
-
self.pull_request_id = env[
|
18
|
-
self.repo_url = env[
|
16
|
+
self.repo_slug = env["GITHUB_REPO_SLUG"]
|
17
|
+
self.pull_request_id = env["GITHUB_PULL_REQUEST_ID"].to_i
|
18
|
+
self.repo_url = env["GITHUB_REPO_URL"]
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
@@ -5,9 +5,9 @@ module Danger
|
|
5
5
|
module CISource
|
6
6
|
class Travis < CI
|
7
7
|
def self.validates?(env)
|
8
|
-
return false unless env[
|
9
|
-
return false unless env[
|
10
|
-
return false unless env[
|
8
|
+
return false unless env["HAS_JOSH_K_SEAL_OF_APPROVAL"]
|
9
|
+
return false unless env["TRAVIS_REPO_SLUG"]
|
10
|
+
return false unless env["TRAVIS_PULL_REQUEST"]
|
11
11
|
|
12
12
|
return true
|
13
13
|
end
|
@@ -17,9 +17,9 @@ module Danger
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def initialize(env)
|
20
|
-
self.repo_slug = env[
|
21
|
-
if env[
|
22
|
-
self.pull_request_id = env[
|
20
|
+
self.repo_slug = env["TRAVIS_REPO_SLUG"]
|
21
|
+
if env["TRAVIS_PULL_REQUEST"].to_i > 0
|
22
|
+
self.pull_request_id = env["TRAVIS_PULL_REQUEST"]
|
23
23
|
end
|
24
24
|
self.repo_url = GitRepo.new.origins # Travis doesn't provide a repo url env variable :/
|
25
25
|
end
|
@@ -4,7 +4,7 @@ module Danger
|
|
4
4
|
module CISource
|
5
5
|
class XcodeServer < CI
|
6
6
|
def self.validates?(env)
|
7
|
-
return false unless env[
|
7
|
+
return false unless env["XCS_BOT_NAME"]
|
8
8
|
|
9
9
|
return true
|
10
10
|
end
|
@@ -14,7 +14,7 @@ module Danger
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def initialize(env)
|
17
|
-
bot_name = env[
|
17
|
+
bot_name = env["XCS_BOT_NAME"]
|
18
18
|
return if bot_name.nil?
|
19
19
|
|
20
20
|
repo_matches = bot_name.match(/\[(.+)\]/)
|
data/lib/danger/commands/init.rb
CHANGED
@@ -1,27 +1,27 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "danger/commands/init_helpers/interviewer"
|
2
|
+
require "danger/ci_source/local_git_repo"
|
3
|
+
require "yaml"
|
4
4
|
|
5
5
|
module Danger
|
6
6
|
class Init < Runner
|
7
|
-
self.summary =
|
8
|
-
self.command =
|
7
|
+
self.summary = "Helps you set up Danger."
|
8
|
+
self.command = "init"
|
9
9
|
|
10
10
|
attr_accessor :ui
|
11
11
|
|
12
12
|
def self.options
|
13
13
|
[
|
14
|
-
[
|
15
|
-
[
|
14
|
+
["--impatient", "'I've not got all day here. Don't add any thematic delays please.'"],
|
15
|
+
["--mousey", "'Don't make me press return to continue the adventure.'"]
|
16
16
|
].concat(super)
|
17
17
|
end
|
18
18
|
|
19
19
|
def initialize(argv)
|
20
|
-
@bot_name = File.basename(Dir.getwd).split(
|
20
|
+
@bot_name = File.basename(Dir.getwd).split(".").first.capitalize + "Bot"
|
21
21
|
super
|
22
22
|
@ui = Interviewer.new(cork)
|
23
|
-
ui.no_delay = argv.flag?(
|
24
|
-
ui.no_waiting = argv.flag?(
|
23
|
+
ui.no_delay = argv.flag?("impatient", false)
|
24
|
+
ui.no_waiting = argv.flag?("mousey", false)
|
25
25
|
end
|
26
26
|
|
27
27
|
def run
|
@@ -43,34 +43,34 @@ module Danger
|
|
43
43
|
def show_todo_state
|
44
44
|
ui.say "We need to do the following:\n"
|
45
45
|
ui.pause 0.6
|
46
|
-
ui.say
|
46
|
+
ui.say " - [ ] Create a Dangerfile and add a few simple rules."
|
47
47
|
ui.pause 0.6
|
48
48
|
ui.say " - [#{@account_created ? 'x' : ' '}] Create a GitHub account for Danger to use, for messaging."
|
49
49
|
ui.pause 0.6
|
50
|
-
ui.say
|
50
|
+
ui.say " - [ ] Set up an access token for Danger."
|
51
51
|
ui.pause 0.6
|
52
52
|
ui.say " - [ ] Set up Danger to run on your CI.\n\n"
|
53
53
|
end
|
54
54
|
|
55
55
|
def setup_dangerfile
|
56
56
|
dir = Danger.gem_path
|
57
|
-
content = File.read(File.join(dir,
|
58
|
-
File.write(
|
57
|
+
content = File.read(File.join(dir, "lib", "assets", "DangerfileTemplate"))
|
58
|
+
File.write("Dangerfile", content)
|
59
59
|
|
60
|
-
ui.header
|
60
|
+
ui.header "Step 1: Creating a starter Dangerfile"
|
61
61
|
ui.say "I've set up an example Dangerfile for you in this folder.\n"
|
62
62
|
ui.pause 1
|
63
63
|
|
64
64
|
ui.say "cat #{Dir.pwd}/Dangerfile\n".blue
|
65
65
|
content.lines.each do |l|
|
66
|
-
ui.say
|
66
|
+
ui.say " " + l.chomp.green
|
67
67
|
end
|
68
|
-
ui.say
|
68
|
+
ui.say ""
|
69
69
|
ui.pause 2
|
70
70
|
|
71
71
|
ui.say "There's a collection of small, simple ideas in here, but Danger is about being able to easily"
|
72
|
-
ui.say
|
73
|
-
ui.say
|
72
|
+
ui.say "iterate. The power comes from you having the ability to codify fixes for some of the problems"
|
73
|
+
ui.say "that come up in day to day programming. It can be difficult to try and see those from day 1."
|
74
74
|
|
75
75
|
ui.say "\nIf you'd like to investigate the file, and make some changes - I'll wait here,"
|
76
76
|
ui.say "press return when you're ready to move on..."
|
@@ -78,7 +78,7 @@ module Danger
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def setup_github_account
|
81
|
-
ui.header
|
81
|
+
ui.header "Step 2: Creating a GitHub account"
|
82
82
|
|
83
83
|
ui.say "In order to get the most out of Danger, I'd recommend giving her the ability to post in"
|
84
84
|
ui.say "the code-review comment section.\n\n"
|
@@ -87,11 +87,11 @@ module Danger
|
|
87
87
|
ui.say "IMO, it's best to do this by using the private mode of your browser. Create an account like"
|
88
88
|
ui.say "#{@bot_name}, and don't forget a cool robot avatar.\n\n"
|
89
89
|
ui.pause 1
|
90
|
-
ui.say
|
91
|
-
ui.link
|
92
|
-
ui.link
|
90
|
+
ui.say "Here are great resources for creative commons images of robots:"
|
91
|
+
ui.link "https://www.flickr.com/search/?text=robot&license=2%2C3%2C4%2C5%2C6%2C9"
|
92
|
+
ui.link "https://www.google.com/search?q=robot&tbs=sur:fmc&tbm=isch&tbo=u&source=univ&sa=X&ved=0ahUKEwjgy8-f95jLAhWI7hoKHV_UD00QsAQIMQ&biw=1265&bih=1359"
|
93
93
|
|
94
|
-
ui.say
|
94
|
+
ui.say ""
|
95
95
|
note_about_clicking_links
|
96
96
|
ui.pause 1
|
97
97
|
ui.say "\nCool, please press return when you have your account ready (and you've verified the email...)"
|
@@ -99,28 +99,29 @@ module Danger
|
|
99
99
|
end
|
100
100
|
|
101
101
|
def setup_access_token
|
102
|
-
ui.header
|
102
|
+
ui.header "Step 3: Configuring a GitHub Personal Access Token"
|
103
103
|
|
104
104
|
ui.say "Here's the link, you should open this in the private session where you just created the new GitHub account"
|
105
|
-
ui.link
|
105
|
+
ui.link "https://github.com/settings/tokens/new"
|
106
106
|
ui.pause 1
|
107
107
|
|
108
|
-
@is_open_source = ui.ask_with_answers("For token access rights, I need to know if this is for an Open Source or Closed Source project\n", [
|
108
|
+
@is_open_source = ui.ask_with_answers("For token access rights, I need to know if this is for an Open Source or Closed Source project\n", ["Open", "Closed"])
|
109
109
|
|
110
110
|
if considered_an_oss_repo?
|
111
111
|
ui.say "For Open Source projects, I'd recommend giving the token the smallest scope possible."
|
112
|
-
ui.say
|
112
|
+
ui.say "This means only providing access to " + "public_repo".yellow + " in the token.\n\n"
|
113
113
|
ui.pause 1
|
114
114
|
ui.say "This token limits Danger's abilities to just writing comments on OSS projects. I recommend"
|
115
|
-
ui.say
|
115
|
+
ui.say "this because the token can quite easily be extracted from the environment via pull requests."
|
116
116
|
ui.say "#{@bot_name} does not need admin access to your repo. So its ability to cause chaos is minimalized.\n"
|
117
117
|
|
118
|
-
|
118
|
+
ui.say "\nIt is important that you do not store this token in your repository, as GitHub will automatically revoke it when pushed.\n"
|
119
|
+
elsif @is_open_source == "closed"
|
119
120
|
ui.say "For Closed Source projects, I'd recommend giving the token access to the whole repo scope."
|
120
|
-
ui.say
|
121
|
+
ui.say "This means only providing access to " + "repo".yellow + ", and its children in the token.\n\n"
|
121
122
|
ui.pause 1
|
122
|
-
ui.say "It's worth noting that you " +
|
123
|
-
ui.say
|
123
|
+
ui.say "It's worth noting that you " + "should not".bold.white + " re-use this token for OSS repos."
|
124
|
+
ui.say "Make a new one for those repos with just " + "public_repo".yellow + "."
|
124
125
|
ui.pause 1
|
125
126
|
ui.say "Additionally, don't forget to add your new GitHub account as a collaborator to your Closed Source project."
|
126
127
|
end
|
@@ -130,85 +131,85 @@ module Danger
|
|
130
131
|
end
|
131
132
|
|
132
133
|
def considered_an_oss_repo?
|
133
|
-
@is_open_source ==
|
134
|
+
@is_open_source == "open"
|
134
135
|
end
|
135
136
|
|
136
137
|
def current_repo_slug
|
137
138
|
@git = GitRepo.new
|
138
139
|
repo_matches = @git.origins.match(%r{([\/:])([^\/]+\/[^\/.]+)(?:.git)?$})
|
139
|
-
repo_matches[2] ||
|
140
|
+
repo_matches[2] || "[Your/Repo]"
|
140
141
|
end
|
141
142
|
|
142
143
|
def setup_danger_ci
|
143
|
-
ui.header
|
144
|
+
ui.header "Step 4: Add Danger for your CI"
|
144
145
|
|
145
|
-
uses_travis if File.exist?
|
146
|
-
uses_circle if File.exist?
|
147
|
-
unsure_ci unless File.exist?(
|
146
|
+
uses_travis if File.exist? ".travis.yml"
|
147
|
+
uses_circle if File.exist? "circle.yml"
|
148
|
+
unsure_ci unless File.exist?(".travis.yml") || File.exist?(".circle.yml")
|
148
149
|
|
149
150
|
ui.say "\nOK, I'll give you a moment to do this..."
|
150
151
|
ui.wait_for_return
|
151
152
|
|
152
|
-
ui.header
|
153
|
+
ui.header "Final step: exposing the GitHub token as an environment build variable."
|
153
154
|
ui.pause 0.4
|
154
155
|
if considered_an_oss_repo?
|
155
|
-
ui.say
|
156
|
+
ui.say "As you have an Open Source repo, this token should be considered public, otherwise you cannot"
|
156
157
|
ui.say "run Danger on pull requests from forks, limiting its use.\n"
|
157
158
|
ui.pause 1
|
158
159
|
end
|
159
160
|
|
160
|
-
travis_token if File.exist?
|
161
|
-
circle_token if File.exist?
|
162
|
-
unsure_token unless File.exist?(
|
161
|
+
travis_token if File.exist? ".travis.yml"
|
162
|
+
circle_token if File.exist? "circle.yml"
|
163
|
+
unsure_token unless File.exist?(".travis.yml") || File.exist?(".circle.yml")
|
163
164
|
|
164
165
|
ui.pause 0.6
|
165
|
-
ui.say
|
166
|
+
ui.say "This is the last step, I can give you a second..."
|
166
167
|
ui.wait_for_return
|
167
168
|
end
|
168
169
|
|
169
170
|
def uses_travis
|
170
|
-
danger =
|
171
|
-
config = YAML.load(File.read(
|
172
|
-
if config[
|
173
|
-
ui.say
|
171
|
+
danger = "bundle exec danger".yellow
|
172
|
+
config = YAML.load(File.read(".travis.yml"))
|
173
|
+
if config["script"]
|
174
|
+
ui.say "Add " + "- ".yellow + danger + " as a new step in the " + "script".yellow + " section of your .travis.yml file."
|
174
175
|
else
|
175
|
-
ui.say "I'd recommend adding " +
|
176
|
+
ui.say "I'd recommend adding " + "script: ".yellow + danger + " to the script section of your .travis.yml file."
|
176
177
|
end
|
177
178
|
|
178
179
|
ui.pause 1
|
179
|
-
ui.say "You shouldn't use " +
|
180
|
+
ui.say "You shouldn't use " + "after_success, after_failure, after_script".red + " as they cannot fail your builds."
|
180
181
|
end
|
181
182
|
|
182
183
|
def uses_circle
|
183
|
-
danger =
|
184
|
-
config = YAML.load(File.read(
|
184
|
+
danger = "- bundle exec danger".yellow
|
185
|
+
config = YAML.load(File.read("circle.yml"))
|
185
186
|
|
186
|
-
if config[
|
187
|
-
if config[
|
188
|
-
ui.say
|
187
|
+
if config["test"]
|
188
|
+
if config["test"]["post"]
|
189
|
+
ui.say "Add " + danger + " as a new step in the " + "test:post:".yellow + " section of your circle.yml file."
|
189
190
|
else
|
190
|
-
ui.say
|
191
|
+
ui.say "Add " + danger + " as a new step in the " + "test:override:".yellow + " section of your circle.yml file."
|
191
192
|
end
|
192
193
|
else
|
193
|
-
ui.say
|
194
|
-
ui.say
|
195
|
-
ui.say
|
194
|
+
ui.say "Add this to the bottom of your circle.yml file:"
|
195
|
+
ui.say "test:".green
|
196
|
+
ui.say " post:".green
|
196
197
|
ui.say " #{danger}".green
|
197
198
|
end
|
198
199
|
end
|
199
200
|
|
200
201
|
def unsure_ci
|
201
|
-
danger =
|
202
|
+
danger = "bundle exec danger".yellow
|
202
203
|
ui.say "As I'm not sure what CI you want to run Danger on based on the files in your repo, I'll just offer some generic"
|
203
|
-
ui.say
|
204
|
-
ui.say
|
204
|
+
ui.say "advice. You want to run " + danger + " after your tests have finished running, it should still be during the testing"
|
205
|
+
ui.say "process so the build can fail."
|
205
206
|
end
|
206
207
|
|
207
208
|
def travis_token
|
208
209
|
# https://travis-ci.org/artsy/eigen/settings
|
209
|
-
ui.say
|
210
|
+
ui.say "In order to add an environment variable, go to:"
|
210
211
|
ui.link "https://travis-ci.org/#{current_repo_slug}/settings"
|
211
|
-
ui.say "\nThe name is " +
|
212
|
+
ui.say "\nThe name is " + "DANGER_GITHUB_API_TOKEN".yellow + " and the value is the GitHub Personal Access Token."
|
212
213
|
if @is_open_source
|
213
214
|
ui.say 'Make sure to have "Display value in build log" enabled.'
|
214
215
|
end
|
@@ -218,44 +219,50 @@ module Danger
|
|
218
219
|
# https://circleci.com/gh/artsy/eigen/edit#env-vars
|
219
220
|
if considered_an_oss_repo?
|
220
221
|
ui.say "Before we start, it's important to be up-front. CircleCI only really has one option to support running Danger"
|
221
|
-
ui.say
|
222
|
+
ui.say "for forks on OSS repos. It is quite a drastic option, and I want to let you know the best place to understand"
|
222
223
|
ui.say "the ramifications of turning on a setting I'm about to advise.\n"
|
223
|
-
ui.link
|
224
|
-
ui.say
|
224
|
+
ui.link "https://circleci.com/docs/fork-pr-builds"
|
225
|
+
ui.say "TLDR: If you have anything other than Danger config settings in CircleCI, then you should not turn on the setting."
|
225
226
|
ui.say "I'll give you a minute to read it..."
|
226
227
|
ui.wait_for_return
|
227
228
|
|
228
|
-
ui.say
|
229
|
-
ui.say
|
229
|
+
ui.say "On Danger/Danger we turn on " + "Permissive building of fork pull requests".yellow + " this exposes the token to Danger"
|
230
|
+
ui.say "You can find this setting at:"
|
230
231
|
ui.link "https://circleci.com/gh/#{current_repo_slug}/edit#advanced-settings\n"
|
231
232
|
ui.say "I'll hold..."
|
232
233
|
ui.wait_for_return
|
233
234
|
end
|
234
235
|
|
235
|
-
ui.say
|
236
|
+
ui.say "In order to expose an environment variable, go to:"
|
236
237
|
ui.link "https://circleci.com/gh/#{current_repo_slug}/edit#env-vars"
|
237
|
-
ui.say
|
238
|
+
ui.say "The name is " + "DANGER_GITHUB_API_TOKEN".yellow + " and the value is the GitHub Personal Acess Token."
|
238
239
|
end
|
239
240
|
|
240
241
|
def unsure_token
|
241
|
-
ui.say
|
242
|
-
ui.say
|
242
|
+
ui.say "You need to expose a token called " + "DANGER_GITHUB_API_TOKEN".yellow + " and the value is the GitHub Personal Acess Token."
|
243
|
+
ui.say "Depending on the CI system, this may need to be done on the machine ( in the " + "~/.bashprofile".yellow + ") or in a web UI somewhere."
|
243
244
|
end
|
244
245
|
|
245
246
|
def note_about_clicking_links
|
246
|
-
|
247
|
+
modifier_key = "ctrl"
|
248
|
+
clicks = "clicking"
|
249
|
+
|
250
|
+
modifier_key = "cmd ( ⌘ )" if darwin?
|
251
|
+
clicks = "double clicking" if darwin? && !ENV["ITERM_SESSION_ID"]
|
252
|
+
|
253
|
+
ui.say "Note: Holding #{modifier_key} and #{clicks} a link will open it in your browser."
|
247
254
|
end
|
248
255
|
|
249
256
|
def info
|
250
|
-
ui.header
|
251
|
-
ui.say
|
257
|
+
ui.header "Useful info"
|
258
|
+
ui.say "- One of the best ways to test out new rules locally is via " + "bundle exec danger local".yellow + "."
|
252
259
|
ui.pause 0.6
|
253
|
-
ui.say
|
260
|
+
ui.say "- You can have Danger output all of its variables to the console via the " + "--verbose".yellow + " option."
|
254
261
|
ui.pause 0.6
|
255
|
-
ui.say
|
262
|
+
ui.say "- You can look at the following Dangerfiles to get some more ideas:"
|
256
263
|
ui.pause 0.6
|
257
|
-
ui.link
|
258
|
-
ui.link
|
264
|
+
ui.link "https://github.com/danger/danger/blob/master/Dangerfile"
|
265
|
+
ui.link "https://github.com/artsy/eigen/blob/master/Dangerfile"
|
259
266
|
ui.pause 1
|
260
267
|
end
|
261
268
|
|
@@ -264,8 +271,12 @@ module Danger
|
|
264
271
|
ui.pause 0.6
|
265
272
|
|
266
273
|
ui.say "And you're good to go. Danger is a collaboration between Orta Therox, Gem 'Danger' McShane and Felix Krause."
|
267
|
-
ui.say
|
274
|
+
ui.say "If you like it, let others know. If you want to know more, follow " + "@orta".yellow + " and " + "@KrauseFx".yellow + " on Twitter."
|
268
275
|
ui.say "If you don't like it, help us improve it! xxx"
|
269
276
|
end
|
277
|
+
|
278
|
+
def darwin?
|
279
|
+
Gem::Platform.local.os == "darwin"
|
280
|
+
end
|
270
281
|
end
|
271
282
|
end
|