dependabot-common 0.244.0 → 0.246.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/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
|