dependabot-common 0.109.1 → 0.110.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/dependabot/clients/azure.rb +213 -0
- data/lib/dependabot/file_fetchers/base.rb +32 -0
- data/lib/dependabot/pull_request_creator.rb +16 -0
- data/lib/dependabot/pull_request_creator/azure.rb +92 -0
- data/lib/dependabot/pull_request_creator/labeler.rb +12 -0
- data/lib/dependabot/pull_request_creator/message_builder.rb +8 -3
- data/lib/dependabot/pull_request_creator/pr_name_prefixer.rb +39 -2
- data/lib/dependabot/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f65e5de2ce518246b0ec585237c62ac0bcc0de7392f119a4b3ffeab96ea9479f
|
|
4
|
+
data.tar.gz: d200fe282d5a0c10794a80d5f11526c1665519be29e41e0cc6e788f06abe5e3a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ede7202b5774b8e2ebd919d0c90a6b0010f5c9f56332ec41de1d9396c0f7617abb03825d0c02ee487077792928d24e5fc628248a20a9846ddbc2bed6aa2e6f7e
|
|
7
|
+
data.tar.gz: 2eefd19dbb76137dd133079840918f5a1357126d0a1d182aec15b89deb38b87c4502868c01fe9ad1d855f3181fe5ad5fd4d09ad469af4086d6e3fca3e1b37b54
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "dependabot/shared_helpers"
|
|
4
|
+
require "excon"
|
|
5
|
+
|
|
6
|
+
module Dependabot
|
|
7
|
+
module Clients
|
|
8
|
+
class Azure
|
|
9
|
+
class NotFound < StandardError; end
|
|
10
|
+
|
|
11
|
+
#######################
|
|
12
|
+
# Constructor methods #
|
|
13
|
+
#######################
|
|
14
|
+
|
|
15
|
+
def self.for_source(source:, credentials:)
|
|
16
|
+
credential =
|
|
17
|
+
credentials.
|
|
18
|
+
select { |cred| cred["type"] == "git_source" }.
|
|
19
|
+
find { |cred| cred["host"] == source.hostname }
|
|
20
|
+
|
|
21
|
+
new(source, credential)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
##########
|
|
25
|
+
# Client #
|
|
26
|
+
##########
|
|
27
|
+
|
|
28
|
+
def initialize(source, credentials)
|
|
29
|
+
@source = source
|
|
30
|
+
@credentials = credentials
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def fetch_commit(_repo, branch)
|
|
34
|
+
response = get(source.api_endpoint +
|
|
35
|
+
source.organization + "/" + source.project +
|
|
36
|
+
"/_apis/git/repositories/" + source.unscoped_repo +
|
|
37
|
+
"/stats/branches?name=" + branch)
|
|
38
|
+
|
|
39
|
+
JSON.parse(response.body).fetch("commit").fetch("commitId")
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def fetch_default_branch(_repo)
|
|
43
|
+
response = get(source.api_endpoint +
|
|
44
|
+
source.organization + "/" + source.project +
|
|
45
|
+
"/_apis/git/repositories/" + source.unscoped_repo)
|
|
46
|
+
|
|
47
|
+
JSON.parse(response.body).fetch("defaultBranch").gsub("refs/heads/", "")
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def fetch_repo_contents(commit = nil, path = nil)
|
|
51
|
+
tree = fetch_repo_contents_treeroot(commit, path)
|
|
52
|
+
|
|
53
|
+
response = get(source.api_endpoint +
|
|
54
|
+
source.organization + "/" + source.project +
|
|
55
|
+
"/_apis/git/repositories/" + source.unscoped_repo +
|
|
56
|
+
"/trees/" + tree + "?recursive=false")
|
|
57
|
+
|
|
58
|
+
JSON.parse(response.body).fetch("treeEntries")
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def fetch_repo_contents_treeroot(commit = nil, path = nil)
|
|
62
|
+
actual_path = path
|
|
63
|
+
actual_path = "/" if path.to_s.empty?
|
|
64
|
+
|
|
65
|
+
tree_url = source.api_endpoint +
|
|
66
|
+
source.organization + "/" + source.project +
|
|
67
|
+
"/_apis/git/repositories/" + source.unscoped_repo +
|
|
68
|
+
"/items?path=" + actual_path
|
|
69
|
+
|
|
70
|
+
unless commit.to_s.empty?
|
|
71
|
+
tree_url += "&versionDescriptor.versionType=commit" \
|
|
72
|
+
"&versionDescriptor.version=" + commit
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
tree_response = get(tree_url)
|
|
76
|
+
|
|
77
|
+
JSON.parse(tree_response.body).fetch("objectId")
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def fetch_file_contents(commit, path)
|
|
81
|
+
response = get(source.api_endpoint +
|
|
82
|
+
source.organization + "/" + source.project +
|
|
83
|
+
"/_apis/git/repositories/" + source.unscoped_repo +
|
|
84
|
+
"/items?path=" + path +
|
|
85
|
+
"&versionDescriptor.versionType=commit" \
|
|
86
|
+
"&versionDescriptor.version=" + commit)
|
|
87
|
+
|
|
88
|
+
response.body
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def commits(branch_name = nil)
|
|
92
|
+
commits_url = source.api_endpoint +
|
|
93
|
+
source.organization + "/" + source.project +
|
|
94
|
+
"/_apis/git/repositories/" + source.unscoped_repo +
|
|
95
|
+
"/commits"
|
|
96
|
+
|
|
97
|
+
unless branch_name.to_s.empty?
|
|
98
|
+
commits_url += "?searchCriteria.itemVersion.version=" + branch_name
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
response = get(commits_url)
|
|
102
|
+
|
|
103
|
+
JSON.parse(response.body).fetch("value")
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def branch(branch_name)
|
|
107
|
+
response = get(source.api_endpoint +
|
|
108
|
+
source.organization + "/" + source.project +
|
|
109
|
+
"/_apis/git/repositories/" + source.unscoped_repo +
|
|
110
|
+
"/refs?filter=heads/" + branch_name)
|
|
111
|
+
|
|
112
|
+
JSON.parse(response.body).fetch("value").first
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def pull_requests(source_branch, target_branch)
|
|
116
|
+
response = get(source.api_endpoint +
|
|
117
|
+
source.organization + "/" + source.project +
|
|
118
|
+
"/_apis/git/repositories/" + source.unscoped_repo +
|
|
119
|
+
"/pullrequests?searchCriteria.status=all" \
|
|
120
|
+
"&searchCriteria.sourceRefName=refs/heads/" + source_branch +
|
|
121
|
+
"&searchCriteria.targetRefName=refs/heads/" + target_branch)
|
|
122
|
+
|
|
123
|
+
JSON.parse(response.body).fetch("value")
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def create_commit(branch_name, base_commit, commit_message, files)
|
|
127
|
+
content = {
|
|
128
|
+
refUpdates: [
|
|
129
|
+
{ name: "refs/heads/" + branch_name, oldObjectId: base_commit }
|
|
130
|
+
],
|
|
131
|
+
commits: [
|
|
132
|
+
{
|
|
133
|
+
comment: commit_message,
|
|
134
|
+
changes: files.map do |file|
|
|
135
|
+
{
|
|
136
|
+
changeType: "edit",
|
|
137
|
+
item: { path: file.path },
|
|
138
|
+
newContent: {
|
|
139
|
+
content: Base64.encode64(file.content),
|
|
140
|
+
contentType: "base64encoded"
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
end
|
|
144
|
+
}
|
|
145
|
+
]
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
post(source.api_endpoint + source.organization + "/" + source.project +
|
|
149
|
+
"/_apis/git/repositories/" + source.unscoped_repo +
|
|
150
|
+
"/pushes?api-version=5.0", content.to_json)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def create_pull_request(pr_name, source_branch, target_branch,
|
|
154
|
+
pr_description, labels)
|
|
155
|
+
# Azure DevOps only support descriptions up to 4000 characters (https://developercommunity.visualstudio.com/content/problem/608770/remove-4000-character-limit-on-pull-request-descri.html)
|
|
156
|
+
azure_max_length = 3999
|
|
157
|
+
if pr_description.length > azure_max_length
|
|
158
|
+
truncated_msg = "...\n\n_Description has been truncated_"
|
|
159
|
+
truncate_length = azure_max_length - truncated_msg.length
|
|
160
|
+
pr_description = pr_description[0..truncate_length] + truncated_msg
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
content = {
|
|
164
|
+
sourceRefName: "refs/heads/" + source_branch,
|
|
165
|
+
targetRefName: "refs/heads/" + target_branch,
|
|
166
|
+
title: pr_name,
|
|
167
|
+
description: pr_description,
|
|
168
|
+
labels: labels.map { |label| { name: label } }
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
post(source.api_endpoint +
|
|
172
|
+
source.organization + "/" + source.project +
|
|
173
|
+
"/_apis/git/repositories/" + source.unscoped_repo +
|
|
174
|
+
"/pullrequests?api-version=5.0", content.to_json)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def get(url)
|
|
178
|
+
response = Excon.get(
|
|
179
|
+
url,
|
|
180
|
+
user: credentials&.fetch("username"),
|
|
181
|
+
password: credentials&.fetch("password"),
|
|
182
|
+
idempotent: true,
|
|
183
|
+
**SharedHelpers.excon_defaults
|
|
184
|
+
)
|
|
185
|
+
raise NotFound if response.status == 404
|
|
186
|
+
|
|
187
|
+
response
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def post(url, json)
|
|
191
|
+
response = Excon.post(
|
|
192
|
+
url,
|
|
193
|
+
headers: {
|
|
194
|
+
"Content-Type" => "application/json"
|
|
195
|
+
},
|
|
196
|
+
body: json,
|
|
197
|
+
user: credentials&.fetch("username"),
|
|
198
|
+
password: credentials&.fetch("password"),
|
|
199
|
+
idempotent: true,
|
|
200
|
+
**SharedHelpers.excon_defaults
|
|
201
|
+
)
|
|
202
|
+
raise NotFound if response.status == 404
|
|
203
|
+
|
|
204
|
+
response
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
private
|
|
208
|
+
|
|
209
|
+
attr_reader :credentials
|
|
210
|
+
attr_reader :source
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
end
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require "dependabot/dependency_file"
|
|
4
4
|
require "dependabot/source"
|
|
5
5
|
require "dependabot/errors"
|
|
6
|
+
require "dependabot/clients/azure"
|
|
6
7
|
require "dependabot/clients/github_with_retries"
|
|
7
8
|
require "dependabot/clients/bitbucket_with_retries"
|
|
8
9
|
require "dependabot/clients/gitlab_with_retries"
|
|
@@ -17,6 +18,7 @@ module Dependabot
|
|
|
17
18
|
CLIENT_NOT_FOUND_ERRORS = [
|
|
18
19
|
Octokit::NotFound,
|
|
19
20
|
Gitlab::Error::NotFound,
|
|
21
|
+
Dependabot::Clients::Azure::NotFound,
|
|
20
22
|
Dependabot::Clients::Bitbucket::NotFound
|
|
21
23
|
].freeze
|
|
22
24
|
|
|
@@ -144,6 +146,8 @@ module Dependabot
|
|
|
144
146
|
_github_repo_contents(repo, path, commit)
|
|
145
147
|
when "gitlab"
|
|
146
148
|
_gitlab_repo_contents(repo, path, commit)
|
|
149
|
+
when "azure"
|
|
150
|
+
_azure_repo_contents(path, commit)
|
|
147
151
|
when "bitbucket"
|
|
148
152
|
_bitbucket_repo_contents(repo, path, commit)
|
|
149
153
|
else raise "Unsupported provider '#{provider}'."
|
|
@@ -214,6 +218,25 @@ module Dependabot
|
|
|
214
218
|
end
|
|
215
219
|
end
|
|
216
220
|
|
|
221
|
+
def _azure_repo_contents(path, commit)
|
|
222
|
+
response = azure_client.fetch_repo_contents(commit, path)
|
|
223
|
+
|
|
224
|
+
response.map do |entry|
|
|
225
|
+
type = case entry.fetch("gitObjectType")
|
|
226
|
+
when "blob" then "file"
|
|
227
|
+
when "tree" then "dir"
|
|
228
|
+
else entry.fetch("gitObjectType")
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
OpenStruct.new(
|
|
232
|
+
name: File.basename(entry.fetch("relativePath")),
|
|
233
|
+
path: entry.fetch("relativePath"),
|
|
234
|
+
type: type,
|
|
235
|
+
size: entry.fetch("size")
|
|
236
|
+
)
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
217
240
|
def _bitbucket_repo_contents(repo, path, commit)
|
|
218
241
|
response = bitbucket_client.fetch_repo_contents(
|
|
219
242
|
repo,
|
|
@@ -289,6 +312,8 @@ module Dependabot
|
|
|
289
312
|
when "gitlab"
|
|
290
313
|
tmp = gitlab_client.get_file(repo, path, commit).content
|
|
291
314
|
Base64.decode64(tmp).force_encoding("UTF-8").encode
|
|
315
|
+
when "azure"
|
|
316
|
+
azure_client.fetch_file_contents(commit, path)
|
|
292
317
|
when "bitbucket"
|
|
293
318
|
bitbucket_client.fetch_file_contents(repo, commit, path)
|
|
294
319
|
else raise "Unsupported provider '#{source.provider}'."
|
|
@@ -362,6 +387,7 @@ module Dependabot
|
|
|
362
387
|
case source.provider
|
|
363
388
|
when "github" then github_client
|
|
364
389
|
when "gitlab" then gitlab_client
|
|
390
|
+
when "azure" then azure_client
|
|
365
391
|
when "bitbucket" then bitbucket_client
|
|
366
392
|
else raise "Unsupported provider '#{source.provider}'."
|
|
367
393
|
end
|
|
@@ -383,6 +409,12 @@ module Dependabot
|
|
|
383
409
|
)
|
|
384
410
|
end
|
|
385
411
|
|
|
412
|
+
def azure_client
|
|
413
|
+
@azure_client ||=
|
|
414
|
+
Dependabot::Clients::Azure.
|
|
415
|
+
for_source(source: source, credentials: credentials)
|
|
416
|
+
end
|
|
417
|
+
|
|
386
418
|
def bitbucket_client
|
|
387
419
|
# TODO: When self-hosted Bitbucket is supported this should use
|
|
388
420
|
# `Bitbucket.for_source`
|
|
@@ -4,6 +4,7 @@ require "dependabot/metadata_finders"
|
|
|
4
4
|
|
|
5
5
|
module Dependabot
|
|
6
6
|
class PullRequestCreator
|
|
7
|
+
require "dependabot/pull_request_creator/azure"
|
|
7
8
|
require "dependabot/pull_request_creator/github"
|
|
8
9
|
require "dependabot/pull_request_creator/gitlab"
|
|
9
10
|
require "dependabot/pull_request_creator/message_builder"
|
|
@@ -68,6 +69,7 @@ module Dependabot
|
|
|
68
69
|
case source.provider
|
|
69
70
|
when "github" then github_creator.create
|
|
70
71
|
when "gitlab" then gitlab_creator.create
|
|
72
|
+
when "azure" then azure_creator.create
|
|
71
73
|
else raise "Unsupported provider #{source.provider}"
|
|
72
74
|
end
|
|
73
75
|
end
|
|
@@ -120,6 +122,20 @@ module Dependabot
|
|
|
120
122
|
)
|
|
121
123
|
end
|
|
122
124
|
|
|
125
|
+
def azure_creator
|
|
126
|
+
Azure.new(
|
|
127
|
+
source: source,
|
|
128
|
+
branch_name: branch_namer.new_branch_name,
|
|
129
|
+
base_commit: base_commit,
|
|
130
|
+
credentials: credentials,
|
|
131
|
+
files: files,
|
|
132
|
+
commit_message: message_builder.commit_message,
|
|
133
|
+
pr_description: message_builder.pr_message,
|
|
134
|
+
pr_name: message_builder.pr_name,
|
|
135
|
+
labeler: labeler
|
|
136
|
+
)
|
|
137
|
+
end
|
|
138
|
+
|
|
123
139
|
def message_builder
|
|
124
140
|
@message_builder ||
|
|
125
141
|
MessageBuilder.new(
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "dependabot/clients/azure"
|
|
4
|
+
require "dependabot/pull_request_creator"
|
|
5
|
+
|
|
6
|
+
module Dependabot
|
|
7
|
+
class PullRequestCreator
|
|
8
|
+
class Azure
|
|
9
|
+
attr_reader :source, :branch_name, :base_commit, :credentials,
|
|
10
|
+
:files, :commit_message, :pr_description, :pr_name,
|
|
11
|
+
:labeler
|
|
12
|
+
|
|
13
|
+
def initialize(source:, branch_name:, base_commit:, credentials:,
|
|
14
|
+
files:, commit_message:, pr_description:, pr_name:,
|
|
15
|
+
labeler:)
|
|
16
|
+
@source = source
|
|
17
|
+
@branch_name = branch_name
|
|
18
|
+
@base_commit = base_commit
|
|
19
|
+
@credentials = credentials
|
|
20
|
+
@files = files
|
|
21
|
+
@commit_message = commit_message
|
|
22
|
+
@pr_description = pr_description
|
|
23
|
+
@pr_name = pr_name
|
|
24
|
+
@labeler = labeler
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def create
|
|
28
|
+
return if branch_exists? && pull_request_exists?
|
|
29
|
+
|
|
30
|
+
create_commit unless branch_exists? && commit_exists?
|
|
31
|
+
|
|
32
|
+
create_pull_request
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def azure_client_for_source
|
|
38
|
+
@azure_client_for_source ||=
|
|
39
|
+
Dependabot::Clients::Azure.for_source(
|
|
40
|
+
source: source,
|
|
41
|
+
credentials: credentials
|
|
42
|
+
)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def branch_exists?
|
|
46
|
+
@branch_ref ||=
|
|
47
|
+
azure_client_for_source.branch(branch_name)
|
|
48
|
+
|
|
49
|
+
@branch_ref
|
|
50
|
+
rescue ::Azure::Error::NotFound
|
|
51
|
+
false
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def commit_exists?
|
|
55
|
+
@commits ||=
|
|
56
|
+
azure_client_for_source.commits(branch_name)
|
|
57
|
+
commit_message.start_with?(@commits.first.fetch("comment"))
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def pull_request_exists?
|
|
61
|
+
azure_client_for_source.pull_requests(
|
|
62
|
+
branch_name,
|
|
63
|
+
source.branch || default_branch
|
|
64
|
+
).any?
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def create_commit
|
|
68
|
+
azure_client_for_source.create_commit(
|
|
69
|
+
branch_name,
|
|
70
|
+
base_commit,
|
|
71
|
+
commit_message,
|
|
72
|
+
files
|
|
73
|
+
)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def create_pull_request
|
|
77
|
+
azure_client_for_source.create_pull_request(
|
|
78
|
+
pr_name,
|
|
79
|
+
branch_name,
|
|
80
|
+
source.branch || default_branch,
|
|
81
|
+
pr_description,
|
|
82
|
+
labeler.labels_for_pr
|
|
83
|
+
)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def default_branch
|
|
87
|
+
@default_branch ||=
|
|
88
|
+
azure_client_for_source.fetch_default_branch(source.repo)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -221,6 +221,7 @@ module Dependabot
|
|
|
221
221
|
case source.provider
|
|
222
222
|
when "github" then fetch_github_labels
|
|
223
223
|
when "gitlab" then fetch_gitlab_labels
|
|
224
|
+
when "azure" then fetch_azure_labels
|
|
224
225
|
else raise "Unsupported provider #{source.provider}"
|
|
225
226
|
end
|
|
226
227
|
end
|
|
@@ -251,10 +252,19 @@ module Dependabot
|
|
|
251
252
|
map(&:name)
|
|
252
253
|
end
|
|
253
254
|
|
|
255
|
+
def fetch_azure_labels
|
|
256
|
+
langauge_name =
|
|
257
|
+
self.class.label_details_for_package_manager(package_manager).
|
|
258
|
+
fetch(:name)
|
|
259
|
+
|
|
260
|
+
@labels = [*@labels, "dependencies", "security", langauge_name].uniq
|
|
261
|
+
end
|
|
262
|
+
|
|
254
263
|
def create_dependencies_label
|
|
255
264
|
case source.provider
|
|
256
265
|
when "github" then create_github_dependencies_label
|
|
257
266
|
when "gitlab" then create_gitlab_dependencies_label
|
|
267
|
+
when "azure" then @labels # Azure does not have centralised labels
|
|
258
268
|
else raise "Unsupported provider #{source.provider}"
|
|
259
269
|
end
|
|
260
270
|
end
|
|
@@ -263,6 +273,7 @@ module Dependabot
|
|
|
263
273
|
case source.provider
|
|
264
274
|
when "github" then create_github_security_label
|
|
265
275
|
when "gitlab" then create_gitlab_security_label
|
|
276
|
+
when "azure" then @labels # Azure does not have centralised labels
|
|
266
277
|
else raise "Unsupported provider #{source.provider}"
|
|
267
278
|
end
|
|
268
279
|
end
|
|
@@ -271,6 +282,7 @@ module Dependabot
|
|
|
271
282
|
case source.provider
|
|
272
283
|
when "github" then create_github_language_label
|
|
273
284
|
when "gitlab" then create_gitlab_language_label
|
|
285
|
+
when "azure" then @labels # Azure does not have centralised labels
|
|
274
286
|
else raise "Unsupported provider #{source.provider}"
|
|
275
287
|
end
|
|
276
288
|
end
|
|
@@ -417,9 +417,14 @@ module Dependabot
|
|
|
417
417
|
end
|
|
418
418
|
|
|
419
419
|
def build_details_tag(summary:, body:)
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
420
|
+
# Azure DevOps does not support <details> tag (https://developercommunity.visualstudio.com/content/problem/608769/add-support-for-in-markdown.html)
|
|
421
|
+
if source.provider == "azure"
|
|
422
|
+
"\n\##{summary}\n\n#{body}"
|
|
423
|
+
else
|
|
424
|
+
msg = "\n<details>\n<summary>#{summary}</summary>\n\n"
|
|
425
|
+
msg += body
|
|
426
|
+
msg + "</details>"
|
|
427
|
+
end
|
|
423
428
|
end
|
|
424
429
|
|
|
425
430
|
def serialized_vulnerability_details(details)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "dependabot/clients/azure"
|
|
3
4
|
require "dependabot/clients/github_with_retries"
|
|
4
5
|
require "dependabot/clients/gitlab_with_retries"
|
|
5
6
|
require "dependabot/pull_request_creator"
|
|
@@ -267,10 +268,15 @@ module Dependabot
|
|
|
267
268
|
case source.provider
|
|
268
269
|
when "github" then recent_github_commit_messages
|
|
269
270
|
when "gitlab" then recent_gitlab_commit_messages
|
|
271
|
+
when "azure" then recent_azure_commit_messages
|
|
270
272
|
else raise "Unsupported provider: #{source.provider}"
|
|
271
273
|
end
|
|
272
274
|
end
|
|
273
275
|
|
|
276
|
+
def dependabot_email
|
|
277
|
+
"support@dependabot.com"
|
|
278
|
+
end
|
|
279
|
+
|
|
274
280
|
def recent_github_commit_messages
|
|
275
281
|
recent_github_commits.
|
|
276
282
|
reject { |c| c.author&.type == "Bot" }.
|
|
@@ -286,18 +292,31 @@ module Dependabot
|
|
|
286
292
|
gitlab_client_for_source.commits(source.repo)
|
|
287
293
|
|
|
288
294
|
@recent_gitlab_commit_messages.
|
|
289
|
-
reject { |c| c.author_email ==
|
|
295
|
+
reject { |c| c.author_email == dependabot_email }.
|
|
290
296
|
reject { |c| c.message&.start_with?("merge !") }.
|
|
291
297
|
map(&:message).
|
|
292
298
|
compact.
|
|
293
299
|
map(&:strip)
|
|
294
300
|
end
|
|
295
301
|
|
|
302
|
+
def recent_azure_commit_messages
|
|
303
|
+
@recent_azure_commit_messages ||=
|
|
304
|
+
azure_client_for_source.commits
|
|
305
|
+
|
|
306
|
+
@recent_azure_commit_messages.
|
|
307
|
+
reject { |c| c.fetch("author").fetch("email") == dependabot_email }.
|
|
308
|
+
reject { |c| c.fetch("comment")&.start_with?("Merge") }.
|
|
309
|
+
map { |c| c.fetch("comment") }.
|
|
310
|
+
compact.
|
|
311
|
+
map(&:strip)
|
|
312
|
+
end
|
|
313
|
+
|
|
296
314
|
def last_dependabot_commit_message
|
|
297
315
|
@last_dependabot_commit_message ||=
|
|
298
316
|
case source.provider
|
|
299
317
|
when "github" then last_github_dependabot_commit_message
|
|
300
318
|
when "gitlab" then last_gitlab_dependabot_commit_message
|
|
319
|
+
when "azure" then last_azure_dependabot_commit_message
|
|
301
320
|
else raise "Unsupported provider: #{source.provider}"
|
|
302
321
|
end
|
|
303
322
|
end
|
|
@@ -323,7 +342,17 @@ module Dependabot
|
|
|
323
342
|
gitlab_client_for_source.commits(source.repo)
|
|
324
343
|
|
|
325
344
|
@recent_gitlab_commit_messages.
|
|
326
|
-
find { |c| c.author_email ==
|
|
345
|
+
find { |c| c.author_email == dependabot_email }&.
|
|
346
|
+
message&.
|
|
347
|
+
strip
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
def last_azure_dependabot_commit_message
|
|
351
|
+
@recent_azure_commit_messages ||=
|
|
352
|
+
azure_client_for_source.commits
|
|
353
|
+
|
|
354
|
+
@recent_azure_commit_messages.
|
|
355
|
+
find { |c| c.fetch("author").fetch("email") == dependabot_email }&.
|
|
327
356
|
message&.
|
|
328
357
|
strip
|
|
329
358
|
end
|
|
@@ -344,6 +373,14 @@ module Dependabot
|
|
|
344
373
|
)
|
|
345
374
|
end
|
|
346
375
|
|
|
376
|
+
def azure_client_for_source
|
|
377
|
+
@azure_client_for_source ||=
|
|
378
|
+
Dependabot::Clients::Azure.for_source(
|
|
379
|
+
source: source,
|
|
380
|
+
credentials: credentials
|
|
381
|
+
)
|
|
382
|
+
end
|
|
383
|
+
|
|
347
384
|
def package_manager
|
|
348
385
|
@package_manager ||= dependencies.first.package_manager
|
|
349
386
|
end
|
data/lib/dependabot/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dependabot-common
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.110.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dependabot
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2019-06-
|
|
11
|
+
date: 2019-06-27 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: aws-sdk-ecr
|
|
@@ -311,6 +311,7 @@ extra_rdoc_files: []
|
|
|
311
311
|
files:
|
|
312
312
|
- bin/git-credential-store-immutable
|
|
313
313
|
- lib/dependabot.rb
|
|
314
|
+
- lib/dependabot/clients/azure.rb
|
|
314
315
|
- lib/dependabot/clients/bitbucket.rb
|
|
315
316
|
- lib/dependabot/clients/bitbucket_with_retries.rb
|
|
316
317
|
- lib/dependabot/clients/github_with_retries.rb
|
|
@@ -338,6 +339,7 @@ files:
|
|
|
338
339
|
- lib/dependabot/metadata_finders/base/commits_finder.rb
|
|
339
340
|
- lib/dependabot/metadata_finders/base/release_finder.rb
|
|
340
341
|
- lib/dependabot/pull_request_creator.rb
|
|
342
|
+
- lib/dependabot/pull_request_creator/azure.rb
|
|
341
343
|
- lib/dependabot/pull_request_creator/branch_namer.rb
|
|
342
344
|
- lib/dependabot/pull_request_creator/commit_signer.rb
|
|
343
345
|
- lib/dependabot/pull_request_creator/github.rb
|