diff --git a/common/lib/dependabot/pull_request_creator.rb b/common/lib/dependabot/pull_request_creator.rb index 94b6c27c057f..7eb279e7816b 100644 --- a/common/lib/dependabot/pull_request_creator.rb +++ b/common/lib/dependabot/pull_request_creator.rb @@ -326,12 +326,12 @@ def bitbucket_creator base_commit: base_commit, credentials: credentials, files: files, - commit_message: message.commit_message, - pr_description: message.pr_message, - pr_name: message.pr_name, + commit_message: T.must(message.commit_message), + pr_description: T.must(message.pr_message), + pr_name: T.must(message.pr_name), author_details: author_details, labeler: nil, - work_item: provider_metadata&.fetch(:work_item, nil) + work_item: T.cast(provider_metadata&.fetch(:work_item, nil), T.nilable(String)) ) end diff --git a/common/lib/dependabot/pull_request_creator/bitbucket.rb b/common/lib/dependabot/pull_request_creator/bitbucket.rb index b69819f81384..14888047eb1b 100644 --- a/common/lib/dependabot/pull_request_creator/bitbucket.rb +++ b/common/lib/dependabot/pull_request_creator/bitbucket.rb @@ -1,19 +1,70 @@ -# typed: true +# typed: strict # frozen_string_literal: true +require "sorbet-runtime" + require "dependabot/clients/bitbucket" +require "dependabot/credential" +require "dependabot/dependency_file" require "dependabot/pull_request_creator" module Dependabot class PullRequestCreator class Bitbucket - attr_reader :source, :branch_name, :base_commit, :credentials, - :files, :commit_message, :pr_description, :pr_name, - :author_details, :labeler, :work_item + extend T::Sig + + sig { returns(Dependabot::Source) } + attr_reader :source + + sig { returns(String) } + attr_reader :branch_name + + sig { returns(String) } + attr_reader :base_commit + + sig { returns(T::Array[Dependabot::Credential]) } + attr_reader :credentials + + sig { returns(T::Array[Dependabot::DependencyFile]) } + attr_reader :files + + sig { returns(String) } + attr_reader :commit_message + + sig { returns(String) } + attr_reader :pr_description + + sig { returns(String) } + attr_reader :pr_name + + sig { returns(T.nilable(T::Hash[Symbol, String])) } + attr_reader :author_details + + sig { returns(T.nilable(String)) } + attr_reader :labeler + + sig { returns(T.nilable(String)) } + attr_reader :work_item # BitBucket Cloud accepts > 1MB characters, but they display poorly in the UI, so limiting to 4x 65,536 PR_DESCRIPTION_MAX_LENGTH = 262_143 # 0 based count + sig do + params( + source: Dependabot::Source, + branch_name: String, + base_commit: String, + credentials: T::Array[Dependabot::Credential], + files: T::Array[Dependabot::DependencyFile], + commit_message: String, + pr_description: String, + pr_name: String, + author_details: T.nilable(T::Hash[Symbol, String]), + labeler: T.nilable(String), + work_item: T.nilable(String) + ) + .void + end def initialize(source:, branch_name:, base_commit:, credentials:, files:, commit_message:, pr_description:, pr_name:, author_details:, labeler: nil, work_item: nil) @@ -30,6 +81,7 @@ def initialize(source:, branch_name:, base_commit:, credentials:, @work_item = work_item end + sig { void } def create return if branch_exists? && pull_request_exists? @@ -43,20 +95,26 @@ def create private + sig { returns(Dependabot::Clients::Bitbucket) } def bitbucket_client_for_source @bitbucket_client_for_source ||= - Dependabot::Clients::Bitbucket.for_source( - source: source, - credentials: credentials + T.let( + Dependabot::Clients::Bitbucket.for_source( + source: source, + credentials: credentials + ), + T.nilable(Dependabot::Clients::Bitbucket) ) end + sig { returns(T::Boolean) } def branch_exists? - bitbucket_client_for_source.branch(source.repo, branch_name) + !bitbucket_client_for_source.branch(source.repo, branch_name).nil? rescue Clients::Bitbucket::NotFound false end + sig { returns(T::Boolean) } def pull_request_exists? bitbucket_client_for_source.pull_requests( source.repo, @@ -65,6 +123,7 @@ def pull_request_exists? ).any? end + sig { void } def create_commit author = author_details&.slice(:name, :email) author = nil unless author&.any? @@ -79,6 +138,7 @@ def create_commit ) end + sig { void } def create_pull_request bitbucket_client_for_source.create_pull_request( source.repo, @@ -91,9 +151,13 @@ def create_pull_request ) end + sig { returns(String) } def default_branch @default_branch ||= - bitbucket_client_for_source.fetch_default_branch(source.repo) + T.let( + bitbucket_client_for_source.fetch_default_branch(source.repo), + T.nilable(String) + ) end end end diff --git a/common/spec/dependabot/pull_request_creator/bitbucket_test.rb b/common/spec/dependabot/pull_request_creator/bitbucket_test.rb new file mode 100644 index 000000000000..e7618fb119e5 --- /dev/null +++ b/common/spec/dependabot/pull_request_creator/bitbucket_test.rb @@ -0,0 +1,46 @@ +# typed: strict +# frozen_string_literal: true + +require "minitest/autorun" + +require "dependabot/pull_request_creator/bitbucket" + +class TestBitbucket < Minitest::Test + def setup + @source = Dependabot::Source.new(provider: "bitbucket", repo: "org/gocardless/_git/bump") + @branch_name = "dependabot/bundler/business-1.5.0" + @base_commit = "basecommitsha" + @credentials = [ + Dependabot::Credential.new({ + "type" => "git_source", + "host" => "bitbucket.org", + "username" => "x-access-token", + "password" => "token" + }) + ] + @commit_message = "Commit msg" + @pr_description = "PR msg" + @pr_name = "PR name" + @author_details = nil + @labeler = nil + @work_item = nil + + @creator = Dependabot::PullRequestCreator::Bitbucket.new( + source: @source, + branch_name: @branch_name, + base_commit: @base_commit, + credentials: @credentials, + files: [], + commit_message: @commit_message, + pr_description: @pr_description, + pr_name: @pr_name, + author_details: @author_details, + labeler: @labeler, + work_item: @work_item + ) + end + + def test_source + assert_equal @source, @creator.source + end +end