danger 8.2.1 → 8.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/danger/ci_source/azure_pipelines.rb +5 -1
- data/lib/danger/ci_source/buildkite.rb +1 -1
- data/lib/danger/ci_source/codefresh.rb +7 -13
- data/lib/danger/ci_source/codemagic.rb +58 -0
- data/lib/danger/ci_source/gitlab_ci.rb +18 -17
- data/lib/danger/ci_source/jenkins.rb +1 -1
- data/lib/danger/ci_source/local_git_repo.rb +29 -37
- data/lib/danger/ci_source/local_only_git_repo.rb +4 -8
- data/lib/danger/ci_source/support/commits.rb +14 -12
- data/lib/danger/ci_source/support/pull_request_finder.rb +43 -40
- data/lib/danger/ci_source/xcode_cloud.rb +38 -0
- data/lib/danger/commands/dangerfile/init.rb +1 -1
- data/lib/danger/commands/pr.rb +2 -1
- data/lib/danger/comment_generators/gitlab_inline.md.erb +2 -7
- data/lib/danger/comment_generators/vsts_inline.md.erb +17 -0
- data/lib/danger/danger_core/dangerfile.rb +15 -8
- data/lib/danger/danger_core/environment_manager.rb +2 -0
- data/lib/danger/danger_core/plugins/dangerfile_git_plugin.rb +1 -1
- data/lib/danger/danger_core/plugins/dangerfile_github_plugin.rb +8 -0
- data/lib/danger/danger_core/plugins/dangerfile_gitlab_plugin.rb +16 -0
- data/lib/danger/helpers/array_subclass.rb +2 -2
- data/lib/danger/helpers/comments_helper.rb +4 -3
- data/lib/danger/helpers/emoji_mapper.rb +1 -1
- data/lib/danger/plugin_support/plugin.rb +6 -2
- data/lib/danger/request_sources/bitbucket_cloud.rb +0 -1
- data/lib/danger/request_sources/bitbucket_cloud_api.rb +7 -6
- data/lib/danger/request_sources/bitbucket_server.rb +20 -16
- data/lib/danger/request_sources/bitbucket_server_api.rb +17 -9
- data/lib/danger/request_sources/code_insights_api.rb +2 -3
- data/lib/danger/request_sources/github/github.rb +30 -26
- data/lib/danger/request_sources/gitlab.rb +24 -24
- data/lib/danger/request_sources/local_only.rb +1 -2
- data/lib/danger/request_sources/request_source.rb +16 -4
- data/lib/danger/request_sources/vsts.rb +171 -9
- data/lib/danger/request_sources/vsts_api.rb +34 -3
- data/lib/danger/scm_source/git_repo.rb +2 -1
- data/lib/danger/version.rb +1 -1
- metadata +17 -8
@@ -49,22 +49,26 @@ module Danger
|
|
49
49
|
# However, as we're using using them in the DSL, they won't
|
50
50
|
# get method_missing called correctly without overriding them.
|
51
51
|
|
52
|
-
def warn(*args, &blk)
|
53
|
-
method_missing(:warn, *args, &blk)
|
52
|
+
def warn(*args, **kargs, &blk)
|
53
|
+
method_missing(:warn, *args, **kargs, &blk)
|
54
54
|
end
|
55
55
|
|
56
|
-
def fail(*args, &blk)
|
57
|
-
method_missing(:fail, *args, &blk)
|
56
|
+
def fail(*args, **kargs, &blk)
|
57
|
+
method_missing(:fail, *args, **kargs, &blk)
|
58
58
|
end
|
59
59
|
|
60
60
|
# When an undefined method is called, we check to see if it's something
|
61
61
|
# that the core DSLs have, then starts looking at plugins support.
|
62
62
|
|
63
63
|
# rubocop:disable Style/MethodMissing
|
64
|
-
def method_missing(method_sym, *arguments, &_block)
|
64
|
+
def method_missing(method_sym, *arguments, **keyword_arguments, &_block)
|
65
65
|
@core_plugins.each do |plugin|
|
66
66
|
if plugin.public_methods(false).include?(method_sym)
|
67
|
-
|
67
|
+
if keyword_arguments.empty?
|
68
|
+
return plugin.send(method_sym, *arguments)
|
69
|
+
else
|
70
|
+
return plugin.send(method_sym, *arguments, **keyword_arguments)
|
71
|
+
end
|
68
72
|
end
|
69
73
|
end
|
70
74
|
super
|
@@ -270,7 +274,7 @@ module Danger
|
|
270
274
|
env.scm.diff_for_folder(".".freeze, from: base_branch, to: head_branch, lookup_top_level: true)
|
271
275
|
end
|
272
276
|
|
273
|
-
def run(base_branch, head_branch, dangerfile_path, danger_id, new_comment, remove_previous_comments)
|
277
|
+
def run(base_branch, head_branch, dangerfile_path, danger_id, new_comment, remove_previous_comments, report_results = true)
|
274
278
|
# Setup internal state
|
275
279
|
init_plugins
|
276
280
|
env.fill_environment_vars
|
@@ -285,7 +289,7 @@ module Danger
|
|
285
289
|
# Push results to the API
|
286
290
|
# Pass along the details of the run to the request source
|
287
291
|
# to send back to the code review site.
|
288
|
-
post_results(danger_id, new_comment, remove_previous_comments)
|
292
|
+
post_results(danger_id, new_comment, remove_previous_comments) if report_results
|
289
293
|
|
290
294
|
# Print results in the terminal
|
291
295
|
print_results
|
@@ -331,6 +335,9 @@ module Danger
|
|
331
335
|
end
|
332
336
|
|
333
337
|
def post_exception(ex, danger_id, new_comment)
|
338
|
+
return if ENV["DANGER_DO_NOT_POST_INVALID_DANGERFILE_ERROR"]
|
339
|
+
return if danger_id.nil?
|
340
|
+
|
334
341
|
env.request_source.update_pull_request!(
|
335
342
|
danger_id: danger_id,
|
336
343
|
new_comment: new_comment,
|
@@ -128,7 +128,7 @@ module Danger
|
|
128
128
|
# @return [Git::Diff::DiffFile] from the gem `git`
|
129
129
|
#
|
130
130
|
def diff_for_file(file)
|
131
|
-
(added_files + modified_files).include?(file) ? @git.diff[file] : nil
|
131
|
+
(added_files + modified_files + deleted_files).include?(file) ? @git.diff[file] : nil
|
132
132
|
end
|
133
133
|
|
134
134
|
# @!group Git Metadata
|
@@ -143,6 +143,14 @@ module Danger
|
|
143
143
|
@github.issue_json["labels"].map { |l| l[:name] }
|
144
144
|
end
|
145
145
|
|
146
|
+
# @!group PR Metadata
|
147
|
+
# Whether the PR is a Draft.
|
148
|
+
# @return [Boolean]
|
149
|
+
#
|
150
|
+
def pr_draft?
|
151
|
+
pr_json["draft"] == true
|
152
|
+
end
|
153
|
+
|
146
154
|
# @!group PR Commit Metadata
|
147
155
|
# The branch to which the PR is going to be merged into.
|
148
156
|
# @return [String]
|
@@ -131,6 +131,22 @@ module Danger
|
|
131
131
|
@gitlab.mr_diff
|
132
132
|
end
|
133
133
|
|
134
|
+
# @!group MR Changes
|
135
|
+
# The array of changes
|
136
|
+
# @return [Array<Gitlab::ObjectifiedHash>]
|
137
|
+
#
|
138
|
+
def mr_changes
|
139
|
+
@gitlab.mr_changes.changes
|
140
|
+
end
|
141
|
+
|
142
|
+
# @!group MR Closes issues
|
143
|
+
# The array of issues that this MR closes
|
144
|
+
# @return [Array<Gitlab::ObjectifiedHash>]
|
145
|
+
#
|
146
|
+
def mr_closes_issues
|
147
|
+
@gitlab.mr_closes_issues
|
148
|
+
end
|
149
|
+
|
134
150
|
# @!group MR Commit Metadata
|
135
151
|
# The branch to which the MR is going to be merged into
|
136
152
|
# @deprecated Please use {#branch_for_base} instead
|
@@ -19,8 +19,8 @@ module Danger
|
|
19
19
|
respond_to_method(name, *args, &block)
|
20
20
|
end
|
21
21
|
|
22
|
-
def respond_to_missing?(name)
|
23
|
-
__array__.respond_to?(name) || super
|
22
|
+
def respond_to_missing?(name, include_all)
|
23
|
+
__array__.respond_to?(name, include_all) || super
|
24
24
|
end
|
25
25
|
|
26
26
|
def to_a
|
@@ -24,7 +24,8 @@ module Danger
|
|
24
24
|
# @param [Bool] Should hide any generated link created
|
25
25
|
#
|
26
26
|
# @return [String] The Markdown compatible link
|
27
|
-
def markdown_link_to_message(message,
|
27
|
+
def markdown_link_to_message(message, hide_link)
|
28
|
+
return "" if hide_link
|
28
29
|
"#{message.file}#L#{message.line}"
|
29
30
|
end
|
30
31
|
|
@@ -147,8 +148,8 @@ module Danger
|
|
147
148
|
|
148
149
|
def generate_description(warnings: nil, errors: nil, template: "github")
|
149
150
|
emoji_mapper = EmojiMapper.new(template)
|
150
|
-
if errors.empty? && warnings.empty?
|
151
|
-
return "All green. #{random_compliment}"
|
151
|
+
if (errors.nil? || errors.empty?) && (warnings.nil? || warnings.empty?)
|
152
|
+
return ENV['DANGER_SUCCESS_MESSAGE'] || "All green. #{random_compliment}"
|
152
153
|
else
|
153
154
|
message = "#{emoji_mapper.map('warning')} "
|
154
155
|
message += "#{'Error'.danger_pluralize(errors.count)}. " unless errors.empty?
|
@@ -19,8 +19,12 @@ module Danger
|
|
19
19
|
# We need to redirect the self calls to the Dangerfile
|
20
20
|
|
21
21
|
# rubocop:disable Style/MethodMissing
|
22
|
-
def method_missing(method_sym, *arguments, &block)
|
23
|
-
|
22
|
+
def method_missing(method_sym, *arguments, **keyword_arguments, &block)
|
23
|
+
if keyword_arguments.empty?
|
24
|
+
@dangerfile.send(method_sym, *arguments, &block)
|
25
|
+
else
|
26
|
+
@dangerfile.send(method_sym, *arguments, **keyword_arguments, &block)
|
27
|
+
end
|
24
28
|
end
|
25
29
|
|
26
30
|
def self.all_plugins
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# coding: utf-8
|
2
3
|
|
3
4
|
require "danger/helpers/comments_helper"
|
@@ -32,9 +33,8 @@ module Danger
|
|
32
33
|
def inspect
|
33
34
|
inspected = super
|
34
35
|
|
35
|
-
if @password
|
36
|
-
|
37
|
-
end
|
36
|
+
inspected.gsub!(@password, "********") if @password
|
37
|
+
inspected.gsub!(@access_token, "********") if @access_token
|
38
38
|
|
39
39
|
inspected
|
40
40
|
end
|
@@ -95,12 +95,13 @@ module Danger
|
|
95
95
|
"#{base_url(2)}/#{pull_request_id}"
|
96
96
|
end
|
97
97
|
|
98
|
-
def
|
99
|
-
|
98
|
+
def prs_api_url(branch_name)
|
99
|
+
encoded_branch_name = URI.encode_www_form_component(branch_name)
|
100
|
+
"#{base_url(2)}?q=source.branch.name=\"#{encoded_branch_name}\""
|
100
101
|
end
|
101
102
|
|
102
103
|
def fetch_pr_from_branch(branch_name)
|
103
|
-
uri = URI(
|
104
|
+
uri = URI(prs_api_url(branch_name))
|
104
105
|
fetch_json(uri)[:values][0][:id]
|
105
106
|
end
|
106
107
|
|
@@ -20,16 +20,17 @@ module Danger
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def self.optional_env_vars
|
23
|
-
[
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
[
|
24
|
+
"DANGER_BITBUCKETSERVER_CODE_INSIGHTS_REPORT_KEY",
|
25
|
+
"DANGER_BITBUCKETSERVER_CODE_INSIGHTS_REPORT_TITLE",
|
26
|
+
"DANGER_BITBUCKETSERVER_CODE_INSIGHTS_REPORT_DESCRIPTION",
|
27
|
+
"DANGER_BITBUCKETSERVER_CODE_INSIGHTS_REPORT_LOGO_URL",
|
28
|
+
"DANGER_BITBUCKETSERVER_VERIFY_SSL"
|
27
29
|
]
|
28
30
|
end
|
29
31
|
|
30
32
|
def initialize(ci_source, environment)
|
31
33
|
self.ci_source = ci_source
|
32
|
-
self.environment = environment
|
33
34
|
|
34
35
|
project, slug = ci_source.repo_slug.split("/")
|
35
36
|
@api = BitbucketServerAPI.new(project, slug, ci_source.pull_request_id, environment)
|
@@ -110,17 +111,20 @@ module Danger
|
|
110
111
|
markdowns = main_violations[:markdowns] || []
|
111
112
|
end
|
112
113
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
114
|
+
has_comments = (warnings.count > 0 || errors.count > 0 || messages.count > 0 || markdowns.count > 0)
|
115
|
+
if has_comments
|
116
|
+
comment = generate_description(warnings: warnings,
|
117
|
+
errors: errors)
|
118
|
+
comment += "\n\n"
|
119
|
+
comment += generate_comment(warnings: warnings,
|
120
|
+
errors: errors,
|
121
|
+
messages: messages,
|
122
|
+
markdowns: markdowns,
|
123
|
+
previous_violations: {},
|
124
|
+
danger_id: danger_id,
|
125
|
+
template: "bitbucket_server")
|
126
|
+
@api.post_comment(comment)
|
127
|
+
end
|
124
128
|
end
|
125
129
|
|
126
130
|
def delete_old_comments(danger_id: "danger")
|
@@ -1,16 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# coding: utf-8
|
2
3
|
|
4
|
+
require "openssl"
|
3
5
|
require "danger/helpers/comments_helper"
|
4
6
|
|
5
7
|
module Danger
|
6
8
|
module RequestSources
|
7
9
|
class BitbucketServerAPI
|
8
|
-
attr_accessor :host, :pr_api_endpoint, :key, :project
|
10
|
+
attr_accessor :host, :verify_ssl, :pr_api_endpoint, :key, :project
|
9
11
|
|
10
12
|
def initialize(project, slug, pull_request_id, environment)
|
11
13
|
@username = environment["DANGER_BITBUCKETSERVER_USERNAME"]
|
12
14
|
@password = environment["DANGER_BITBUCKETSERVER_PASSWORD"]
|
13
15
|
self.host = environment["DANGER_BITBUCKETSERVER_HOST"]
|
16
|
+
self.verify_ssl = environment["DANGER_BITBUCKETSERVER_VERIFY_SSL"] != "false"
|
14
17
|
if self.host && !(self.host.include? "http://") && !(self.host.include? "https://")
|
15
18
|
self.host = "https://" + self.host
|
16
19
|
end
|
@@ -22,9 +25,7 @@ module Danger
|
|
22
25
|
def inspect
|
23
26
|
inspected = super
|
24
27
|
|
25
|
-
if @password
|
26
|
-
inspected = inspected.sub! @password, "********".freeze
|
27
|
-
end
|
28
|
+
inspected.gsub!(@password, "********") if @password
|
28
29
|
|
29
30
|
inspected
|
30
31
|
end
|
@@ -57,7 +58,7 @@ module Danger
|
|
57
58
|
body = { text: text }.to_json
|
58
59
|
post(uri, body)
|
59
60
|
end
|
60
|
-
|
61
|
+
|
61
62
|
def update_pr_build_status(status, changeset, build_job_link, description)
|
62
63
|
uri = URI("#{self.host}/rest/build-status/1.0/commits/#{changeset}")
|
63
64
|
body = build_status_body(status, build_job_link, description)
|
@@ -73,7 +74,7 @@ module Danger
|
|
73
74
|
def fetch_json(uri)
|
74
75
|
req = Net::HTTP::Get.new(uri.request_uri, { "Content-Type" => "application/json" })
|
75
76
|
req.basic_auth @username, @password
|
76
|
-
res =
|
77
|
+
res = http(uri).start do |http|
|
77
78
|
http.request(req)
|
78
79
|
end
|
79
80
|
JSON.parse(res.body, symbolize_names: true)
|
@@ -84,7 +85,7 @@ module Danger
|
|
84
85
|
req.basic_auth @username, @password
|
85
86
|
req.body = body
|
86
87
|
|
87
|
-
res =
|
88
|
+
res = http(uri).start do |http|
|
88
89
|
http.request(req)
|
89
90
|
end
|
90
91
|
|
@@ -99,11 +100,18 @@ module Danger
|
|
99
100
|
def delete(uri)
|
100
101
|
req = Net::HTTP::Delete.new(uri.request_uri, { "Content-Type" => "application/json" })
|
101
102
|
req.basic_auth @username, @password
|
102
|
-
|
103
|
+
http(uri).start do |http|
|
103
104
|
http.request(req)
|
104
105
|
end
|
105
106
|
end
|
106
|
-
|
107
|
+
|
108
|
+
def http(uri)
|
109
|
+
http = Net::HTTP.new(uri.hostname, uri.port)
|
110
|
+
http.use_ssl = use_ssl
|
111
|
+
http.verify_mode = verify_ssl ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
|
112
|
+
http
|
113
|
+
end
|
114
|
+
|
107
115
|
def build_status_body(status, build_job_link, description)
|
108
116
|
body = Hash.new
|
109
117
|
body["state"] = status
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# coding: utf-8
|
2
3
|
|
3
4
|
module Danger
|
@@ -26,9 +27,7 @@ module Danger
|
|
26
27
|
def inspect
|
27
28
|
inspected = super
|
28
29
|
|
29
|
-
if @password
|
30
|
-
inspected = inspected.sub! @password, "********".freeze
|
31
|
-
end
|
30
|
+
inspected.gsub!(@password, "********") if @password
|
32
31
|
|
33
32
|
inspected
|
34
33
|
end
|
@@ -14,10 +14,10 @@ module Danger
|
|
14
14
|
class GitHub < RequestSource
|
15
15
|
include Danger::Helpers::CommentsHelper
|
16
16
|
|
17
|
-
attr_accessor :pr_json, :issue_json, :support_tokenless_auth, :dismiss_out_of_range_messages
|
17
|
+
attr_accessor :pr_json, :issue_json, :use_local_git, :support_tokenless_auth, :dismiss_out_of_range_messages, :host, :api_url, :verify_ssl
|
18
18
|
|
19
19
|
def self.env_vars
|
20
|
-
["DANGER_GITHUB_API_TOKEN"]
|
20
|
+
["DANGER_GITHUB_API_TOKEN", "DANGER_GITHUB_BEARER_TOKEN"]
|
21
21
|
end
|
22
22
|
|
23
23
|
def self.optional_env_vars
|
@@ -26,11 +26,22 @@ module Danger
|
|
26
26
|
|
27
27
|
def initialize(ci_source, environment)
|
28
28
|
self.ci_source = ci_source
|
29
|
-
self.
|
29
|
+
self.use_local_git = environment["DANGER_USE_LOCAL_GIT"]
|
30
30
|
self.support_tokenless_auth = false
|
31
31
|
self.dismiss_out_of_range_messages = false
|
32
|
+
self.host = environment.fetch("DANGER_GITHUB_HOST", "github.com")
|
33
|
+
# `DANGER_GITHUB_API_HOST` is the old name kept for legacy reasons and
|
34
|
+
# backwards compatibility. `DANGER_GITHUB_API_BASE_URL` is the new
|
35
|
+
# correctly named variable.
|
36
|
+
self.api_url = environment.fetch("DANGER_GITHUB_API_HOST") do
|
37
|
+
environment.fetch("DANGER_GITHUB_API_BASE_URL") do
|
38
|
+
"https://api.github.com/".freeze
|
39
|
+
end
|
40
|
+
end
|
41
|
+
self.verify_ssl = environment["DANGER_OCTOKIT_VERIFY_SSL"] != "false"
|
32
42
|
|
33
|
-
@
|
43
|
+
@access_token = environment["DANGER_GITHUB_API_TOKEN"]
|
44
|
+
@bearer_token = environment["DANGER_GITHUB_BEARER_TOKEN"]
|
34
45
|
end
|
35
46
|
|
36
47
|
def get_pr_from_branch(repo_name, branch_name, owner)
|
@@ -45,39 +56,24 @@ module Danger
|
|
45
56
|
end
|
46
57
|
|
47
58
|
def validates_as_api_source?
|
48
|
-
|
59
|
+
valid_bearer_token? || valid_access_token? || use_local_git
|
49
60
|
end
|
50
61
|
|
51
62
|
def scm
|
52
63
|
@scm ||= GitRepo.new
|
53
64
|
end
|
54
65
|
|
55
|
-
def host
|
56
|
-
@host = @environment["DANGER_GITHUB_HOST"] || "github.com"
|
57
|
-
end
|
58
|
-
|
59
|
-
def verify_ssl
|
60
|
-
@environment["DANGER_OCTOKIT_VERIFY_SSL"] == "false" ? false : true
|
61
|
-
end
|
62
|
-
|
63
|
-
# `DANGER_GITHUB_API_HOST` is the old name kept for legacy reasons and
|
64
|
-
# backwards compatibility. `DANGER_GITHUB_API_BASE_URL` is the new
|
65
|
-
# correctly named variable.
|
66
|
-
def api_url
|
67
|
-
@environment.fetch("DANGER_GITHUB_API_HOST") do
|
68
|
-
@environment.fetch("DANGER_GITHUB_API_BASE_URL") do
|
69
|
-
"https://api.github.com/".freeze
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
66
|
def client
|
75
|
-
raise "No API token given, please provide one using `DANGER_GITHUB_API_TOKEN`" if
|
67
|
+
raise "No API token given, please provide one using `DANGER_GITHUB_API_TOKEN` or `DANGER_GITHUB_BEARER_TOKEN`" if !valid_access_token? && !valid_bearer_token? && !support_tokenless_auth
|
76
68
|
@client ||= begin
|
77
69
|
Octokit.configure do |config|
|
78
70
|
config.connection_options[:ssl] = { verify: verify_ssl }
|
79
71
|
end
|
80
|
-
|
72
|
+
if valid_bearer_token?
|
73
|
+
Octokit::Client.new(bearer_token: @bearer_token, auto_paginate: true, api_endpoint: api_url)
|
74
|
+
elsif valid_access_token?
|
75
|
+
Octokit::Client.new(access_token: @access_token, auto_paginate: true, api_endpoint: api_url)
|
76
|
+
end
|
81
77
|
end
|
82
78
|
end
|
83
79
|
|
@@ -493,6 +489,14 @@ module Danger
|
|
493
489
|
|
494
490
|
private
|
495
491
|
|
492
|
+
def valid_access_token?
|
493
|
+
@access_token && !@access_token.empty?
|
494
|
+
end
|
495
|
+
|
496
|
+
def valid_bearer_token?
|
497
|
+
@bearer_token && !@bearer_token.empty?
|
498
|
+
end
|
499
|
+
|
496
500
|
def regular_violations_group(warnings: [], errors: [], messages: [], markdowns: [])
|
497
501
|
{
|
498
502
|
warnings: warnings.reject(&:inline?),
|
@@ -8,7 +8,7 @@ module Danger
|
|
8
8
|
module RequestSources
|
9
9
|
class GitLab < RequestSource
|
10
10
|
include Danger::Helpers::CommentsHelper
|
11
|
-
attr_accessor :mr_json, :commits_json, :dismiss_out_of_range_messages
|
11
|
+
attr_accessor :mr_json, :commits_json, :dismiss_out_of_range_messages, :endpoint, :host
|
12
12
|
|
13
13
|
FIRST_GITLAB_GEM_WITH_VERSION_CHECK = Gem::Version.new("4.6.0")
|
14
14
|
FIRST_VERSION_WITH_INLINE_COMMENTS = Gem::Version.new("10.8.0")
|
@@ -23,20 +23,19 @@ module Danger
|
|
23
23
|
|
24
24
|
def initialize(ci_source, environment)
|
25
25
|
self.ci_source = ci_source
|
26
|
-
self.environment = environment
|
27
26
|
self.dismiss_out_of_range_messages = false
|
28
|
-
|
29
|
-
@
|
27
|
+
@endpoint = environment["DANGER_GITLAB_API_BASE_URL"] || environment.fetch("CI_API_V4_URL", "https://gitlab.com/api/v4")
|
28
|
+
@host = environment.fetch("DANGER_GITLAB_HOST", URI.parse(endpoint).host) || "gitlab.com"
|
29
|
+
@token = environment["DANGER_GITLAB_API_TOKEN"]
|
30
30
|
end
|
31
31
|
|
32
32
|
def client
|
33
|
-
token
|
34
|
-
raise "No API token given, please provide one using `DANGER_GITLAB_API_TOKEN`" unless token
|
33
|
+
raise "No API token given, please provide one using `DANGER_GITLAB_API_TOKEN`" unless @token
|
35
34
|
|
36
35
|
# The require happens inline so that it won't cause exceptions when just using the `danger` gem.
|
37
36
|
require "gitlab"
|
38
37
|
|
39
|
-
@client ||= Gitlab.client(endpoint: endpoint, private_token: token)
|
38
|
+
@client ||= Gitlab.client(endpoint: endpoint, private_token: @token)
|
40
39
|
rescue LoadError => e
|
41
40
|
if e.path == "gitlab"
|
42
41
|
puts "The GitLab gem was not installed, you will need to change your Gem from `danger` to `danger-gitlab`.".red
|
@@ -48,7 +47,7 @@ module Danger
|
|
48
47
|
end
|
49
48
|
|
50
49
|
def validates_as_ci?
|
51
|
-
includes_port =
|
50
|
+
includes_port = host.include? ":"
|
52
51
|
raise "Port number included in `DANGER_GITLAB_HOST`, this will fail with GitLab CI Runners" if includes_port
|
53
52
|
|
54
53
|
# We don't call super because in some cases the Git remote doesn't match the GitLab instance host.
|
@@ -66,14 +65,6 @@ module Danger
|
|
66
65
|
@scm ||= GitRepo.new
|
67
66
|
end
|
68
67
|
|
69
|
-
def endpoint
|
70
|
-
@endpoint ||= @environment["DANGER_GITLAB_API_BASE_URL"] || @environment["CI_API_V4_URL"] || "https://gitlab.com/api/v4"
|
71
|
-
end
|
72
|
-
|
73
|
-
def host
|
74
|
-
@host ||= @environment["DANGER_GITLAB_HOST"] || URI.parse(endpoint).host || "gitlab.com"
|
75
|
-
end
|
76
|
-
|
77
68
|
def base_commit
|
78
69
|
@base_commit ||= self.mr_json.diff_refs.base_sha
|
79
70
|
end
|
@@ -85,7 +76,7 @@ module Danger
|
|
85
76
|
if supports_inline_comments
|
86
77
|
@raw_comments = mr_discussions
|
87
78
|
.auto_paginate
|
88
|
-
.flat_map { |discussion| discussion.notes.map { |note| note.merge({"discussion_id" => discussion.id}) } }
|
79
|
+
.flat_map { |discussion| discussion.notes.map { |note| note.to_h.merge({"discussion_id" => discussion.id}) } }
|
89
80
|
@raw_comments
|
90
81
|
.map { |comment| Comment.from_gitlab(comment) }
|
91
82
|
else
|
@@ -130,6 +121,12 @@ module Danger
|
|
130
121
|
end
|
131
122
|
end
|
132
123
|
|
124
|
+
def mr_closes_issues
|
125
|
+
@mr_closes_issues ||= begin
|
126
|
+
client.merge_request_closes_issues(ci_source.repo_slug, ci_source.pull_request_id)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
133
130
|
def setup_danger_branches
|
134
131
|
# we can use a GitLab specific feature here:
|
135
132
|
base_branch = self.mr_json.source_branch
|
@@ -298,6 +295,10 @@ module Danger
|
|
298
295
|
end
|
299
296
|
end
|
300
297
|
|
298
|
+
def markdown_link_to_message(message, _)
|
299
|
+
"#{message.file}#L#{message.line}: "
|
300
|
+
end
|
301
|
+
|
301
302
|
# @return [String] The organisation name, is nil if it can't be detected
|
302
303
|
def organisation
|
303
304
|
nil # TODO: Implement this
|
@@ -316,11 +317,10 @@ module Danger
|
|
316
317
|
# @return [String] A URL to the specific file, ready to be downloaded
|
317
318
|
def file_url(organisation: nil, repository: nil, branch: nil, path: nil)
|
318
319
|
branch ||= 'master'
|
319
|
-
token = @environment["DANGER_GITLAB_API_TOKEN"]
|
320
320
|
# According to GitLab Repositories API docs path and id(slug) should be encoded.
|
321
321
|
path = URI.encode_www_form_component(path)
|
322
322
|
repository = URI.encode_www_form_component(repository)
|
323
|
-
"#{endpoint}/projects/#{repository}/repository/files/#{path}/raw?ref=#{branch}&private_token=#{token}"
|
323
|
+
"#{endpoint}/projects/#{repository}/repository/files/#{path}/raw?ref=#{branch}&private_token=#{@token}"
|
324
324
|
end
|
325
325
|
|
326
326
|
def regular_violations_group(warnings: [], errors: [], messages: [], markdowns: [])
|
@@ -359,7 +359,7 @@ module Danger
|
|
359
359
|
def submit_inline_comments!(warnings: [], errors: [], messages: [], markdowns: [], previous_violations: [], danger_id: "danger")
|
360
360
|
comments = mr_discussions
|
361
361
|
.auto_paginate
|
362
|
-
.flat_map { |discussion| discussion.notes.map { |note| note.merge({"discussion_id" => discussion.id}) } }
|
362
|
+
.flat_map { |discussion| discussion.notes.map { |note| note.to_h.merge({"discussion_id" => discussion.id}) } }
|
363
363
|
.select { |comment| Comment.from_gitlab(comment).inline? }
|
364
364
|
|
365
365
|
danger_comments = comments.select { |comment| Comment.from_gitlab(comment).generated_by_danger?(danger_id) }
|
@@ -410,7 +410,7 @@ module Danger
|
|
410
410
|
next false unless m.file && m.line
|
411
411
|
# Reject if it's out of range and in dismiss mode
|
412
412
|
next true if dismiss_out_of_range_messages_for(kind) && is_out_of_range(mr_changes.changes, m)
|
413
|
-
|
413
|
+
|
414
414
|
# Once we know we're gonna submit it, we format it
|
415
415
|
if is_markdown_content
|
416
416
|
body = generate_inline_markdown_body(m, danger_id: danger_id, template: "gitlab")
|
@@ -531,10 +531,10 @@ module Danger
|
|
531
531
|
end
|
532
532
|
|
533
533
|
def is_out_of_range(changes, message)
|
534
|
-
change = changes.find { |c| c["new_path"] == message.file }
|
534
|
+
change = changes.find { |c| c["new_path"] == message.file }
|
535
535
|
# If there is no changes or rename only or deleted, return out of range.
|
536
536
|
return true if change.nil? || change["diff"].empty? || change["deleted_file"]
|
537
|
-
|
537
|
+
|
538
538
|
# If new file then return in range
|
539
539
|
return false if change["new_file"]
|
540
540
|
|
@@ -544,7 +544,7 @@ module Danger
|
|
544
544
|
return true
|
545
545
|
end
|
546
546
|
|
547
|
-
def generate_addition_lines(diff)
|
547
|
+
def generate_addition_lines(diff)
|
548
548
|
range_header_regexp = /@@ -(?<old>[0-9]+)(,([0-9]+))? \+(?<new>[0-9]+)(,([0-9]+))? @@.*/
|
549
549
|
addition_lines = []
|
550
550
|
line_number = 0
|