danger 5.3.5 → 5.4.0
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/lib/danger/ci_source/gitlab_ci.rb +1 -1
- data/lib/danger/ci_source/vsts.rb +73 -0
- data/lib/danger/comment_generators/vsts.md.erb +20 -0
- data/lib/danger/danger_core/plugins/dangerfile_danger_plugin.rb +2 -0
- data/lib/danger/helpers/comments_helper.rb +1 -1
- data/lib/danger/request_sources/vsts.rb +106 -0
- data/lib/danger/request_sources/vsts_api.rb +138 -0
- data/lib/danger/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 06752bbffec806b31893a0befbc36c7a9fdb2fae
|
4
|
+
data.tar.gz: a040e75f604c3efaa4fef0f9a4ef5525986d56f6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f67e7ec2195c040f6005238e1dc522b0be4e7976972aa110b3f91c213e420436ad3dcc1ab4d720aa5dc34c0242d321d4bdb69ce3c4b41353ce25a498e0696946
|
7
|
+
data.tar.gz: b510818c68d7ff4a88152158f1254b84d02e9daa07c2d612c424a6b127561a2aec8b982b52786c453aa7692ca5d8d32726daba85c5c7f97062585e1938b41e95
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require "danger/request_sources/github/github"
|
2
|
+
require "danger/request_sources/vsts"
|
3
|
+
|
4
|
+
module Danger
|
5
|
+
# ### CI Setup
|
6
|
+
#
|
7
|
+
# You need to go to your project's build definiton. Then add a "Command Line" Task with the "Tool" field set to "bundle"
|
8
|
+
# and the "Arguments" field set to "exec danger".
|
9
|
+
#
|
10
|
+
# ### Token Setup
|
11
|
+
#
|
12
|
+
# #### GitHub
|
13
|
+
#
|
14
|
+
# You need to add the `DANGER_GITHUB_API_TOKEN` environment variable, to do this, go to your build definition's variables tab.
|
15
|
+
#
|
16
|
+
# Make sure that `DANGER_GITHUB_API_TOKEN` is not set to secret since vsts does not expose secret variables while building.
|
17
|
+
#
|
18
|
+
# #### VSTS
|
19
|
+
#
|
20
|
+
# You need to add the `DANGER_VSTS_API_TOKEN` and `DANGER_VSTS_HOST` environment variable, to do this,
|
21
|
+
# go to your build definition's variables tab. The `DANGER_VSTS_API_TOKEN` is your vsts personal access token.
|
22
|
+
# Instructions for creating a personal access token can be found [here](https://www.visualstudio.com/en-us/docs/setup-admin/team-services/use-personal-access-tokens-to-authenticate).
|
23
|
+
# For the `DANGER_VSTS_HOST` variable the suggested value is `$(System.TeamFoundationCollectionUri)$(System.TeamProject)`
|
24
|
+
# which will automatically get your vsts domain and your project name needed for the vsts api.
|
25
|
+
#
|
26
|
+
# Make sure that `DANGER_VSTS_API_TOKEN` is not set to secret since vsts does not expose secret variables while building.
|
27
|
+
#
|
28
|
+
class VSTS < CI
|
29
|
+
class << self
|
30
|
+
def github_slug(env)
|
31
|
+
env["BUILD_REPOSITORY_NAME"]
|
32
|
+
end
|
33
|
+
|
34
|
+
def vsts_slug(env)
|
35
|
+
project_name = env["SYSTEM_TEAMPROJECT"]
|
36
|
+
repo_name = env["BUILD_REPOSITORY_NAME"]
|
37
|
+
|
38
|
+
"#{project_name}/#{repo_name}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.validates_as_ci?(env)
|
43
|
+
has_all_variables = ["SYSTEM_TEAMFOUNDATIONCOLLECTIONURI", "BUILD_REPOSITORY_PROVIDER"].all? { |x| env[x] && !env[x].empty? }
|
44
|
+
|
45
|
+
is_support_source_control = ["GitHub", "TfsGit"].include?(env["BUILD_REPOSITORY_PROVIDER"])
|
46
|
+
|
47
|
+
has_all_variables && is_support_source_control
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.validates_as_pr?(env)
|
51
|
+
has_all_variables = ["BUILD_SOURCEBRANCH", "BUILD_REPOSITORY_URI", "BUILD_REASON", "BUILD_REPOSITORY_NAME"].all? { |x| env[x] && !env[x].empty? }
|
52
|
+
|
53
|
+
has_all_variables && env["BUILD_REASON"] == "PullRequest"
|
54
|
+
end
|
55
|
+
|
56
|
+
def supported_request_sources
|
57
|
+
@supported_request_sources ||= [Danger::RequestSources::GitHub, Danger::RequestSources::VSTS]
|
58
|
+
end
|
59
|
+
|
60
|
+
def initialize(env)
|
61
|
+
case env["BUILD_REPOSITORY_PROVIDER"]
|
62
|
+
when "GitHub"
|
63
|
+
self.repo_slug = self.class.github_slug(env)
|
64
|
+
when "TfsGit"
|
65
|
+
self.repo_slug = self.class.vsts_slug(env)
|
66
|
+
end
|
67
|
+
|
68
|
+
repo_matches = env["BUILD_SOURCEBRANCH"].match(%r{refs\/pull\/([0-9]+)\/merge})
|
69
|
+
self.pull_request_id = repo_matches[1] unless repo_matches.nil?
|
70
|
+
self.repo_url = env["BUILD_REPOSITORY_URI"]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<%- @tables.each do |table| -%>
|
2
|
+
<%- if table[:content].any? || table[:resolved].any? -%>
|
3
|
+
| | <%= table[:count] %> <%= table[:name] %><%= "s" unless table[:count] == 1 %> |
|
4
|
+
|---|---|
|
5
|
+
<%- table[:content].each do |violation| -%>
|
6
|
+
| <%= @emoji_mapper.map(table[:emoji]) %> | <%= violation.message %> |
|
7
|
+
<%- end -%>
|
8
|
+
<%- table[:resolved].each do |message| -%>
|
9
|
+
| @emoji_mapper.map("white_check_mark") | <%= message %> |
|
10
|
+
<%- end -%>
|
11
|
+
|
12
|
+
<%- end -%>
|
13
|
+
<%- end -%>
|
14
|
+
|
15
|
+
<%- @markdowns.each do |current| -%>
|
16
|
+
<%= current %>
|
17
|
+
<%# the previous line has to be aligned far to the left, otherwise markdown can break easily %>
|
18
|
+
<%- end -%>
|
19
|
+
|
20
|
+
Generated by :no_entry_sign: [Danger](https://danger.systems/ "generated_by_<%= @danger_id %>")
|
@@ -56,7 +56,7 @@ module Danger
|
|
56
56
|
|
57
57
|
def table(name, emoji, violations, all_previous_violations, template: "github")
|
58
58
|
content = violations
|
59
|
-
content = content.map { |v| process_markdown(v) } unless
|
59
|
+
content = content.map { |v| process_markdown(v) } unless ["bitbucket_server", "vsts"].include?(template)
|
60
60
|
|
61
61
|
kind = table_kind_from_title(name)
|
62
62
|
previous_violations = all_previous_violations[kind] || []
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require "danger/helpers/comments_helper"
|
4
|
+
require "danger/request_sources/vsts_api"
|
5
|
+
|
6
|
+
module Danger
|
7
|
+
module RequestSources
|
8
|
+
class VSTS < RequestSource
|
9
|
+
include Danger::Helpers::CommentsHelper
|
10
|
+
attr_accessor :pr_json
|
11
|
+
|
12
|
+
def self.env_vars
|
13
|
+
[
|
14
|
+
"DANGER_VSTS_API_TOKEN",
|
15
|
+
"DANGER_VSTS_HOST"
|
16
|
+
]
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.optional_env_vars
|
20
|
+
[
|
21
|
+
"DANGER_VSTS_API_VERSION"
|
22
|
+
]
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(ci_source, environment)
|
26
|
+
self.ci_source = ci_source
|
27
|
+
self.environment = environment
|
28
|
+
|
29
|
+
@is_vsts_git = environment["BUILD_REPOSITORY_PROVIDER"] == "TfsGit"
|
30
|
+
|
31
|
+
project, slug = ci_source.repo_slug.split("/")
|
32
|
+
@api = VSTSAPI.new(project, slug, ci_source.pull_request_id, environment)
|
33
|
+
end
|
34
|
+
|
35
|
+
def validates_as_ci?
|
36
|
+
@is_vsts_git
|
37
|
+
end
|
38
|
+
|
39
|
+
def validates_as_api_source?
|
40
|
+
@api.credentials_given?
|
41
|
+
end
|
42
|
+
|
43
|
+
def scm
|
44
|
+
@scm ||= GitRepo.new
|
45
|
+
end
|
46
|
+
|
47
|
+
def host
|
48
|
+
@host ||= @api.host
|
49
|
+
end
|
50
|
+
|
51
|
+
def fetch_details
|
52
|
+
self.pr_json = @api.fetch_pr_json
|
53
|
+
end
|
54
|
+
|
55
|
+
def setup_danger_branches
|
56
|
+
base_commit = self.pr_json[:lastMergeTargetCommit][:commitId]
|
57
|
+
head_commit = self.pr_json[:lastMergeSourceCommit][:commitId]
|
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! 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! 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)
|
74
|
+
unless @api.supports_comments?
|
75
|
+
return
|
76
|
+
end
|
77
|
+
|
78
|
+
comment = generate_description(warnings: warnings, errors: errors)
|
79
|
+
comment += "\n\n"
|
80
|
+
comment += generate_comment(warnings: warnings,
|
81
|
+
errors: errors,
|
82
|
+
messages: messages,
|
83
|
+
markdowns: markdowns,
|
84
|
+
previous_violations: {},
|
85
|
+
danger_id: danger_id,
|
86
|
+
template: "vsts")
|
87
|
+
if new_comment
|
88
|
+
@api.post_comment(comment)
|
89
|
+
else
|
90
|
+
update_old_comment(comment, danger_id: danger_id)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def update_old_comment(new_comment, danger_id: "danger")
|
95
|
+
@api.fetch_last_comments.each do |c|
|
96
|
+
thread_id = c[:id]
|
97
|
+
comment = c[:comments].first
|
98
|
+
comment_id = comment[:id]
|
99
|
+
comment_content = comment[:content].nil? ? "" : comment[:content]
|
100
|
+
|
101
|
+
@api.update_comment(thread_id, comment_id, new_comment) if comment_content.include?("generated_by_#{danger_id}")
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require "base64"
|
4
|
+
require "danger/helpers/comments_helper"
|
5
|
+
|
6
|
+
module Danger
|
7
|
+
module RequestSources
|
8
|
+
class VSTSAPI
|
9
|
+
attr_accessor :host, :pr_api_endpoint, :min_api_version_for_comments
|
10
|
+
|
11
|
+
def initialize(_project, slug, pull_request_id, environment)
|
12
|
+
self.min_api_version_for_comments = "3.0"
|
13
|
+
|
14
|
+
user_name = ""
|
15
|
+
personal_access_token = environment["DANGER_VSTS_API_TOKEN"]
|
16
|
+
|
17
|
+
@token = Base64.strict_encode64("#{user_name}:#{personal_access_token}")
|
18
|
+
@api_version = environment["DANGER_VSTS_API_VERSION"] ||= self.min_api_version_for_comments
|
19
|
+
|
20
|
+
self.host = environment["DANGER_VSTS_HOST"]
|
21
|
+
if self.host && !(self.host.include? "http://") && !(self.host.include? "https://")
|
22
|
+
self.host = "https://" + self.host
|
23
|
+
end
|
24
|
+
|
25
|
+
self.pr_api_endpoint = "#{host}/_apis/git/repositories/#{slug}/pullRequests/#{pull_request_id}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def supports_comments?
|
29
|
+
major_version = @api_version.split(".").first.to_i
|
30
|
+
minimun_version_for_comments = self.min_api_version_for_comments.split(".").first.to_i
|
31
|
+
|
32
|
+
major_version >= minimun_version_for_comments
|
33
|
+
end
|
34
|
+
|
35
|
+
def inspect
|
36
|
+
inspected = super
|
37
|
+
|
38
|
+
if @token
|
39
|
+
inspected = inspected.sub! @token, "********".freeze
|
40
|
+
end
|
41
|
+
|
42
|
+
inspected
|
43
|
+
end
|
44
|
+
|
45
|
+
def credentials_given?
|
46
|
+
@token && !@token.empty?
|
47
|
+
end
|
48
|
+
|
49
|
+
def fetch_pr_json
|
50
|
+
uri = URI("#{pr_api_endpoint}?api-version=#{@api_version}")
|
51
|
+
fetch_json(uri)
|
52
|
+
end
|
53
|
+
|
54
|
+
def fetch_last_comments
|
55
|
+
uri = URI("#{pr_api_endpoint}/threads?api-version=#{@api_version}")
|
56
|
+
fetch_json(uri)[:value]
|
57
|
+
end
|
58
|
+
|
59
|
+
def post_comment(text)
|
60
|
+
uri = URI("#{pr_api_endpoint}/threads?api-version=#{@api_version}")
|
61
|
+
body = {
|
62
|
+
"comments" => [
|
63
|
+
{
|
64
|
+
"parentCommentId" => 0,
|
65
|
+
"content" => text,
|
66
|
+
"commentType" => 1
|
67
|
+
}
|
68
|
+
],
|
69
|
+
"properties" => {
|
70
|
+
"Microsoft.TeamFoundation.Discussion.SupportsMarkdown" => {
|
71
|
+
"type" => "System.Int32",
|
72
|
+
"value" => 1
|
73
|
+
}
|
74
|
+
},
|
75
|
+
"status" => 1
|
76
|
+
}.to_json
|
77
|
+
post(uri, body)
|
78
|
+
end
|
79
|
+
|
80
|
+
def update_comment(thread, id, new_comment)
|
81
|
+
uri = URI("#{pr_api_endpoint}/threads/#{thread}/comments/#{id}?api-version=#{@api_version}")
|
82
|
+
body = {
|
83
|
+
"content" => new_comment
|
84
|
+
}.to_json
|
85
|
+
patch(uri, body)
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def use_ssl
|
91
|
+
return self.pr_api_endpoint.include? "https://"
|
92
|
+
end
|
93
|
+
|
94
|
+
def fetch_json(uri)
|
95
|
+
req = Net::HTTP::Get.new(uri.request_uri, { "Content-Type" => "application/json", "Authorization" => "Basic #{@token}" })
|
96
|
+
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: use_ssl) do |http|
|
97
|
+
http.request(req)
|
98
|
+
end
|
99
|
+
JSON.parse(res.body, symbolize_names: true)
|
100
|
+
end
|
101
|
+
|
102
|
+
def post(uri, body)
|
103
|
+
req = Net::HTTP::Post.new(uri.request_uri, { "Content-Type" => "application/json", "Authorization" => "Basic #{@token}" })
|
104
|
+
req.body = body
|
105
|
+
|
106
|
+
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: use_ssl) do |http|
|
107
|
+
http.request(req)
|
108
|
+
end
|
109
|
+
|
110
|
+
# show error to the user when VSTS returned an error
|
111
|
+
case res
|
112
|
+
when Net::HTTPClientError, Net::HTTPServerError
|
113
|
+
# HTTP 4xx - 5xx
|
114
|
+
abort "\nError posting comment to VSTS: #{res.code} (#{res.message})\n\n"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def patch(uri, body)
|
119
|
+
puts uri
|
120
|
+
puts body
|
121
|
+
|
122
|
+
req = Net::HTTP::Patch.new(uri.request_uri, { "Content-Type" => "application/json", "Authorization" => "Basic #{@token}" })
|
123
|
+
req.body = body
|
124
|
+
|
125
|
+
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: use_ssl) do |http|
|
126
|
+
http.request(req)
|
127
|
+
end
|
128
|
+
|
129
|
+
# show error to the user when VSTS returned an error
|
130
|
+
case res
|
131
|
+
when Net::HTTPClientError, Net::HTTPServerError
|
132
|
+
# HTTP 4xx - 5xx
|
133
|
+
abort "\nError updating comment on VSTS: #{res.code} (#{res.message})\n\n"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
data/lib/danger/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: danger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Orta Therox
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-
|
12
|
+
date: 2017-09-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: claide
|
@@ -399,6 +399,7 @@ files:
|
|
399
399
|
- lib/danger/ci_source/surf.rb
|
400
400
|
- lib/danger/ci_source/teamcity.rb
|
401
401
|
- lib/danger/ci_source/travis.rb
|
402
|
+
- lib/danger/ci_source/vsts.rb
|
402
403
|
- lib/danger/ci_source/xcode_server.rb
|
403
404
|
- lib/danger/clients/rubygems_client.rb
|
404
405
|
- lib/danger/commands/dangerfile/gem.rb
|
@@ -419,6 +420,7 @@ files:
|
|
419
420
|
- lib/danger/comment_generators/github.md.erb
|
420
421
|
- lib/danger/comment_generators/github_inline.md.erb
|
421
422
|
- lib/danger/comment_generators/gitlab.md.erb
|
423
|
+
- lib/danger/comment_generators/vsts.md.erb
|
422
424
|
- lib/danger/core_ext/file_list.rb
|
423
425
|
- lib/danger/core_ext/string.rb
|
424
426
|
- lib/danger/danger_core/dangerfile.rb
|
@@ -459,6 +461,8 @@ files:
|
|
459
461
|
- lib/danger/request_sources/gitlab.rb
|
460
462
|
- lib/danger/request_sources/request_source.rb
|
461
463
|
- lib/danger/request_sources/support/get_ignored_violation.rb
|
464
|
+
- lib/danger/request_sources/vsts.rb
|
465
|
+
- lib/danger/request_sources/vsts_api.rb
|
462
466
|
- lib/danger/scm_source/git_repo.rb
|
463
467
|
- lib/danger/version.rb
|
464
468
|
homepage: https://github.com/danger/danger
|