danger 5.3.5 → 5.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7a125bab695ff0f61f64ca3ecb36d6e63b096b9d
4
- data.tar.gz: 157d76ea80c2eebe6c747cd31d4d23e39dbec3df
3
+ metadata.gz: 06752bbffec806b31893a0befbc36c7a9fdb2fae
4
+ data.tar.gz: a040e75f604c3efaa4fef0f9a4ef5525986d56f6
5
5
  SHA512:
6
- metadata.gz: bf6c4041c36f6a2af052b02608f709db4fc1cb48a17b69c255ee87f9d72824a62f5058cd2aa01e4ce9f5493b43085c2371881b6d5ccbd2f5e52e5823ac993e5a
7
- data.tar.gz: 3d91b2f6304630f93b8ab6819a501d659866d8f031896a9eb939ce64e5c5501cc472217cfebb457eb40dc98603309b2dd1d4bd629f915faab235304f0909d7fe
6
+ metadata.gz: f67e7ec2195c040f6005238e1dc522b0be4e7976972aa110b3f91c213e420436ad3dcc1ab4d720aa5dc34c0242d321d4bdb69ce3c4b41353ce25a498e0696946
7
+ data.tar.gz: b510818c68d7ff4a88152158f1254b84d02e9daa07c2d612c424a6b127561a2aec8b982b52786c453aa7692ca5d8d32726daba85c5c7f97062585e1938b41e95
@@ -39,7 +39,7 @@ module Danger
39
39
 
40
40
  merge_requests = client.merge_requests(project_id, state: :opened)
41
41
  merge_request = merge_requests.auto_paginate.bsearch do |mr|
42
- mr.sha == base_commit
42
+ mr.sha >= base_commit
43
43
  end
44
44
 
45
45
  merge_request.nil? ? 0 : merge_request.iid
@@ -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 %>")
@@ -105,6 +105,8 @@ module Danger
105
105
  :bitbucket_server
106
106
  when Danger::RequestSources::BitbucketCloud
107
107
  :bitbucket_cloud
108
+ when Danger::RequestSources::VSTS
109
+ :vsts
108
110
  else
109
111
  :unknown
110
112
  end
@@ -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 template == "bitbucket_server"
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
@@ -1,4 +1,4 @@
1
1
  module Danger
2
- VERSION = "5.3.5".freeze
2
+ VERSION = "5.4.0".freeze
3
3
  DESCRIPTION = "Like Unit Tests, but for your Team Culture.".freeze
4
4
  end
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.3.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-08-24 00:00:00.000000000 Z
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