dependabot-core 0.94.13 → 0.95.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
- metadata +13 -337
- data/CHANGELOG.md +0 -7079
- data/LICENSE +0 -39
- data/README.md +0 -114
- data/helpers/test/run.rb +0 -18
- data/helpers/utils/git-credential-store-immutable +0 -10
- data/lib/dependabot/clients/bitbucket.rb +0 -105
- data/lib/dependabot/clients/github_with_retries.rb +0 -121
- data/lib/dependabot/clients/gitlab.rb +0 -72
- data/lib/dependabot/dependency.rb +0 -115
- data/lib/dependabot/dependency_file.rb +0 -60
- data/lib/dependabot/errors.rb +0 -179
- data/lib/dependabot/file_fetchers/README.md +0 -65
- data/lib/dependabot/file_fetchers/base.rb +0 -368
- data/lib/dependabot/file_fetchers.rb +0 -18
- data/lib/dependabot/file_parsers/README.md +0 -45
- data/lib/dependabot/file_parsers/base/dependency_set.rb +0 -77
- data/lib/dependabot/file_parsers/base.rb +0 -31
- data/lib/dependabot/file_parsers.rb +0 -18
- data/lib/dependabot/file_updaters/README.md +0 -58
- data/lib/dependabot/file_updaters/base.rb +0 -52
- data/lib/dependabot/file_updaters.rb +0 -18
- data/lib/dependabot/git_commit_checker.rb +0 -412
- data/lib/dependabot/metadata_finders/README.md +0 -53
- data/lib/dependabot/metadata_finders/base/changelog_finder.rb +0 -321
- data/lib/dependabot/metadata_finders/base/changelog_pruner.rb +0 -177
- data/lib/dependabot/metadata_finders/base/commits_finder.rb +0 -221
- data/lib/dependabot/metadata_finders/base/release_finder.rb +0 -255
- data/lib/dependabot/metadata_finders/base.rb +0 -117
- data/lib/dependabot/metadata_finders.rb +0 -18
- data/lib/dependabot/pull_request_creator/branch_namer.rb +0 -170
- data/lib/dependabot/pull_request_creator/commit_signer.rb +0 -63
- data/lib/dependabot/pull_request_creator/github.rb +0 -277
- data/lib/dependabot/pull_request_creator/gitlab.rb +0 -136
- data/lib/dependabot/pull_request_creator/labeler.rb +0 -373
- data/lib/dependabot/pull_request_creator/message_builder.rb +0 -906
- data/lib/dependabot/pull_request_creator.rb +0 -153
- data/lib/dependabot/pull_request_updater/github.rb +0 -165
- data/lib/dependabot/pull_request_updater.rb +0 -43
- data/lib/dependabot/shared_helpers.rb +0 -224
- data/lib/dependabot/source.rb +0 -120
- data/lib/dependabot/update_checkers/README.md +0 -67
- data/lib/dependabot/update_checkers/base.rb +0 -220
- data/lib/dependabot/update_checkers.rb +0 -18
- data/lib/dependabot/utils.rb +0 -33
- data/lib/dependabot/version.rb +0 -5
- data/lib/dependabot.rb +0 -4
- data/lib/rubygems_version_patch.rb +0 -14
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "dependabot/metadata_finders"
|
|
4
|
-
require "dependabot/pull_request_creator"
|
|
5
|
-
|
|
6
|
-
module Dependabot
|
|
7
|
-
class PullRequestCreator
|
|
8
|
-
class BranchNamer
|
|
9
|
-
attr_reader :dependencies, :files, :target_branch, :separator
|
|
10
|
-
|
|
11
|
-
def initialize(dependencies:, files:, target_branch:, separator: "/")
|
|
12
|
-
@dependencies = dependencies
|
|
13
|
-
@files = files
|
|
14
|
-
@target_branch = target_branch
|
|
15
|
-
@separator = separator
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
# rubocop:disable Metrics/AbcSize
|
|
19
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
|
20
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
|
21
|
-
def new_branch_name
|
|
22
|
-
@name ||=
|
|
23
|
-
if dependencies.count > 1 && updating_a_property?
|
|
24
|
-
property_name
|
|
25
|
-
elsif dependencies.count > 1 && updating_a_dependency_set?
|
|
26
|
-
dependency_set.fetch(:group)
|
|
27
|
-
elsif dependencies.count > 1
|
|
28
|
-
dependencies.map(&:name).join("-and-").tr(":", "-")
|
|
29
|
-
elsif library? && ref_changed?(dependencies.first)
|
|
30
|
-
dep = dependencies.first
|
|
31
|
-
"#{dep.name.tr(':', '-')}-#{new_ref(dep)}"
|
|
32
|
-
elsif library?
|
|
33
|
-
dep = dependencies.first
|
|
34
|
-
"#{dep.name.tr(':', '-')}-#{sanitized_requirement(dep)}"
|
|
35
|
-
else
|
|
36
|
-
dep = dependencies.first
|
|
37
|
-
"#{dep.name.tr(':', '-')}-#{new_version(dep)}"
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
branch_name = File.join(prefixes, @name).gsub(%r{/\.}, "/dot-")
|
|
41
|
-
|
|
42
|
-
# Some users need branch names without slashes
|
|
43
|
-
branch_name.gsub("/", separator)
|
|
44
|
-
end
|
|
45
|
-
# rubocop:enable Metrics/AbcSize
|
|
46
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
|
47
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
|
48
|
-
|
|
49
|
-
private
|
|
50
|
-
|
|
51
|
-
def prefixes
|
|
52
|
-
[
|
|
53
|
-
"dependabot",
|
|
54
|
-
package_manager,
|
|
55
|
-
files.first.directory.tr(" ", "-"),
|
|
56
|
-
target_branch
|
|
57
|
-
].compact
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def package_manager
|
|
61
|
-
dependencies.first.package_manager
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def updating_a_property?
|
|
65
|
-
dependencies.first.
|
|
66
|
-
requirements.
|
|
67
|
-
any? { |r| r.dig(:metadata, :property_name) }
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def updating_a_dependency_set?
|
|
71
|
-
dependencies.first.
|
|
72
|
-
requirements.
|
|
73
|
-
any? { |r| r.dig(:metadata, :dependency_set) }
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def property_name
|
|
77
|
-
@property_name ||= dependencies.first.requirements.
|
|
78
|
-
find { |r| r.dig(:metadata, :property_name) }&.
|
|
79
|
-
dig(:metadata, :property_name)
|
|
80
|
-
|
|
81
|
-
raise "No property name!" unless @property_name
|
|
82
|
-
|
|
83
|
-
@property_name
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
def dependency_set
|
|
87
|
-
@dependency_set ||= dependencies.first.requirements.
|
|
88
|
-
find { |r| r.dig(:metadata, :dependency_set) }&.
|
|
89
|
-
dig(:metadata, :dependency_set)
|
|
90
|
-
|
|
91
|
-
raise "No dependency set!" unless @dependency_set
|
|
92
|
-
|
|
93
|
-
@dependency_set
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
def sanitized_requirement(dependency)
|
|
97
|
-
new_library_requirement(dependency).
|
|
98
|
-
delete(" ").
|
|
99
|
-
gsub("!=", "neq-").
|
|
100
|
-
gsub(">=", "gte-").
|
|
101
|
-
gsub("<=", "lte-").
|
|
102
|
-
gsub("~>", "tw-").
|
|
103
|
-
gsub("^", "tw-").
|
|
104
|
-
gsub("||", "or-").
|
|
105
|
-
gsub("~", "approx-").
|
|
106
|
-
gsub("~=", "tw-").
|
|
107
|
-
gsub(/==*/, "eq-").
|
|
108
|
-
gsub(">", "gt-").
|
|
109
|
-
gsub("<", "lt-").
|
|
110
|
-
gsub("*", "star").
|
|
111
|
-
gsub(",", "-and-")
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
def new_version(dependency)
|
|
115
|
-
if dependency.version.match?(/^[0-9a-f]{40}$/)
|
|
116
|
-
return new_ref(dependency) if ref_changed?(dependency)
|
|
117
|
-
|
|
118
|
-
dependency.version[0..6]
|
|
119
|
-
elsif dependency.version == dependency.previous_version &&
|
|
120
|
-
package_manager == "docker"
|
|
121
|
-
dependency.requirements.
|
|
122
|
-
map { |r| r.dig(:source, "digest") || r.dig(:source, :digest) }.
|
|
123
|
-
compact.first.split(":").last[0..6]
|
|
124
|
-
else
|
|
125
|
-
dependency.version
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
def previous_ref(dependency)
|
|
130
|
-
dependency.previous_requirements.map do |r|
|
|
131
|
-
r.dig(:source, "ref") || r.dig(:source, :ref)
|
|
132
|
-
end.compact.first
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
def new_ref(dependency)
|
|
136
|
-
dependency.requirements.map do |r|
|
|
137
|
-
r.dig(:source, "ref") || r.dig(:source, :ref)
|
|
138
|
-
end.compact.first
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
def ref_changed?(dependency)
|
|
142
|
-
previous_ref(dependency) && new_ref(dependency) &&
|
|
143
|
-
previous_ref(dependency) != new_ref(dependency)
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
def new_library_requirement(dependency)
|
|
147
|
-
updated_reqs =
|
|
148
|
-
dependency.requirements - dependency.previous_requirements
|
|
149
|
-
|
|
150
|
-
gemspec =
|
|
151
|
-
updated_reqs.find { |r| r[:file].match?(%r{^[^/]*\.gemspec$}) }
|
|
152
|
-
return gemspec[:requirement] if gemspec
|
|
153
|
-
|
|
154
|
-
updated_reqs.first[:requirement]
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
def library?
|
|
158
|
-
if files.map(&:name).any? { |name| name.end_with?(".gemspec") }
|
|
159
|
-
return true
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
dependencies.none?(&:appears_in_lockfile?)
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
def requirements_changed?(dependency)
|
|
166
|
-
(dependency.requirements - dependency.previous_requirements).any?
|
|
167
|
-
end
|
|
168
|
-
end
|
|
169
|
-
end
|
|
170
|
-
end
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "time"
|
|
4
|
-
require "gpgme"
|
|
5
|
-
require "tmpdir"
|
|
6
|
-
require "dependabot/pull_request_creator"
|
|
7
|
-
|
|
8
|
-
module Dependabot
|
|
9
|
-
class PullRequestCreator
|
|
10
|
-
class CommitSigner
|
|
11
|
-
attr_reader :author_details, :commit_message, :tree_sha, :parent_sha,
|
|
12
|
-
:signature_key
|
|
13
|
-
|
|
14
|
-
def initialize(author_details:, commit_message:, tree_sha:, parent_sha:,
|
|
15
|
-
signature_key:)
|
|
16
|
-
@author_details = author_details
|
|
17
|
-
@commit_message = commit_message
|
|
18
|
-
@tree_sha = tree_sha
|
|
19
|
-
@parent_sha = parent_sha
|
|
20
|
-
@signature_key = signature_key
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def signature
|
|
24
|
-
email = author_details[:email]
|
|
25
|
-
|
|
26
|
-
dir = Dir.mktmpdir
|
|
27
|
-
|
|
28
|
-
GPGME::Engine.home_dir = dir
|
|
29
|
-
GPGME::Key.import(signature_key)
|
|
30
|
-
|
|
31
|
-
crypto = GPGME::Crypto.new(armor: true)
|
|
32
|
-
opts = { mode: GPGME::SIG_MODE_DETACH, signer: email }
|
|
33
|
-
crypto.sign(commit_object, opts).to_s
|
|
34
|
-
rescue Errno::ENOTEMPTY
|
|
35
|
-
FileUtils.remove_entry(dir, true)
|
|
36
|
-
# This appears to be a Ruby bug which occurs very rarely
|
|
37
|
-
raise if @retrying
|
|
38
|
-
|
|
39
|
-
@retrying = true
|
|
40
|
-
retry
|
|
41
|
-
ensure
|
|
42
|
-
FileUtils.remove_entry(dir, true)
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
private
|
|
46
|
-
|
|
47
|
-
def commit_object
|
|
48
|
-
time_str = Time.parse(author_details[:date]).strftime("%s %z")
|
|
49
|
-
name = author_details[:name]
|
|
50
|
-
email = author_details[:email]
|
|
51
|
-
|
|
52
|
-
[
|
|
53
|
-
"tree #{tree_sha}",
|
|
54
|
-
"parent #{parent_sha}",
|
|
55
|
-
"author #{name} <#{email}> #{time_str}",
|
|
56
|
-
"committer #{name} <#{email}> #{time_str}",
|
|
57
|
-
"",
|
|
58
|
-
commit_message
|
|
59
|
-
].join("\n")
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
end
|
|
@@ -1,277 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "octokit"
|
|
4
|
-
require "securerandom"
|
|
5
|
-
require "dependabot/clients/github_with_retries"
|
|
6
|
-
require "dependabot/pull_request_creator"
|
|
7
|
-
require "dependabot/pull_request_creator/commit_signer"
|
|
8
|
-
|
|
9
|
-
module Dependabot
|
|
10
|
-
class PullRequestCreator
|
|
11
|
-
class Github
|
|
12
|
-
attr_reader :source, :branch_name, :base_commit, :credentials,
|
|
13
|
-
:files, :pr_description, :pr_name, :commit_message,
|
|
14
|
-
:author_details, :signature_key,
|
|
15
|
-
:labeler, :reviewers, :assignees, :milestone
|
|
16
|
-
|
|
17
|
-
def initialize(source:, branch_name:, base_commit:, credentials:,
|
|
18
|
-
files:, commit_message:, pr_description:, pr_name:,
|
|
19
|
-
author_details:, signature_key:,
|
|
20
|
-
labeler:, reviewers:, assignees:, milestone:)
|
|
21
|
-
@source = source
|
|
22
|
-
@branch_name = branch_name
|
|
23
|
-
@base_commit = base_commit
|
|
24
|
-
@credentials = credentials
|
|
25
|
-
@files = files
|
|
26
|
-
@commit_message = commit_message
|
|
27
|
-
@pr_description = pr_description
|
|
28
|
-
@pr_name = pr_name
|
|
29
|
-
@author_details = author_details
|
|
30
|
-
@signature_key = signature_key
|
|
31
|
-
@labeler = labeler
|
|
32
|
-
@reviewers = reviewers
|
|
33
|
-
@assignees = assignees
|
|
34
|
-
@milestone = milestone
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def create
|
|
38
|
-
return if branch_exists? && pull_request_exists?
|
|
39
|
-
|
|
40
|
-
commit = create_commit
|
|
41
|
-
branch = create_or_update_branch(commit)
|
|
42
|
-
return unless branch
|
|
43
|
-
|
|
44
|
-
pull_request = create_pull_request
|
|
45
|
-
return unless pull_request
|
|
46
|
-
|
|
47
|
-
annotate_pull_request(pull_request)
|
|
48
|
-
|
|
49
|
-
pull_request
|
|
50
|
-
rescue Octokit::Error => error
|
|
51
|
-
handle_error(error)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
private
|
|
55
|
-
|
|
56
|
-
def github_client_for_source
|
|
57
|
-
@github_client_for_source ||=
|
|
58
|
-
Dependabot::Clients::GithubWithRetries.for_source(
|
|
59
|
-
source: source,
|
|
60
|
-
credentials: credentials
|
|
61
|
-
)
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def branch_exists?
|
|
65
|
-
@branch_ref ||=
|
|
66
|
-
github_client_for_source.ref(source.repo, "heads/#{branch_name}")
|
|
67
|
-
if @branch_ref.is_a?(Array)
|
|
68
|
-
@branch_ref.any? { |r| r.ref == "refs/heads/#{branch_name}" }
|
|
69
|
-
else
|
|
70
|
-
@branch_ref.ref == "refs/heads/#{branch_name}"
|
|
71
|
-
end
|
|
72
|
-
rescue Octokit::NotFound
|
|
73
|
-
false
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def pull_request_exists?
|
|
77
|
-
github_client_for_source.pull_requests(
|
|
78
|
-
source.repo,
|
|
79
|
-
head: "#{source.repo.split('/').first}:#{branch_name}",
|
|
80
|
-
state: "all"
|
|
81
|
-
).any?
|
|
82
|
-
rescue Octokit::InternalServerError
|
|
83
|
-
# A GitHub bug sometimes means adding `state: all` causes problems.
|
|
84
|
-
# In that case, fall back to making two separate requests.
|
|
85
|
-
open_prs = github_client_for_source.pull_requests(
|
|
86
|
-
source.repo,
|
|
87
|
-
head: "#{source.repo.split('/').first}:#{branch_name}",
|
|
88
|
-
state: "open"
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
closed_prs = github_client_for_source.pull_requests(
|
|
92
|
-
source.repo,
|
|
93
|
-
head: "#{source.repo.split('/').first}:#{branch_name}",
|
|
94
|
-
state: "closed"
|
|
95
|
-
)
|
|
96
|
-
|
|
97
|
-
[*open_prs, *closed_prs].any?
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
def repo_exists?
|
|
101
|
-
github_client_for_source.repo(source.repo)
|
|
102
|
-
true
|
|
103
|
-
rescue Octokit::NotFound
|
|
104
|
-
false
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
def create_commit
|
|
108
|
-
tree = create_tree
|
|
109
|
-
|
|
110
|
-
options = author_details&.any? ? { author: author_details } : {}
|
|
111
|
-
|
|
112
|
-
if options[:author]&.any? && signature_key
|
|
113
|
-
options[:author][:date] = Time.now.utc.iso8601
|
|
114
|
-
options[:signature] = commit_signature(tree, options[:author])
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
github_client_for_source.create_commit(
|
|
118
|
-
source.repo,
|
|
119
|
-
commit_message,
|
|
120
|
-
tree.sha,
|
|
121
|
-
base_commit,
|
|
122
|
-
options
|
|
123
|
-
)
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
def create_tree
|
|
127
|
-
file_trees = files.map do |file|
|
|
128
|
-
if file.type == "submodule"
|
|
129
|
-
{
|
|
130
|
-
path: file.path.sub(%r{^/}, ""),
|
|
131
|
-
mode: "160000",
|
|
132
|
-
type: "commit",
|
|
133
|
-
sha: file.content
|
|
134
|
-
}
|
|
135
|
-
else
|
|
136
|
-
{
|
|
137
|
-
path: file.path.sub(%r{^/}, ""),
|
|
138
|
-
mode: "100644",
|
|
139
|
-
type: "blob",
|
|
140
|
-
content: file.content
|
|
141
|
-
}
|
|
142
|
-
end
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
github_client_for_source.create_tree(
|
|
146
|
-
source.repo,
|
|
147
|
-
file_trees,
|
|
148
|
-
base_tree: base_commit
|
|
149
|
-
)
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
def create_or_update_branch(commit)
|
|
153
|
-
branch_exists? ? update_branch(commit) : create_branch(commit)
|
|
154
|
-
rescue Octokit::UnprocessableEntity
|
|
155
|
-
# A race condition may cause GitHub to fail here, in which case we retry
|
|
156
|
-
retry_count ||= 0
|
|
157
|
-
retry_count += 1
|
|
158
|
-
retry unless retry_count >= 2
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
def create_branch(commit)
|
|
162
|
-
github_client_for_source.create_ref(
|
|
163
|
-
source.repo,
|
|
164
|
-
"heads/#{branch_name}",
|
|
165
|
-
commit.sha
|
|
166
|
-
)
|
|
167
|
-
rescue Octokit::UnprocessableEntity => error
|
|
168
|
-
# Return quietly in the case of a race
|
|
169
|
-
return nil if error.message.match?(/Reference already exists/i)
|
|
170
|
-
raise if @retrying_branch_creation
|
|
171
|
-
|
|
172
|
-
@retrying_branch_creation = true
|
|
173
|
-
|
|
174
|
-
# Branch creation will fail if a branch called `dependabot` already
|
|
175
|
-
# exists, since git won't be able to create a folder with the same name
|
|
176
|
-
@branch_name = SecureRandom.hex[0..3] + @branch_name
|
|
177
|
-
retry
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
def update_branch(commit)
|
|
181
|
-
github_client_for_source.update_ref(
|
|
182
|
-
source.repo,
|
|
183
|
-
"heads/#{branch_name}",
|
|
184
|
-
commit.sha,
|
|
185
|
-
true
|
|
186
|
-
)
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
def annotate_pull_request(pull_request)
|
|
190
|
-
labeler.label_pull_request(pull_request.number)
|
|
191
|
-
add_reviewers_to_pull_request(pull_request) if reviewers&.any?
|
|
192
|
-
add_assignees_to_pull_request(pull_request) if assignees&.any?
|
|
193
|
-
add_milestone_to_pull_request(pull_request) if milestone
|
|
194
|
-
end
|
|
195
|
-
|
|
196
|
-
def add_reviewers_to_pull_request(pull_request)
|
|
197
|
-
reviewers_hash =
|
|
198
|
-
Hash[reviewers.keys.map { |k| [k.to_sym, reviewers[k]] }]
|
|
199
|
-
|
|
200
|
-
github_client_for_source.request_pull_request_review(
|
|
201
|
-
source.repo,
|
|
202
|
-
pull_request.number,
|
|
203
|
-
reviewers: reviewers_hash[:reviewers] || [],
|
|
204
|
-
team_reviewers: reviewers_hash[:team_reviewers] || []
|
|
205
|
-
)
|
|
206
|
-
rescue Octokit::UnprocessableEntity => error
|
|
207
|
-
return if error.message.include?("not a collaborator")
|
|
208
|
-
return if error.message.include?("Could not resolve to a node")
|
|
209
|
-
|
|
210
|
-
raise
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
def add_assignees_to_pull_request(pull_request)
|
|
214
|
-
github_client_for_source.add_assignees(
|
|
215
|
-
source.repo,
|
|
216
|
-
pull_request.number,
|
|
217
|
-
assignees
|
|
218
|
-
)
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
def add_milestone_to_pull_request(pull_request)
|
|
222
|
-
github_client_for_source.update_issue(
|
|
223
|
-
source.repo,
|
|
224
|
-
pull_request.number,
|
|
225
|
-
milestone: milestone
|
|
226
|
-
)
|
|
227
|
-
end
|
|
228
|
-
|
|
229
|
-
def create_pull_request
|
|
230
|
-
github_client_for_source.create_pull_request(
|
|
231
|
-
source.repo,
|
|
232
|
-
source.branch || default_branch,
|
|
233
|
-
branch_name,
|
|
234
|
-
pr_name,
|
|
235
|
-
pr_description
|
|
236
|
-
)
|
|
237
|
-
rescue Octokit::UnprocessableEntity => error
|
|
238
|
-
# Ignore races that we lose
|
|
239
|
-
raise unless error.message.include?("pull request already exists")
|
|
240
|
-
end
|
|
241
|
-
|
|
242
|
-
def default_branch
|
|
243
|
-
@default_branch ||=
|
|
244
|
-
github_client_for_source.repository(source.repo).default_branch
|
|
245
|
-
end
|
|
246
|
-
|
|
247
|
-
def commit_signature(tree, author_details_with_date)
|
|
248
|
-
CommitSigner.new(
|
|
249
|
-
author_details: author_details_with_date,
|
|
250
|
-
commit_message: commit_message,
|
|
251
|
-
tree_sha: tree.sha,
|
|
252
|
-
parent_sha: base_commit,
|
|
253
|
-
signature_key: signature_key
|
|
254
|
-
).signature
|
|
255
|
-
end
|
|
256
|
-
|
|
257
|
-
def handle_error(error)
|
|
258
|
-
case error
|
|
259
|
-
when Octokit::Forbidden
|
|
260
|
-
raise error unless error.message.include?("Repository was archived")
|
|
261
|
-
|
|
262
|
-
raise RepoArchived, error.message
|
|
263
|
-
when Octokit::NotFound
|
|
264
|
-
raise error if repo_exists?
|
|
265
|
-
|
|
266
|
-
raise RepoNotFound, error.message
|
|
267
|
-
when Octokit::UnprocessableEntity
|
|
268
|
-
raise error unless error.message.include?("no history in common")
|
|
269
|
-
|
|
270
|
-
raise NoHistoryInCommon, error.message
|
|
271
|
-
else
|
|
272
|
-
raise error
|
|
273
|
-
end
|
|
274
|
-
end
|
|
275
|
-
end
|
|
276
|
-
end
|
|
277
|
-
end
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "dependabot/clients/gitlab"
|
|
4
|
-
require "dependabot/pull_request_creator"
|
|
5
|
-
require "gitlab"
|
|
6
|
-
|
|
7
|
-
module Dependabot
|
|
8
|
-
class PullRequestCreator
|
|
9
|
-
class Gitlab
|
|
10
|
-
attr_reader :source, :branch_name, :base_commit, :credentials,
|
|
11
|
-
:files, :pr_description, :pr_name, :commit_message,
|
|
12
|
-
:author_details, :labeler, :assignee
|
|
13
|
-
|
|
14
|
-
def initialize(source:, branch_name:, base_commit:, credentials:,
|
|
15
|
-
files:, commit_message:, pr_description:, pr_name:,
|
|
16
|
-
author_details:, labeler:, assignee:)
|
|
17
|
-
@source = source
|
|
18
|
-
@branch_name = branch_name
|
|
19
|
-
@base_commit = base_commit
|
|
20
|
-
@credentials = credentials
|
|
21
|
-
@files = files
|
|
22
|
-
@commit_message = commit_message
|
|
23
|
-
@pr_description = pr_description
|
|
24
|
-
@pr_name = pr_name
|
|
25
|
-
@author_details = author_details
|
|
26
|
-
@labeler = labeler
|
|
27
|
-
@assignee = assignee
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def create
|
|
31
|
-
return if branch_exists? && merge_request_exists?
|
|
32
|
-
|
|
33
|
-
if branch_exists?
|
|
34
|
-
create_commit unless commit_exists?
|
|
35
|
-
else
|
|
36
|
-
create_branch
|
|
37
|
-
create_commit
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
labeler.create_default_labels_if_required
|
|
41
|
-
create_merge_request
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
private
|
|
45
|
-
|
|
46
|
-
def gitlab_client_for_source
|
|
47
|
-
@gitlab_client_for_source ||= Dependabot::Clients::Gitlab.for_source(
|
|
48
|
-
source: source,
|
|
49
|
-
credentials: credentials
|
|
50
|
-
)
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def branch_exists?
|
|
54
|
-
@branch_ref ||=
|
|
55
|
-
gitlab_client_for_source.branch(source.repo, branch_name)
|
|
56
|
-
true
|
|
57
|
-
rescue ::Gitlab::Error::NotFound
|
|
58
|
-
false
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def commit_exists?
|
|
62
|
-
@commits ||=
|
|
63
|
-
gitlab_client_for_source.commits(source.repo, ref_name: branch_name)
|
|
64
|
-
@commits.first.message == commit_message
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def merge_request_exists?
|
|
68
|
-
gitlab_client_for_source.merge_requests(
|
|
69
|
-
source.repo,
|
|
70
|
-
source_branch: branch_name,
|
|
71
|
-
target_branch: source.branch || default_branch,
|
|
72
|
-
state: "all"
|
|
73
|
-
).any?
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def create_branch
|
|
77
|
-
gitlab_client_for_source.create_branch(
|
|
78
|
-
source.repo,
|
|
79
|
-
branch_name,
|
|
80
|
-
base_commit
|
|
81
|
-
)
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def create_commit
|
|
85
|
-
if files.count == 1 && files.first.type == "submodule"
|
|
86
|
-
return create_submodule_update_commit
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
actions = files.map do |file|
|
|
90
|
-
{
|
|
91
|
-
action: "update",
|
|
92
|
-
file_path: file.path,
|
|
93
|
-
content: file.content
|
|
94
|
-
}
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
gitlab_client_for_source.create_commit(
|
|
98
|
-
source.repo,
|
|
99
|
-
branch_name,
|
|
100
|
-
commit_message,
|
|
101
|
-
actions
|
|
102
|
-
)
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
def create_submodule_update_commit
|
|
106
|
-
file = files.first
|
|
107
|
-
|
|
108
|
-
gitlab_client_for_source.edit_submodule(
|
|
109
|
-
source.repo,
|
|
110
|
-
file.path.gsub(%r{^/}, ""),
|
|
111
|
-
branch: branch_name,
|
|
112
|
-
commit_sha: file.content,
|
|
113
|
-
commit_message: commit_message
|
|
114
|
-
)
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
def create_merge_request
|
|
118
|
-
gitlab_client_for_source.create_merge_request(
|
|
119
|
-
source.repo,
|
|
120
|
-
pr_name,
|
|
121
|
-
source_branch: branch_name,
|
|
122
|
-
target_branch: source.branch || default_branch,
|
|
123
|
-
description: pr_description,
|
|
124
|
-
remove_source_branch: true,
|
|
125
|
-
assignee_id: assignee,
|
|
126
|
-
labels: labeler.labels_for_pr.join(",")
|
|
127
|
-
)
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
def default_branch
|
|
131
|
-
@default_branch ||=
|
|
132
|
-
gitlab_client_for_source.project(source.repo).default_branch
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
end
|