class Dependabot::PullRequestUpdater::Github
Attributes
base_commit[R]
credentials[R]
files[R]
old_commit[R]
pull_request_number[R]
signature_key[R]
source[R]
Public Class Methods
new(source:, base_commit:, old_commit:, files:, credentials:, pull_request_number:, author_details: nil, signature_key: nil)
click to toggle source
# File lib/dependabot/pull_request_updater/github.rb, line 14 def initialize(source:, base_commit:, old_commit:, files:, credentials:, pull_request_number:, author_details: nil, signature_key: nil) @source = source @base_commit = base_commit @old_commit = old_commit @files = files @credentials = credentials @pull_request_number = pull_request_number @author_details = author_details @signature_key = signature_key end
Public Instance Methods
update()
click to toggle source
# File lib/dependabot/pull_request_updater/github.rb, line 27 def update return unless pull_request_exists? return unless branch_exists?(pull_request.head.ref) commit = create_commit branch = update_branch(commit) update_pull_request_target_branch branch end
Private Instance Methods
branch_exists?(name)
click to toggle source
# File lib/dependabot/pull_request_updater/github.rb, line 87 def branch_exists?(name) github_client_for_source.branch(source.repo, name) rescue Octokit::NotFound false end
commit_being_updated()
click to toggle source
# File lib/dependabot/pull_request_updater/github.rb, line 189 def commit_being_updated @commit_being_updated ||= if pull_request.commits == 1 github_client_for_source. git_commit(source.repo, pull_request.head.sha) else author_name = author_details&.fetch(:name, nil) || "dependabot" commits = github_client_for_source. pull_request_commits(source.repo, pull_request_number). reverse commit = commits.find { |c| c.sha == old_commit } || commits.find { |c| c.commit.author.name.include?(author_name) } || commits.first commit.commit end end
commit_message()
click to toggle source
# File lib/dependabot/pull_request_updater/github.rb, line 184 def commit_message # Take the commit message from the old commit commit_being_updated.message end
commit_signature(tree, author_details_with_date)
click to toggle source
# File lib/dependabot/pull_request_updater/github.rb, line 210 def commit_signature(tree, author_details_with_date) PullRequestCreator::CommitSigner.new( author_details: author_details_with_date, commit_message: commit_message, tree_sha: tree.sha, parent_sha: base_commit, signature_key: signature_key ).signature end
create_commit()
click to toggle source
# File lib/dependabot/pull_request_updater/github.rb, line 93 def create_commit tree = create_tree options = author_details&.any? ? { author: author_details } : {} if options[:author]&.any? && signature_key options[:author][:date] = Time.now.utc.iso8601 options[:signature] = commit_signature(tree, options[:author]) end begin github_client_for_source.create_commit( source.repo, commit_message, tree.sha, base_commit, options ) rescue Octokit::UnprocessableEntity => e raise unless e.message == "Tree SHA does not exist" # Sometimes a race condition on GitHub's side means we get an error # here. No harm in retrying if we do. retry_count ||= 0 retry_count += 1 raise if retry_count > 10 sleep(rand(1..1.99)) retry end end
create_tree()
click to toggle source
# File lib/dependabot/pull_request_updater/github.rb, line 125 def create_tree file_trees = files.map do |file| if file.type == "submodule" { path: file.path.sub(%r{^/}, ""), mode: "160000", type: "commit", sha: file.content } else content = if file.operation == Dependabot::DependencyFile::Operation::DELETE { sha: nil } elsif file.binary? sha = github_client_for_source.create_blob( source.repo, file.content, "base64" ) { sha: sha } else { content: file.content } end { path: (file.symlink_target || file.path).sub(%r{^/}, ""), mode: "100644", type: "blob" }.merge(content) end end github_client_for_source.create_tree( source.repo, file_trees, base_tree: base_commit ) end
github_client_for_source()
click to toggle source
# File lib/dependabot/pull_request_updater/github.rb, line 64 def github_client_for_source @github_client_for_source ||= Dependabot::Clients::GithubWithRetries.for_source( source: source, credentials: credentials ) end
handle_pr_update_error(error)
click to toggle source
# File lib/dependabot/pull_request_updater/github.rb, line 52 def handle_pr_update_error(error) # Return quietly if the PR has been closed return if error.message.match?(/closed pull request/i) # Ignore cases where the target branch has been deleted return if error.message.include?("field: base") && source.branch && !branch_exists?(source.branch) raise error end
pull_request()
click to toggle source
# File lib/dependabot/pull_request_updater/github.rb, line 79 def pull_request @pull_request ||= github_client_for_source.pull_request( source.repo, pull_request_number ) end
pull_request_exists?()
click to toggle source
# File lib/dependabot/pull_request_updater/github.rb, line 72 def pull_request_exists? pull_request true rescue Octokit::NotFound false end
update_branch(commit)
click to toggle source
# File lib/dependabot/pull_request_updater/github.rb, line 162 def update_branch(commit) github_client_for_source.update_ref( source.repo, "heads/" + pull_request.head.ref, commit.sha, true ) rescue Octokit::UnprocessableEntity => e # Return quietly if the branch has been deleted or merged return nil if e.message.match?(/Reference does not exist/i) return nil if e.message.match?(/Reference cannot be updated/i) if e.message.match?(/protected branch/i) || e.message.match?(/not authorized to push/i) || e.message.match?(/must not contain merge commits/) || e.message.match?(/required status check/i) raise BranchProtected end raise end
update_pull_request_target_branch()
click to toggle source
# File lib/dependabot/pull_request_updater/github.rb, line 39 def update_pull_request_target_branch target_branch = source.branch || pull_request.base.repo.default_branch return if target_branch == pull_request.base.ref github_client_for_source.update_pull_request( source.repo, pull_request_number, base: target_branch ) rescue Octokit::UnprocessableEntity => e handle_pr_update_error(e) end