danger 8.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +22 -0
- data/README.md +94 -0
- data/bin/danger +5 -0
- data/lib/assets/DangerfileTemplate +13 -0
- data/lib/danger.rb +44 -0
- data/lib/danger/ci_source/appcenter.rb +55 -0
- data/lib/danger/ci_source/appveyor.rb +60 -0
- data/lib/danger/ci_source/azure_pipelines.rb +44 -0
- data/lib/danger/ci_source/bamboo.rb +41 -0
- data/lib/danger/ci_source/bitbucket_pipelines.rb +37 -0
- data/lib/danger/ci_source/bitrise.rb +65 -0
- data/lib/danger/ci_source/buddybuild.rb +62 -0
- data/lib/danger/ci_source/buildkite.rb +51 -0
- data/lib/danger/ci_source/ci_source.rb +37 -0
- data/lib/danger/ci_source/circle.rb +94 -0
- data/lib/danger/ci_source/circle_api.rb +51 -0
- data/lib/danger/ci_source/cirrus.rb +31 -0
- data/lib/danger/ci_source/code_build.rb +57 -0
- data/lib/danger/ci_source/codefresh.rb +53 -0
- data/lib/danger/ci_source/codeship.rb +44 -0
- data/lib/danger/ci_source/dotci.rb +52 -0
- data/lib/danger/ci_source/drone.rb +71 -0
- data/lib/danger/ci_source/github_actions.rb +43 -0
- data/lib/danger/ci_source/gitlab_ci.rb +86 -0
- data/lib/danger/ci_source/jenkins.rb +149 -0
- data/lib/danger/ci_source/local_git_repo.rb +119 -0
- data/lib/danger/ci_source/local_only_git_repo.rb +47 -0
- data/lib/danger/ci_source/screwdriver.rb +47 -0
- data/lib/danger/ci_source/semaphore.rb +37 -0
- data/lib/danger/ci_source/support/commits.rb +17 -0
- data/lib/danger/ci_source/support/find_repo_info_from_logs.rb +35 -0
- data/lib/danger/ci_source/support/find_repo_info_from_url.rb +42 -0
- data/lib/danger/ci_source/support/local_pull_request.rb +14 -0
- data/lib/danger/ci_source/support/no_pull_request.rb +7 -0
- data/lib/danger/ci_source/support/no_repo_info.rb +5 -0
- data/lib/danger/ci_source/support/pull_request_finder.rb +179 -0
- data/lib/danger/ci_source/support/remote_pull_request.rb +15 -0
- data/lib/danger/ci_source/support/repo_info.rb +10 -0
- data/lib/danger/ci_source/surf.rb +37 -0
- data/lib/danger/ci_source/teamcity.rb +161 -0
- data/lib/danger/ci_source/travis.rb +51 -0
- data/lib/danger/ci_source/vsts.rb +73 -0
- data/lib/danger/ci_source/xcode_server.rb +48 -0
- data/lib/danger/clients/rubygems_client.rb +14 -0
- data/lib/danger/commands/dangerfile/gem.rb +43 -0
- data/lib/danger/commands/dangerfile/init.rb +30 -0
- data/lib/danger/commands/dry_run.rb +54 -0
- data/lib/danger/commands/init.rb +297 -0
- data/lib/danger/commands/init_helpers/interviewer.rb +92 -0
- data/lib/danger/commands/local.rb +83 -0
- data/lib/danger/commands/local_helpers/http_cache.rb +36 -0
- data/lib/danger/commands/local_helpers/local_setup.rb +46 -0
- data/lib/danger/commands/local_helpers/pry_setup.rb +31 -0
- data/lib/danger/commands/plugins/plugin_json.rb +46 -0
- data/lib/danger/commands/plugins/plugin_lint.rb +54 -0
- data/lib/danger/commands/plugins/plugin_readme.rb +45 -0
- data/lib/danger/commands/pr.rb +92 -0
- data/lib/danger/commands/runner.rb +94 -0
- data/lib/danger/commands/staging.rb +53 -0
- data/lib/danger/commands/systems.rb +43 -0
- data/lib/danger/comment_generators/bitbucket_server.md.erb +20 -0
- data/lib/danger/comment_generators/bitbucket_server_inline.md.erb +15 -0
- data/lib/danger/comment_generators/bitbucket_server_message_group.md.erb +12 -0
- data/lib/danger/comment_generators/github.md.erb +55 -0
- data/lib/danger/comment_generators/github_inline.md.erb +26 -0
- data/lib/danger/comment_generators/gitlab.md.erb +40 -0
- data/lib/danger/comment_generators/gitlab_inline.md.erb +26 -0
- data/lib/danger/comment_generators/vsts.md.erb +20 -0
- data/lib/danger/core_ext/file_list.rb +18 -0
- data/lib/danger/core_ext/string.rb +20 -0
- data/lib/danger/danger_core/dangerfile.rb +341 -0
- data/lib/danger/danger_core/dangerfile_dsl.rb +29 -0
- data/lib/danger/danger_core/dangerfile_generator.rb +11 -0
- data/lib/danger/danger_core/environment_manager.rb +123 -0
- data/lib/danger/danger_core/executor.rb +92 -0
- data/lib/danger/danger_core/message_aggregator.rb +49 -0
- data/lib/danger/danger_core/message_group.rb +68 -0
- data/lib/danger/danger_core/messages/base.rb +56 -0
- data/lib/danger/danger_core/messages/markdown.rb +42 -0
- data/lib/danger/danger_core/messages/violation.rb +54 -0
- data/lib/danger/danger_core/plugins/dangerfile_bitbucket_cloud_plugin.rb +144 -0
- data/lib/danger/danger_core/plugins/dangerfile_bitbucket_server_plugin.rb +211 -0
- data/lib/danger/danger_core/plugins/dangerfile_danger_plugin.rb +248 -0
- data/lib/danger/danger_core/plugins/dangerfile_git_plugin.rb +158 -0
- data/lib/danger/danger_core/plugins/dangerfile_github_plugin.rb +254 -0
- data/lib/danger/danger_core/plugins/dangerfile_gitlab_plugin.rb +240 -0
- data/lib/danger/danger_core/plugins/dangerfile_local_only_plugin.rb +42 -0
- data/lib/danger/danger_core/plugins/dangerfile_messaging_plugin.rb +218 -0
- data/lib/danger/danger_core/plugins/dangerfile_vsts_plugin.rb +191 -0
- data/lib/danger/danger_core/standard_error.rb +143 -0
- data/lib/danger/helpers/array_subclass.rb +61 -0
- data/lib/danger/helpers/comment.rb +32 -0
- data/lib/danger/helpers/comments_helper.rb +178 -0
- data/lib/danger/helpers/comments_parsing_helper.rb +70 -0
- data/lib/danger/helpers/emoji_mapper.rb +41 -0
- data/lib/danger/helpers/find_max_num_violations.rb +31 -0
- data/lib/danger/helpers/message_groups_array_helper.rb +31 -0
- data/lib/danger/plugin_support/gems_resolver.rb +77 -0
- data/lib/danger/plugin_support/plugin.rb +49 -0
- data/lib/danger/plugin_support/plugin_file_resolver.rb +30 -0
- data/lib/danger/plugin_support/plugin_linter.rb +161 -0
- data/lib/danger/plugin_support/plugin_parser.rb +199 -0
- data/lib/danger/plugin_support/templates/readme_table.html.erb +26 -0
- data/lib/danger/request_sources/bitbucket_cloud.rb +171 -0
- data/lib/danger/request_sources/bitbucket_cloud_api.rb +181 -0
- data/lib/danger/request_sources/bitbucket_server.rb +105 -0
- data/lib/danger/request_sources/bitbucket_server_api.rb +117 -0
- data/lib/danger/request_sources/github/github.rb +530 -0
- data/lib/danger/request_sources/github/github_review.rb +126 -0
- data/lib/danger/request_sources/github/github_review_resolver.rb +19 -0
- data/lib/danger/request_sources/github/github_review_unsupported.rb +25 -0
- data/lib/danger/request_sources/gitlab.rb +525 -0
- data/lib/danger/request_sources/local_only.rb +53 -0
- data/lib/danger/request_sources/request_source.rb +85 -0
- data/lib/danger/request_sources/support/get_ignored_violation.rb +17 -0
- data/lib/danger/request_sources/vsts.rb +118 -0
- data/lib/danger/request_sources/vsts_api.rb +138 -0
- data/lib/danger/scm_source/git_repo.rb +181 -0
- data/lib/danger/version.rb +4 -0
- metadata +339 -0
@@ -0,0 +1,26 @@
|
|
1
|
+
<% json.each do |plugin| %>
|
2
|
+
|
3
|
+
### <%= plugin["instance_name"] %>
|
4
|
+
|
5
|
+
<%= plugin["body_md"] %>
|
6
|
+
<%- plugin["example_code"].each do |example| %>
|
7
|
+
<blockquote><%= example["title"] %>
|
8
|
+
<pre><%= example["text"] %></pre>
|
9
|
+
</blockquote>
|
10
|
+
<%- end %>
|
11
|
+
|
12
|
+
<%- unless plugin["attributes"].empty? %>
|
13
|
+
#### Attributes
|
14
|
+
<%- plugin["attributes"].each do |attribute| %>
|
15
|
+
`<%= attribute.keys.first %>` - <%= attribute.values.first["write"]["body_md"] %>
|
16
|
+
<%- end %>
|
17
|
+
<%- end %>
|
18
|
+
|
19
|
+
<%- unless plugin["methods"].empty? %>
|
20
|
+
#### Methods
|
21
|
+
<%- plugin["methods"].each do |method| %>
|
22
|
+
`<%= method["name"] %>` - <%= method["body_md"] %>
|
23
|
+
<%- end %>
|
24
|
+
<%- end %>
|
25
|
+
|
26
|
+
<% end %>
|
@@ -0,0 +1,171 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require "danger/helpers/comments_helper"
|
4
|
+
require "danger/request_sources/bitbucket_cloud_api"
|
5
|
+
require "danger/danger_core/message_group"
|
6
|
+
|
7
|
+
module Danger
|
8
|
+
module RequestSources
|
9
|
+
class BitbucketCloud < RequestSource
|
10
|
+
include Danger::Helpers::CommentsHelper
|
11
|
+
attr_accessor :pr_json
|
12
|
+
|
13
|
+
def self.env_vars
|
14
|
+
[
|
15
|
+
"DANGER_BITBUCKETCLOUD_USERNAME",
|
16
|
+
"DANGER_BITBUCKETCLOUD_UUID",
|
17
|
+
"DANGER_BITBUCKETCLOUD_PASSWORD"
|
18
|
+
]
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.optional_env_vars
|
22
|
+
["DANGER_BITBUCKETCLOUD_OAUTH_KEY", "DANGER_BITBUCKETCLOUD_OAUTH_SECRET"]
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(ci_source, environment)
|
26
|
+
self.ci_source = ci_source
|
27
|
+
self.environment = environment
|
28
|
+
|
29
|
+
@api = BitbucketCloudAPI.new(ci_source.repo_slug, ci_source.pull_request_id, nil, environment)
|
30
|
+
end
|
31
|
+
|
32
|
+
def validates_as_ci?
|
33
|
+
# TODO: ???
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
def validates_as_api_source?
|
38
|
+
@api.credentials_given?
|
39
|
+
end
|
40
|
+
|
41
|
+
def scm
|
42
|
+
@scm ||= GitRepo.new
|
43
|
+
end
|
44
|
+
|
45
|
+
def host
|
46
|
+
@host ||= @api.host
|
47
|
+
end
|
48
|
+
|
49
|
+
def fetch_details
|
50
|
+
self.pr_json = @api.fetch_pr_json
|
51
|
+
end
|
52
|
+
|
53
|
+
def setup_danger_branches
|
54
|
+
base_branch = self.pr_json[:destination][:branch][:name]
|
55
|
+
base_commit = self.pr_json[:destination][:commit][:hash]
|
56
|
+
head_branch = self.pr_json[:source][:branch][:name]
|
57
|
+
head_commit = self.pr_json[:source][:commit][:hash]
|
58
|
+
|
59
|
+
# Next, we want to ensure that we have a version of the current branch at a known location
|
60
|
+
scm.ensure_commitish_exists_on_branch! base_branch, base_commit
|
61
|
+
self.scm.exec "branch #{EnvironmentManager.danger_base_branch} #{base_commit}"
|
62
|
+
|
63
|
+
# OK, so we want to ensure that we have a known head branch, this will always represent
|
64
|
+
# the head of the PR ( e.g. the most recent commit that will be merged. )
|
65
|
+
scm.ensure_commitish_exists_on_branch! head_branch, head_commit
|
66
|
+
self.scm.exec "branch #{EnvironmentManager.danger_head_branch} #{head_commit}"
|
67
|
+
end
|
68
|
+
|
69
|
+
def organisation
|
70
|
+
nil
|
71
|
+
end
|
72
|
+
|
73
|
+
def update_pull_request!(warnings: [], errors: [], messages: [], markdowns: [], danger_id: "danger", new_comment: false, remove_previous_comments: false)
|
74
|
+
delete_old_comments(danger_id: danger_id) if !new_comment || remove_previous_comments
|
75
|
+
|
76
|
+
comment = generate_description(warnings: warnings, errors: errors, template: "bitbucket_server")
|
77
|
+
comment += "\n\n"
|
78
|
+
|
79
|
+
warnings = update_inline_comments_for_kind!(:warnings, warnings, danger_id: danger_id)
|
80
|
+
errors = update_inline_comments_for_kind!(:errors, errors, danger_id: danger_id)
|
81
|
+
messages = update_inline_comments_for_kind!(:messages, messages, danger_id: danger_id)
|
82
|
+
markdowns = update_inline_comments_for_kind!(:markdowns, markdowns, danger_id: danger_id)
|
83
|
+
|
84
|
+
comment += generate_comment(warnings: warnings,
|
85
|
+
errors: errors,
|
86
|
+
messages: messages,
|
87
|
+
markdowns: markdowns,
|
88
|
+
previous_violations: {},
|
89
|
+
danger_id: danger_id,
|
90
|
+
template: "bitbucket_server")
|
91
|
+
|
92
|
+
@api.post_comment(comment)
|
93
|
+
end
|
94
|
+
|
95
|
+
def update_pr_by_line!(message_groups:,
|
96
|
+
danger_id: "danger",
|
97
|
+
new_comment: false,
|
98
|
+
remove_previous_comments: false)
|
99
|
+
if !new_comment || remove_previous_comments
|
100
|
+
delete_old_comments(danger_id: danger_id)
|
101
|
+
end
|
102
|
+
|
103
|
+
summary_body = generate_description(warnings: message_groups.fake_warnings_array,
|
104
|
+
errors: message_groups.fake_errors_array,
|
105
|
+
template: "bitbucket_server")
|
106
|
+
summary_body += "\n\n"
|
107
|
+
|
108
|
+
|
109
|
+
# this isn't the most elegant thing in the world, but we need the group
|
110
|
+
# with file: nil, line: nil so we can combine its info in with the
|
111
|
+
# summary_body
|
112
|
+
summary_group = message_groups.first
|
113
|
+
if summary_group && summary_group.file.nil? && summary_group.line.nil?
|
114
|
+
# remove summary_group from message_groups so it doesn't get a
|
115
|
+
# duplicate comment posted in the message_groups loop below
|
116
|
+
message_groups.shift
|
117
|
+
else
|
118
|
+
summary_group = MessageGroup.new(file: nil, line: nil)
|
119
|
+
end
|
120
|
+
|
121
|
+
summary_body += generate_message_group_comment(
|
122
|
+
message_group: summary_group,
|
123
|
+
danger_id: danger_id,
|
124
|
+
template: "bitbucket_server_message_group"
|
125
|
+
)
|
126
|
+
|
127
|
+
@api.post_comment(summary_body)
|
128
|
+
|
129
|
+
message_groups.each do |message_group|
|
130
|
+
body = generate_message_group_comment(message_group: message_group,
|
131
|
+
danger_id: danger_id,
|
132
|
+
template: "bitbucket_server_message_group")
|
133
|
+
@api.post_comment(body,
|
134
|
+
file: message_group.file,
|
135
|
+
line: message_group.line)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def update_inline_comments_for_kind!(kind, messages, danger_id: "danger")
|
140
|
+
emoji = { warnings: "warning", errors: "no_entry_sign", messages: "book" }[kind]
|
141
|
+
|
142
|
+
messages.reject do |message|
|
143
|
+
next false unless message.file && message.line
|
144
|
+
|
145
|
+
body = ""
|
146
|
+
|
147
|
+
if kind == :markdown
|
148
|
+
body = generate_inline_markdown_body(message,
|
149
|
+
danger_id: danger_id,
|
150
|
+
template: "bitbucket_server")
|
151
|
+
else
|
152
|
+
body = generate_inline_comment_body(emoji, message,
|
153
|
+
danger_id: danger_id,
|
154
|
+
template: "bitbucket_server")
|
155
|
+
end
|
156
|
+
|
157
|
+
@api.post_comment(body, file: message.file, line: message.line)
|
158
|
+
|
159
|
+
true
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def delete_old_comments(danger_id: "danger")
|
164
|
+
@api.fetch_comments.each do |c|
|
165
|
+
next if c[:user][:uuid] != @api.my_uuid
|
166
|
+
@api.delete_comment(c[:id]) if c[:content][:raw] =~ /generated_by_#{danger_id}/
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require "danger/helpers/comments_helper"
|
4
|
+
|
5
|
+
module Danger
|
6
|
+
module RequestSources
|
7
|
+
class BitbucketCloudAPI
|
8
|
+
attr_accessor :host, :project, :slug, :access_token, :pull_request_id
|
9
|
+
attr_reader :my_uuid
|
10
|
+
|
11
|
+
def initialize(repo_slug, pull_request_id, branch_name, environment)
|
12
|
+
initialize_my_uuid(environment["DANGER_BITBUCKETCLOUD_UUID"])
|
13
|
+
@username = environment["DANGER_BITBUCKETCLOUD_USERNAME"]
|
14
|
+
@password = environment["DANGER_BITBUCKETCLOUD_PASSWORD"]
|
15
|
+
self.project, self.slug = repo_slug.split("/")
|
16
|
+
self.access_token = fetch_access_token(environment)
|
17
|
+
self.pull_request_id = pull_request_id || fetch_pr_from_branch(branch_name)
|
18
|
+
self.host = "https://bitbucket.org/"
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize_my_uuid(uuid)
|
22
|
+
return if uuid.nil?
|
23
|
+
return @my_uuid = uuid if uuid.empty?
|
24
|
+
|
25
|
+
if uuid.start_with?("{") && uuid.end_with?("}")
|
26
|
+
@my_uuid = uuid
|
27
|
+
else
|
28
|
+
@my_uuid = "{#{uuid}}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def inspect
|
33
|
+
inspected = super
|
34
|
+
|
35
|
+
if @password
|
36
|
+
inspected = inspected.sub! @password, "********".freeze
|
37
|
+
end
|
38
|
+
|
39
|
+
inspected
|
40
|
+
end
|
41
|
+
|
42
|
+
def credentials_given?
|
43
|
+
@my_uuid && !@my_uuid.empty? &&
|
44
|
+
@username && !@username.empty? &&
|
45
|
+
@password && !@password.empty?
|
46
|
+
end
|
47
|
+
|
48
|
+
def pull_request(*)
|
49
|
+
fetch_pr_json
|
50
|
+
end
|
51
|
+
|
52
|
+
def fetch_pr_json
|
53
|
+
uri = URI(pr_api_endpoint)
|
54
|
+
fetch_json(uri)
|
55
|
+
end
|
56
|
+
|
57
|
+
def fetch_comments
|
58
|
+
values = []
|
59
|
+
# TODO: use a url parts encoder to encode the query
|
60
|
+
uri = "#{pr_api_endpoint}/comments?pagelen=100&q=deleted+%7E+false+AND+user.username+%7E+%22#{@username}%22"
|
61
|
+
|
62
|
+
while uri
|
63
|
+
json = fetch_json(URI(uri))
|
64
|
+
values += json[:values]
|
65
|
+
uri = json[:next]
|
66
|
+
end
|
67
|
+
values
|
68
|
+
end
|
69
|
+
|
70
|
+
def delete_comment(id)
|
71
|
+
uri = URI("#{pr_api_endpoint}/comments/#{id}")
|
72
|
+
delete(uri)
|
73
|
+
end
|
74
|
+
|
75
|
+
def post_comment(text, file: nil, line: nil)
|
76
|
+
uri = URI("#{pr_api_endpoint}/comments")
|
77
|
+
body = {
|
78
|
+
content: {
|
79
|
+
raw: text
|
80
|
+
}
|
81
|
+
}
|
82
|
+
body.merge!(inline: { path: file, to: line }) if file && line
|
83
|
+
|
84
|
+
post(uri, body.to_json)
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def base_url(version)
|
90
|
+
"https://api.bitbucket.org/#{version}.0/repositories/#{project}/#{slug}/pullrequests"
|
91
|
+
end
|
92
|
+
|
93
|
+
def pr_api_endpoint
|
94
|
+
"#{base_url(2)}/#{pull_request_id}"
|
95
|
+
end
|
96
|
+
|
97
|
+
def prs_api_endpoint(branch_name)
|
98
|
+
"#{base_url(2)}?q=source.branch.name=\"#{branch_name}\""
|
99
|
+
end
|
100
|
+
|
101
|
+
def fetch_pr_from_branch(branch_name)
|
102
|
+
uri = URI(URI.escape(prs_api_endpoint(branch_name)))
|
103
|
+
fetch_json(uri)[:values][0][:id]
|
104
|
+
end
|
105
|
+
|
106
|
+
def fetch_access_token(environment)
|
107
|
+
oauth_key = environment["DANGER_BITBUCKETCLOUD_OAUTH_KEY"]
|
108
|
+
oauth_secret = environment["DANGER_BITBUCKETCLOUD_OAUTH_SECRET"]
|
109
|
+
return nil if oauth_key.nil?
|
110
|
+
return nil if oauth_secret.nil?
|
111
|
+
|
112
|
+
uri = URI.parse("https://bitbucket.org/site/oauth2/access_token")
|
113
|
+
req = Net::HTTP::Post.new(uri.request_uri, { "Content-Type" => "application/json" })
|
114
|
+
req.basic_auth oauth_key, oauth_secret
|
115
|
+
req.set_form_data({'grant_type' => 'client_credentials'})
|
116
|
+
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
|
117
|
+
http.request(req)
|
118
|
+
end
|
119
|
+
|
120
|
+
JSON.parse(res.body, symbolize_names: true)[:access_token]
|
121
|
+
end
|
122
|
+
|
123
|
+
def fetch_json(uri)
|
124
|
+
raise credentials_not_available unless credentials_given?
|
125
|
+
|
126
|
+
req = Net::HTTP::Get.new(uri.request_uri, { "Content-Type" => "application/json" })
|
127
|
+
if access_token.nil?
|
128
|
+
req.basic_auth @username, @password
|
129
|
+
else
|
130
|
+
req["Authorization"] = "Bearer #{access_token}"
|
131
|
+
end
|
132
|
+
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
|
133
|
+
http.request(req)
|
134
|
+
end
|
135
|
+
raise error_fetching_json(uri.to_s, res.code) unless res.code == "200"
|
136
|
+
|
137
|
+
JSON.parse(res.body, symbolize_names: true)
|
138
|
+
end
|
139
|
+
|
140
|
+
def post(uri, body)
|
141
|
+
raise credentials_not_available unless credentials_given?
|
142
|
+
|
143
|
+
req = Net::HTTP::Post.new(uri.request_uri, { "Content-Type" => "application/json" })
|
144
|
+
if access_token.nil?
|
145
|
+
req.basic_auth @username, @password
|
146
|
+
else
|
147
|
+
req["Authorization"] = "Bearer #{access_token}"
|
148
|
+
end
|
149
|
+
req.body = body
|
150
|
+
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
|
151
|
+
http.request(req)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def delete(uri)
|
156
|
+
raise credentials_not_available unless credentials_given?
|
157
|
+
|
158
|
+
req = Net::HTTP::Delete.new(uri.request_uri, { "Content-Type" => "application/json" })
|
159
|
+
if access_token.nil?
|
160
|
+
req.basic_auth @username, @password
|
161
|
+
else
|
162
|
+
req["Authorization"] = "Bearer #{access_token}"
|
163
|
+
end
|
164
|
+
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
|
165
|
+
http.request(req)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def credentials_not_available
|
170
|
+
"Credentials not available. Provide DANGER_BITBUCKETCLOUD_USERNAME, " \
|
171
|
+
"DANGER_BITBUCKETCLOUD_UUID, and DANGER_BITBUCKETCLOUD_PASSWORD " \
|
172
|
+
"as environment variables."
|
173
|
+
end
|
174
|
+
|
175
|
+
def error_fetching_json(url, status_code)
|
176
|
+
"Error fetching json for: #{url}, status code: #{status_code}"
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require "danger/helpers/comments_helper"
|
4
|
+
require "danger/request_sources/bitbucket_server_api"
|
5
|
+
|
6
|
+
module Danger
|
7
|
+
module RequestSources
|
8
|
+
class BitbucketServer < RequestSource
|
9
|
+
include Danger::Helpers::CommentsHelper
|
10
|
+
attr_accessor :pr_json
|
11
|
+
|
12
|
+
def self.env_vars
|
13
|
+
[
|
14
|
+
"DANGER_BITBUCKETSERVER_USERNAME",
|
15
|
+
"DANGER_BITBUCKETSERVER_PASSWORD",
|
16
|
+
"DANGER_BITBUCKETSERVER_HOST"
|
17
|
+
]
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(ci_source, environment)
|
21
|
+
self.ci_source = ci_source
|
22
|
+
self.environment = environment
|
23
|
+
|
24
|
+
project, slug = ci_source.repo_slug.split("/")
|
25
|
+
@api = BitbucketServerAPI.new(project, slug, ci_source.pull_request_id, environment)
|
26
|
+
end
|
27
|
+
|
28
|
+
def validates_as_ci?
|
29
|
+
# TODO: ???
|
30
|
+
true
|
31
|
+
end
|
32
|
+
|
33
|
+
def validates_as_api_source?
|
34
|
+
@api.credentials_given?
|
35
|
+
end
|
36
|
+
|
37
|
+
def scm
|
38
|
+
@scm ||= GitRepo.new
|
39
|
+
end
|
40
|
+
|
41
|
+
def host
|
42
|
+
@host ||= @api.host
|
43
|
+
end
|
44
|
+
|
45
|
+
def fetch_details
|
46
|
+
self.pr_json = @api.fetch_pr_json
|
47
|
+
end
|
48
|
+
|
49
|
+
def setup_danger_branches
|
50
|
+
base_branch = self.pr_json[:toRef][:id].sub("refs/heads/", "")
|
51
|
+
base_commit = self.pr_json[:toRef][:latestCommit]
|
52
|
+
# Support for older versions of Bitbucket Server
|
53
|
+
base_commit = self.pr_json[:toRef][:latestChangeset] if self.pr_json[:fromRef].key? :latestChangeset
|
54
|
+
head_branch = self.pr_json[:fromRef][:id].sub("refs/heads/", "")
|
55
|
+
head_commit = self.pr_json[:fromRef][:latestCommit]
|
56
|
+
# Support for older versions of Bitbucket Server
|
57
|
+
head_commit = self.pr_json[:fromRef][:latestChangeset] if self.pr_json[:fromRef].key? :latestChangeset
|
58
|
+
|
59
|
+
# Next, we want to ensure that we have a version of the current branch at a known location
|
60
|
+
scm.ensure_commitish_exists_on_branch! base_branch, base_commit
|
61
|
+
self.scm.exec "branch #{EnvironmentManager.danger_base_branch} #{base_commit}"
|
62
|
+
|
63
|
+
# OK, so we want to ensure that we have a known head branch, this will always represent
|
64
|
+
# the head of the PR ( e.g. the most recent commit that will be merged. )
|
65
|
+
scm.ensure_commitish_exists_on_branch! head_branch, head_commit
|
66
|
+
self.scm.exec "branch #{EnvironmentManager.danger_head_branch} #{head_commit}"
|
67
|
+
end
|
68
|
+
|
69
|
+
def organisation
|
70
|
+
nil
|
71
|
+
end
|
72
|
+
|
73
|
+
def update_pull_request!(warnings: [], errors: [], messages: [], markdowns: [], danger_id: "danger", new_comment: false, remove_previous_comments: false)
|
74
|
+
delete_old_comments(danger_id: danger_id) if !new_comment || remove_previous_comments
|
75
|
+
|
76
|
+
comment = generate_description(warnings: warnings, errors: errors)
|
77
|
+
comment += "\n\n"
|
78
|
+
comment += generate_comment(warnings: warnings,
|
79
|
+
errors: errors,
|
80
|
+
messages: messages,
|
81
|
+
markdowns: markdowns,
|
82
|
+
previous_violations: {},
|
83
|
+
danger_id: danger_id,
|
84
|
+
template: "bitbucket_server")
|
85
|
+
|
86
|
+
@api.post_comment(comment)
|
87
|
+
end
|
88
|
+
|
89
|
+
def delete_old_comments(danger_id: "danger")
|
90
|
+
@api.fetch_last_comments.each do |c|
|
91
|
+
@api.delete_comment(c[:id], c[:version]) if c[:text] =~ /generated_by_#{danger_id}/
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def update_pr_build_status(status, build_job_link, description)
|
96
|
+
changeset = self.pr_json[:fromRef][:latestCommit]
|
97
|
+
# Support for older versions of Bitbucket Server
|
98
|
+
changeset = self.pr_json[:fromRef][:latestChangeset] if self.pr_json[:fromRef].key? :latestChangeset
|
99
|
+
puts "Changeset: " + changeset
|
100
|
+
puts self.pr_json.to_json
|
101
|
+
@api.update_pr_build_status(status, changeset, build_job_link, description)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|