dependabot-common 0.244.0 → 0.246.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/dependabot/clients/bitbucket.rb +113 -5
- data/lib/dependabot/clients/bitbucket_with_retries.rb +34 -10
- data/lib/dependabot/clients/codecommit.rb +107 -12
- data/lib/dependabot/clients/github_with_retries.rb +61 -19
- data/lib/dependabot/clients/gitlab_with_retries.rb +60 -7
- data/lib/dependabot/dependency.rb +1 -1
- data/lib/dependabot/errors.rb +8 -2
- data/lib/dependabot/git_commit_checker.rb +4 -3
- data/lib/dependabot/metadata_finders/base/changelog_finder.rb +1 -1
- data/lib/dependabot/metadata_finders/base/commits_finder.rb +1 -1
- data/lib/dependabot/metadata_finders/base/release_finder.rb +1 -1
- data/lib/dependabot/pull_request_creator/azure.rb +80 -9
- data/lib/dependabot/pull_request_creator/bitbucket.rb +73 -9
- data/lib/dependabot/pull_request_creator/codecommit.rb +96 -25
- data/lib/dependabot/pull_request_creator/github.rb +162 -49
- data/lib/dependabot/pull_request_creator/gitlab.rb +109 -21
- data/lib/dependabot/pull_request_creator/message_builder.rb +239 -89
- data/lib/dependabot/pull_request_creator/pr_name_prefixer.rb +11 -9
- data/lib/dependabot/pull_request_creator.rb +32 -27
- data/lib/dependabot/pull_request_updater/azure.rb +75 -11
- data/lib/dependabot/pull_request_updater/github.rb +89 -28
- data/lib/dependabot/pull_request_updater/gitlab.rb +61 -12
- data/lib/dependabot/pull_request_updater.rb +1 -1
- data/lib/dependabot/shared_helpers.rb +19 -1
- data/lib/dependabot/update_checkers/base.rb +121 -31
- data/lib/dependabot.rb +1 -1
- metadata +3 -3
@@ -1,12 +1,14 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "octokit"
|
5
5
|
require "securerandom"
|
6
6
|
require "sorbet-runtime"
|
7
|
+
|
7
8
|
require "dependabot/clients/github_with_retries"
|
8
9
|
require "dependabot/pull_request_creator"
|
9
10
|
require "dependabot/pull_request_creator/commit_signer"
|
11
|
+
|
10
12
|
module Dependabot
|
11
13
|
class PullRequestCreator
|
12
14
|
# rubocop:disable Metrics/ClassLength
|
@@ -17,11 +19,72 @@ module Dependabot
|
|
17
19
|
# https://github.com/orgs/community/discussions/27190#discussioncomment-3726017
|
18
20
|
PR_DESCRIPTION_MAX_LENGTH = 65_535 # 0 based count
|
19
21
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
22
|
+
sig { returns(Dependabot::Source) }
|
23
|
+
attr_reader :source
|
24
|
+
|
25
|
+
sig { returns(String) }
|
26
|
+
attr_reader :branch_name
|
27
|
+
|
28
|
+
sig { returns(String) }
|
29
|
+
attr_reader :base_commit
|
30
|
+
|
31
|
+
sig { returns(T::Array[Dependabot::Credential]) }
|
32
|
+
attr_reader :credentials
|
33
|
+
|
34
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
35
|
+
attr_reader :files
|
36
|
+
|
37
|
+
sig { returns(String) }
|
38
|
+
attr_reader :pr_description
|
39
|
+
|
40
|
+
sig { returns(String) }
|
41
|
+
attr_reader :pr_name
|
42
|
+
|
43
|
+
sig { returns(String) }
|
44
|
+
attr_reader :commit_message
|
45
|
+
|
46
|
+
sig { returns(T.nilable(T::Hash[Symbol, String])) }
|
47
|
+
attr_reader :author_details
|
48
|
+
|
49
|
+
sig { returns(T.nilable(String)) }
|
50
|
+
attr_reader :signature_key
|
51
|
+
|
52
|
+
sig { returns(T.nilable(T::Hash[String, String])) }
|
53
|
+
attr_reader :custom_headers
|
24
54
|
|
55
|
+
sig { returns(Dependabot::PullRequestCreator::Labeler) }
|
56
|
+
attr_reader :labeler
|
57
|
+
|
58
|
+
sig { returns(T.nilable(T::Hash[String, T::Array[String]])) }
|
59
|
+
attr_reader :reviewers
|
60
|
+
|
61
|
+
sig { returns(T.nilable(T::Array[String])) }
|
62
|
+
attr_reader :assignees
|
63
|
+
|
64
|
+
sig { returns(T.nilable(Integer)) }
|
65
|
+
attr_reader :milestone
|
66
|
+
|
67
|
+
sig do
|
68
|
+
params(
|
69
|
+
source: Dependabot::Source,
|
70
|
+
branch_name: String,
|
71
|
+
base_commit: String,
|
72
|
+
credentials: T::Array[Dependabot::Credential],
|
73
|
+
files: T::Array[Dependabot::DependencyFile],
|
74
|
+
commit_message: String,
|
75
|
+
pr_description: String,
|
76
|
+
pr_name: String,
|
77
|
+
author_details: T.nilable(T::Hash[Symbol, String]),
|
78
|
+
signature_key: T.nilable(String),
|
79
|
+
custom_headers: T.nilable(T::Hash[String, String]),
|
80
|
+
labeler: Dependabot::PullRequestCreator::Labeler,
|
81
|
+
reviewers: T.nilable(T::Hash[String, T::Array[String]]),
|
82
|
+
assignees: T.nilable(T::Array[String]),
|
83
|
+
milestone: T.nilable(Integer),
|
84
|
+
require_up_to_date_base: T::Boolean
|
85
|
+
)
|
86
|
+
.void
|
87
|
+
end
|
25
88
|
def initialize(source:, branch_name:, base_commit:, credentials:,
|
26
89
|
files:, commit_message:, pr_description:, pr_name:,
|
27
90
|
author_details:, signature_key:, custom_headers:,
|
@@ -45,6 +108,7 @@ module Dependabot
|
|
45
108
|
@require_up_to_date_base = require_up_to_date_base
|
46
109
|
end
|
47
110
|
|
111
|
+
sig { returns(T.untyped) }
|
48
112
|
def create
|
49
113
|
if branch_exists?(branch_name) && unmerged_pull_request_exists?
|
50
114
|
raise UnmergedPRExists, "PR ##{unmerged_pull_requests.first.number} already exists"
|
@@ -60,11 +124,13 @@ module Dependabot
|
|
60
124
|
|
61
125
|
private
|
62
126
|
|
127
|
+
sig { returns(T::Boolean) }
|
63
128
|
def require_up_to_date_base?
|
64
129
|
@require_up_to_date_base
|
65
130
|
end
|
66
131
|
|
67
132
|
# rubocop:disable Metrics/PerceivedComplexity
|
133
|
+
sig { params(name: String).returns(T::Boolean) }
|
68
134
|
def branch_exists?(name)
|
69
135
|
git_metadata_fetcher.ref_names.include?(name)
|
70
136
|
rescue Dependabot::GitDependenciesNotReachable => e
|
@@ -82,48 +148,60 @@ module Dependabot
|
|
82
148
|
end
|
83
149
|
# rubocop:enable Metrics/PerceivedComplexity
|
84
150
|
|
151
|
+
sig { returns(T::Boolean) }
|
85
152
|
def unmerged_pull_request_exists?
|
86
153
|
unmerged_pull_requests.any?
|
87
154
|
end
|
88
155
|
|
156
|
+
sig { returns(T::Array[T.untyped]) }
|
89
157
|
def unmerged_pull_requests
|
90
158
|
pull_requests_for_branch.reject(&:merged)
|
91
159
|
end
|
92
160
|
|
161
|
+
sig { returns(T::Array[T.untyped]) }
|
93
162
|
def pull_requests_for_branch
|
94
163
|
@pull_requests_for_branch ||=
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
164
|
+
T.let(
|
165
|
+
begin
|
166
|
+
T.unsafe(github_client_for_source).pull_requests(
|
167
|
+
source.repo,
|
168
|
+
head: "#{source.repo.split('/').first}:#{branch_name}",
|
169
|
+
state: "all"
|
170
|
+
)
|
171
|
+
rescue Octokit::InternalServerError
|
172
|
+
# A GitHub bug sometimes means adding `state: all` causes problems.
|
173
|
+
# In that case, fall back to making two separate requests.
|
174
|
+
open_prs = T.unsafe(github_client_for_source).pull_requests(
|
175
|
+
source.repo,
|
176
|
+
head: "#{source.repo.split('/').first}:#{branch_name}",
|
177
|
+
state: "open"
|
178
|
+
)
|
179
|
+
|
180
|
+
closed_prs = T.unsafe(github_client_for_source).pull_requests(
|
181
|
+
source.repo,
|
182
|
+
head: "#{source.repo.split('/').first}:#{branch_name}",
|
183
|
+
state: "closed"
|
184
|
+
)
|
185
|
+
[*open_prs, *closed_prs]
|
186
|
+
end,
|
187
|
+
T.nilable(T::Array[T.untyped])
|
188
|
+
)
|
117
189
|
end
|
118
190
|
|
191
|
+
sig { returns(T::Boolean) }
|
119
192
|
def base_commit_is_up_to_date?
|
120
193
|
head_commit == base_commit
|
121
194
|
end
|
122
195
|
|
196
|
+
sig { returns(T.nilable(String)) }
|
123
197
|
def head_commit
|
124
|
-
@head_commit ||=
|
198
|
+
@head_commit ||= T.let(
|
199
|
+
git_metadata_fetcher.head_commit_for_ref(target_branch),
|
200
|
+
T.nilable(String)
|
201
|
+
)
|
125
202
|
end
|
126
203
|
|
204
|
+
sig { returns(T.untyped) }
|
127
205
|
def create_annotated_pull_request
|
128
206
|
commit = create_commit
|
129
207
|
branch = create_or_update_branch(commit)
|
@@ -141,18 +219,20 @@ module Dependabot
|
|
141
219
|
pull_request
|
142
220
|
end
|
143
221
|
|
222
|
+
sig { returns(T::Boolean) }
|
144
223
|
def repo_exists?
|
145
|
-
github_client_for_source.repo(source.repo)
|
224
|
+
T.unsafe(github_client_for_source).repo(source.repo)
|
146
225
|
true
|
147
226
|
rescue Octokit::NotFound
|
148
227
|
false
|
149
228
|
end
|
150
229
|
|
230
|
+
sig { returns(T.untyped) }
|
151
231
|
def create_commit
|
152
232
|
tree = create_tree
|
153
233
|
|
154
234
|
begin
|
155
|
-
github_client_for_source.create_commit(
|
235
|
+
T.unsafe(github_client_for_source).create_commit(
|
156
236
|
source.repo,
|
157
237
|
commit_message,
|
158
238
|
tree.sha,
|
@@ -164,6 +244,7 @@ module Dependabot
|
|
164
244
|
|
165
245
|
# Sometimes a race condition on GitHub's side means we get an error
|
166
246
|
# here. No harm in retrying if we do.
|
247
|
+
@commit_creation ||= T.let(0, T.nilable(Integer))
|
167
248
|
raise_or_increment_retry_counter(counter: @commit_creation, limit: 3)
|
168
249
|
sleep(rand(1..1.99))
|
169
250
|
retry
|
@@ -171,11 +252,13 @@ module Dependabot
|
|
171
252
|
rescue Octokit::UnprocessableEntity => e
|
172
253
|
raise unless e.message == "Tree SHA does not exist"
|
173
254
|
|
255
|
+
@tree_creation ||= T.let(0, T.nilable(Integer))
|
174
256
|
raise_or_increment_retry_counter(counter: @tree_creation, limit: 1)
|
175
257
|
sleep(rand(1..1.99))
|
176
258
|
retry
|
177
259
|
end
|
178
260
|
|
261
|
+
sig { params(tree: T.untyped).returns(T::Hash[Symbol, T.untyped]) }
|
179
262
|
def commit_options(tree)
|
180
263
|
options = author_details&.any? ? { author: author_details } : {}
|
181
264
|
|
@@ -187,6 +270,7 @@ module Dependabot
|
|
187
270
|
options
|
188
271
|
end
|
189
272
|
|
273
|
+
sig { returns(T.untyped) }
|
190
274
|
def create_tree
|
191
275
|
file_trees = files.map do |file|
|
192
276
|
if file.type == "submodule"
|
@@ -200,7 +284,7 @@ module Dependabot
|
|
200
284
|
content = if file.operation == Dependabot::DependencyFile::Operation::DELETE
|
201
285
|
{ sha: nil }
|
202
286
|
elsif file.binary?
|
203
|
-
sha = github_client_for_source.create_blob(
|
287
|
+
sha = T.unsafe(github_client_for_source).create_blob(
|
204
288
|
source.repo, file.content, "base64"
|
205
289
|
)
|
206
290
|
{ sha: sha }
|
@@ -216,13 +300,14 @@ module Dependabot
|
|
216
300
|
end
|
217
301
|
end
|
218
302
|
|
219
|
-
github_client_for_source.create_tree(
|
303
|
+
T.unsafe(github_client_for_source).create_tree(
|
220
304
|
source.repo,
|
221
305
|
file_trees,
|
222
306
|
base_tree: base_commit
|
223
307
|
)
|
224
308
|
end
|
225
309
|
|
310
|
+
sig { params(commit: T.untyped).returns(T.untyped) }
|
226
311
|
def create_or_update_branch(commit)
|
227
312
|
if branch_exists?(branch_name)
|
228
313
|
update_branch(commit)
|
@@ -241,12 +326,13 @@ module Dependabot
|
|
241
326
|
retry
|
242
327
|
end
|
243
328
|
|
329
|
+
sig { params(commit: T.untyped).returns(T.untyped) }
|
244
330
|
def create_branch(commit)
|
245
331
|
ref = "refs/heads/#{branch_name}"
|
246
332
|
|
247
333
|
begin
|
248
334
|
branch =
|
249
|
-
github_client_for_source.create_ref(source.repo, ref, commit.sha)
|
335
|
+
T.unsafe(github_client_for_source).create_ref(source.repo, ref, commit.sha)
|
250
336
|
@branch_name = ref.gsub(%r{^refs/heads/}, "")
|
251
337
|
branch
|
252
338
|
rescue Octokit::UnprocessableEntity => e
|
@@ -264,8 +350,9 @@ module Dependabot
|
|
264
350
|
end
|
265
351
|
end
|
266
352
|
|
353
|
+
sig { params(commit: T.untyped).void }
|
267
354
|
def update_branch(commit)
|
268
|
-
github_client_for_source.update_ref(
|
355
|
+
T.unsafe(github_client_for_source).update_ref(
|
269
356
|
source.repo,
|
270
357
|
"heads/#{branch_name}",
|
271
358
|
commit.sha,
|
@@ -273,6 +360,7 @@ module Dependabot
|
|
273
360
|
)
|
274
361
|
end
|
275
362
|
|
363
|
+
sig { params(pull_request: T.untyped).void }
|
276
364
|
def annotate_pull_request(pull_request)
|
277
365
|
labeler.label_pull_request(pull_request.number)
|
278
366
|
add_reviewers_to_pull_request(pull_request) if reviewers&.any?
|
@@ -280,11 +368,12 @@ module Dependabot
|
|
280
368
|
add_milestone_to_pull_request(pull_request) if milestone
|
281
369
|
end
|
282
370
|
|
371
|
+
sig { params(pull_request: T.untyped).void }
|
283
372
|
def add_reviewers_to_pull_request(pull_request)
|
284
373
|
reviewers_hash =
|
285
|
-
reviewers.keys.to_h { |k| [k.to_sym, reviewers[k]] }
|
374
|
+
T.must(reviewers).keys.to_h { |k| [k.to_sym, T.must(reviewers)[k]] }
|
286
375
|
|
287
|
-
github_client_for_source.request_pull_request_review(
|
376
|
+
T.unsafe(github_client_for_source).request_pull_request_review(
|
288
377
|
source.repo,
|
289
378
|
pull_request.number,
|
290
379
|
reviewers: reviewers_hash[:reviewers] || [],
|
@@ -302,6 +391,7 @@ module Dependabot
|
|
302
391
|
raise
|
303
392
|
end
|
304
393
|
|
394
|
+
sig { params(message: String).returns(T::Boolean) }
|
305
395
|
def invalid_reviewer?(message)
|
306
396
|
return true if message.include?("Could not resolve to a node")
|
307
397
|
return true if message.include?("not a collaborator")
|
@@ -310,9 +400,10 @@ module Dependabot
|
|
310
400
|
false
|
311
401
|
end
|
312
402
|
|
403
|
+
sig { params(pull_request: T.untyped, message: String).void }
|
313
404
|
def comment_with_invalid_reviewer(pull_request, message)
|
314
405
|
reviewers_hash =
|
315
|
-
reviewers.keys.to_h { |k| [k.to_sym, reviewers[k]] }
|
406
|
+
T.must(reviewers).keys.to_h { |k| [k.to_sym, T.must(reviewers)[k]] }
|
316
407
|
reviewers = []
|
317
408
|
reviewers += reviewers_hash[:reviewers] || []
|
318
409
|
reviewers += (reviewers_hash[:team_reviewers] || [])
|
@@ -333,15 +424,16 @@ module Dependabot
|
|
333
424
|
"#{message}\n" \
|
334
425
|
"```"
|
335
426
|
|
336
|
-
github_client_for_source.add_comment(
|
427
|
+
T.unsafe(github_client_for_source).add_comment(
|
337
428
|
source.repo,
|
338
429
|
pull_request.number,
|
339
430
|
msg
|
340
431
|
)
|
341
432
|
end
|
342
433
|
|
434
|
+
sig { params(pull_request: T.untyped).void }
|
343
435
|
def add_assignees_to_pull_request(pull_request)
|
344
|
-
github_client_for_source.add_assignees(
|
436
|
+
T.unsafe(github_client_for_source).add_assignees(
|
345
437
|
source.repo,
|
346
438
|
pull_request.number,
|
347
439
|
assignees
|
@@ -351,8 +443,9 @@ module Dependabot
|
|
351
443
|
nil
|
352
444
|
end
|
353
445
|
|
446
|
+
sig { params(pull_request: T.untyped).void }
|
354
447
|
def add_milestone_to_pull_request(pull_request)
|
355
|
-
github_client_for_source.update_issue(
|
448
|
+
T.unsafe(github_client_for_source).update_issue(
|
356
449
|
source.repo,
|
357
450
|
pull_request.number,
|
358
451
|
milestone: milestone
|
@@ -361,8 +454,9 @@ module Dependabot
|
|
361
454
|
raise unless e.message.include?("code: invalid")
|
362
455
|
end
|
363
456
|
|
457
|
+
sig { returns(T.untyped) }
|
364
458
|
def create_pull_request
|
365
|
-
github_client_for_source.create_pull_request(
|
459
|
+
T.unsafe(github_client_for_source).create_pull_request(
|
366
460
|
source.repo,
|
367
461
|
target_branch,
|
368
462
|
branch_name,
|
@@ -381,47 +475,65 @@ module Dependabot
|
|
381
475
|
retry
|
382
476
|
end
|
383
477
|
|
478
|
+
sig { returns(String) }
|
384
479
|
def target_branch
|
385
480
|
source.branch || default_branch
|
386
481
|
end
|
387
482
|
|
483
|
+
sig { returns(String) }
|
388
484
|
def default_branch
|
389
485
|
@default_branch ||=
|
390
|
-
|
486
|
+
T.let(
|
487
|
+
T.unsafe(github_client_for_source).repo(source.repo).default_branch,
|
488
|
+
T.nilable(String)
|
489
|
+
)
|
391
490
|
end
|
392
491
|
|
492
|
+
sig { returns(Dependabot::GitMetadataFetcher) }
|
393
493
|
def git_metadata_fetcher
|
394
494
|
@git_metadata_fetcher ||=
|
395
|
-
|
396
|
-
|
397
|
-
|
495
|
+
T.let(
|
496
|
+
GitMetadataFetcher.new(
|
497
|
+
url: source.url,
|
498
|
+
credentials: credentials
|
499
|
+
),
|
500
|
+
T.nilable(Dependabot::GitMetadataFetcher)
|
398
501
|
)
|
399
502
|
end
|
400
503
|
|
504
|
+
sig do
|
505
|
+
params(tree: T.untyped, author_details_with_date: T::Hash[Symbol, String]).returns(String)
|
506
|
+
end
|
401
507
|
def commit_signature(tree, author_details_with_date)
|
402
508
|
CommitSigner.new(
|
403
509
|
author_details: author_details_with_date,
|
404
510
|
commit_message: commit_message,
|
405
511
|
tree_sha: tree.sha,
|
406
512
|
parent_sha: base_commit,
|
407
|
-
signature_key: signature_key
|
513
|
+
signature_key: T.must(signature_key)
|
408
514
|
).signature
|
409
515
|
end
|
410
516
|
|
517
|
+
sig { params(counter: T.nilable(Integer), limit: Integer).void }
|
411
518
|
def raise_or_increment_retry_counter(counter:, limit:)
|
412
519
|
counter ||= 0
|
413
520
|
counter += 1
|
414
521
|
raise if counter > limit
|
415
522
|
end
|
416
523
|
|
524
|
+
sig { returns(Dependabot::Clients::GithubWithRetries) }
|
417
525
|
def github_client_for_source
|
418
526
|
@github_client_for_source ||=
|
419
|
-
|
420
|
-
|
421
|
-
|
527
|
+
T.let(
|
528
|
+
Dependabot::Clients::GithubWithRetries.for_source(
|
529
|
+
source: source,
|
530
|
+
credentials: credentials
|
531
|
+
),
|
532
|
+
T.nilable(Dependabot::Clients::GithubWithRetries)
|
422
533
|
)
|
423
534
|
end
|
424
535
|
|
536
|
+
sig { params(err: StandardError).returns(T.noreturn) }
|
425
537
|
def handle_error(err)
|
426
538
|
cause = case err
|
427
539
|
when AnnotationError
|
@@ -452,6 +564,7 @@ module Dependabot
|
|
452
564
|
end
|
453
565
|
end
|
454
566
|
|
567
|
+
sig { params(base_err: StandardError, type: T.class_of(StandardError), message: String).returns(T.noreturn) }
|
455
568
|
def raise_custom_error(base_err, type, message)
|
456
569
|
case base_err
|
457
570
|
when AnnotationError
|
@@ -1,18 +1,78 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require "gitlab"
|
5
|
+
require "sorbet-runtime"
|
6
|
+
|
4
7
|
require "dependabot/clients/gitlab_with_retries"
|
5
8
|
require "dependabot/pull_request_creator"
|
6
|
-
require "gitlab"
|
7
9
|
|
8
10
|
module Dependabot
|
9
11
|
class PullRequestCreator
|
10
12
|
class Gitlab
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
13
|
+
extend T::Sig
|
14
|
+
|
15
|
+
sig { returns(Dependabot::Source) }
|
16
|
+
attr_reader :source
|
17
|
+
|
18
|
+
sig { returns(String) }
|
19
|
+
attr_reader :branch_name
|
20
|
+
|
21
|
+
sig { returns(String) }
|
22
|
+
attr_reader :base_commit
|
23
|
+
|
24
|
+
sig { returns(T::Array[Dependabot::Credential]) }
|
25
|
+
attr_reader :credentials
|
26
|
+
|
27
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
28
|
+
attr_reader :files
|
29
|
+
|
30
|
+
sig { returns(String) }
|
31
|
+
attr_reader :pr_description
|
32
|
+
|
33
|
+
sig { returns(String) }
|
34
|
+
attr_reader :pr_name
|
35
|
+
|
36
|
+
sig { returns(String) }
|
37
|
+
attr_reader :commit_message
|
38
|
+
|
39
|
+
sig { returns(T.nilable(T::Hash[Symbol, String])) }
|
40
|
+
attr_reader :author_details
|
15
41
|
|
42
|
+
sig { returns(Dependabot::PullRequestCreator::Labeler) }
|
43
|
+
attr_reader :labeler
|
44
|
+
|
45
|
+
sig { returns(T.nilable(T::Hash[Symbol, T::Array[Integer]])) }
|
46
|
+
attr_reader :approvers
|
47
|
+
|
48
|
+
sig { returns(T.nilable(T::Array[Integer])) }
|
49
|
+
attr_reader :assignees
|
50
|
+
|
51
|
+
sig { returns(T.nilable(T.any(T::Array[String], Integer))) }
|
52
|
+
attr_reader :milestone
|
53
|
+
|
54
|
+
sig { returns(T.nilable(Integer)) }
|
55
|
+
attr_reader :target_project_id
|
56
|
+
|
57
|
+
sig do
|
58
|
+
params(
|
59
|
+
source: Dependabot::Source,
|
60
|
+
branch_name: String,
|
61
|
+
base_commit: String,
|
62
|
+
credentials: T::Array[Dependabot::Credential],
|
63
|
+
files: T::Array[Dependabot::DependencyFile],
|
64
|
+
commit_message: String,
|
65
|
+
pr_description: String,
|
66
|
+
pr_name: String,
|
67
|
+
author_details: T.nilable(T::Hash[Symbol, String]),
|
68
|
+
labeler: Dependabot::PullRequestCreator::Labeler,
|
69
|
+
approvers: T.nilable(T::Hash[Symbol, T::Array[Integer]]),
|
70
|
+
assignees: T.nilable(T::Array[Integer]),
|
71
|
+
milestone: T.nilable(T.any(T::Array[String], Integer)),
|
72
|
+
target_project_id: T.nilable(Integer)
|
73
|
+
)
|
74
|
+
.void
|
75
|
+
end
|
16
76
|
def initialize(source:, branch_name:, base_commit:, credentials:,
|
17
77
|
files:, commit_message:, pr_description:, pr_name:,
|
18
78
|
author_details:, labeler:, approvers:, assignees:,
|
@@ -33,6 +93,7 @@ module Dependabot
|
|
33
93
|
@target_project_id = target_project_id
|
34
94
|
end
|
35
95
|
|
96
|
+
sig { returns(T.nilable(::Gitlab::ObjectifiedHash)) }
|
36
97
|
def create
|
37
98
|
return if branch_exists? && merge_request_exists?
|
38
99
|
|
@@ -54,30 +115,43 @@ module Dependabot
|
|
54
115
|
|
55
116
|
private
|
56
117
|
|
118
|
+
sig { returns(Dependabot::Clients::GitlabWithRetries) }
|
57
119
|
def gitlab_client_for_source
|
58
120
|
@gitlab_client_for_source ||=
|
59
|
-
|
60
|
-
|
61
|
-
|
121
|
+
T.let(
|
122
|
+
Dependabot::Clients::GitlabWithRetries.for_source(
|
123
|
+
source: source,
|
124
|
+
credentials: credentials
|
125
|
+
),
|
126
|
+
T.nilable(Dependabot::Clients::GitlabWithRetries)
|
62
127
|
)
|
63
128
|
end
|
64
129
|
|
130
|
+
sig { returns(T::Boolean) }
|
65
131
|
def branch_exists?
|
66
132
|
@branch_ref ||=
|
67
|
-
|
133
|
+
T.let(
|
134
|
+
T.unsafe(gitlab_client_for_source).branch(source.repo, branch_name),
|
135
|
+
T.nilable(::Gitlab::ObjectifiedHash)
|
136
|
+
)
|
68
137
|
true
|
69
138
|
rescue ::Gitlab::Error::NotFound
|
70
139
|
false
|
71
140
|
end
|
72
141
|
|
142
|
+
sig { returns(T::Boolean) }
|
73
143
|
def commit_exists?
|
74
144
|
@commits ||=
|
75
|
-
|
145
|
+
T.let(
|
146
|
+
T.unsafe(gitlab_client_for_source).commits(source.repo, ref_name: branch_name),
|
147
|
+
T.nilable(::Gitlab::PaginatedResponse)
|
148
|
+
)
|
76
149
|
@commits.first.message == commit_message
|
77
150
|
end
|
78
151
|
|
152
|
+
sig { returns(T::Boolean) }
|
79
153
|
def merge_request_exists?
|
80
|
-
gitlab_client_for_source.merge_requests(
|
154
|
+
T.unsafe(gitlab_client_for_source).merge_requests(
|
81
155
|
target_project_id || source.repo,
|
82
156
|
source_branch: branch_name,
|
83
157
|
target_branch: source.branch || default_branch,
|
@@ -85,16 +159,18 @@ module Dependabot
|
|
85
159
|
).any?
|
86
160
|
end
|
87
161
|
|
162
|
+
sig { returns(::Gitlab::ObjectifiedHash) }
|
88
163
|
def create_branch
|
89
|
-
gitlab_client_for_source.create_branch(
|
164
|
+
T.unsafe(gitlab_client_for_source).create_branch(
|
90
165
|
source.repo,
|
91
166
|
branch_name,
|
92
167
|
base_commit
|
93
168
|
)
|
94
169
|
end
|
95
170
|
|
171
|
+
sig { returns(::Gitlab::ObjectifiedHash) }
|
96
172
|
def create_commit
|
97
|
-
return create_submodule_update_commit if files.count == 1 && files.first.type == "submodule"
|
173
|
+
return create_submodule_update_commit if files.count == 1 && T.must(files.first).type == "submodule"
|
98
174
|
|
99
175
|
gitlab_client_for_source.create_commit(
|
100
176
|
source.repo,
|
@@ -104,10 +180,11 @@ module Dependabot
|
|
104
180
|
)
|
105
181
|
end
|
106
182
|
|
183
|
+
sig { returns(::Gitlab::ObjectifiedHash) }
|
107
184
|
def create_submodule_update_commit
|
108
|
-
file = files.first
|
185
|
+
file = T.must(files.first)
|
109
186
|
|
110
|
-
gitlab_client_for_source.edit_submodule(
|
187
|
+
T.unsafe(gitlab_client_for_source).edit_submodule(
|
111
188
|
source.repo,
|
112
189
|
file.path.gsub(%r{^/}, ""),
|
113
190
|
branch: branch_name,
|
@@ -116,8 +193,9 @@ module Dependabot
|
|
116
193
|
)
|
117
194
|
end
|
118
195
|
|
196
|
+
sig { returns(T.nilable(::Gitlab::ObjectifiedHash)) }
|
119
197
|
def create_merge_request
|
120
|
-
gitlab_client_for_source.create_merge_request(
|
198
|
+
T.unsafe(gitlab_client_for_source).create_merge_request(
|
121
199
|
source.repo,
|
122
200
|
pr_name,
|
123
201
|
source_branch: branch_name,
|
@@ -132,16 +210,18 @@ module Dependabot
|
|
132
210
|
)
|
133
211
|
end
|
134
212
|
|
213
|
+
sig { params(merge_request: ::Gitlab::ObjectifiedHash).returns(T.nilable(::Gitlab::ObjectifiedHash)) }
|
135
214
|
def annotate_merge_request(merge_request)
|
136
215
|
add_approvers_to_merge_request(merge_request)
|
137
216
|
end
|
138
217
|
|
218
|
+
sig { params(merge_request: ::Gitlab::ObjectifiedHash).returns(T.nilable(::Gitlab::ObjectifiedHash)) }
|
139
219
|
def add_approvers_to_merge_request(merge_request)
|
140
220
|
return unless approvers_hash[:approvers] || approvers_hash[:group_approvers]
|
141
221
|
|
142
|
-
gitlab_client_for_source.create_merge_request_level_rule(
|
222
|
+
T.unsafe(gitlab_client_for_source).create_merge_request_level_rule(
|
143
223
|
target_project_id || source.repo,
|
144
|
-
merge_request.iid,
|
224
|
+
T.unsafe(merge_request).iid,
|
145
225
|
name: "dependency-updates",
|
146
226
|
approvals_required: 1,
|
147
227
|
user_ids: approvers_hash[:approvers],
|
@@ -149,13 +229,21 @@ module Dependabot
|
|
149
229
|
)
|
150
230
|
end
|
151
231
|
|
232
|
+
sig { returns(T::Hash[Symbol, T::Array[Integer]]) }
|
152
233
|
def approvers_hash
|
153
|
-
@approvers_hash ||=
|
234
|
+
@approvers_hash ||= T.let(
|
235
|
+
approvers || {},
|
236
|
+
T.nilable(T::Hash[Symbol, T::Array[Integer]])
|
237
|
+
)
|
154
238
|
end
|
155
239
|
|
240
|
+
sig { returns(String) }
|
156
241
|
def default_branch
|
157
242
|
@default_branch ||=
|
158
|
-
|
243
|
+
T.let(
|
244
|
+
T.unsafe(gitlab_client_for_source).project(source.repo).default_branch,
|
245
|
+
T.nilable(String)
|
246
|
+
)
|
159
247
|
end
|
160
248
|
end
|
161
249
|
end
|