@@ -65,6 +65,23 @@ const RawBitbucketRepositorySchema = Schema.Struct({
6565 ) ,
6666} ) ;
6767
68+ const RawBitbucketBranchingModelSchema = Schema . Struct ( {
69+ development : Schema . optional (
70+ Schema . Struct ( {
71+ branch : Schema . optional (
72+ Schema . NullOr (
73+ Schema . Struct ( {
74+ name : Schema . optional ( TrimmedNonEmptyString ) ,
75+ } ) ,
76+ ) ,
77+ ) ,
78+ is_valid : Schema . optional ( Schema . Boolean ) ,
79+ name : Schema . optional ( Schema . NullOr ( Schema . String ) ) ,
80+ use_mainbranch : Schema . optional ( Schema . Boolean ) ,
81+ } ) ,
82+ ) ,
83+ } ) ;
84+
6885const BitbucketUserSchema = Schema . Struct ( {
6986 username : Schema . optional ( TrimmedNonEmptyString ) ,
7087 display_name : Schema . optional ( TrimmedNonEmptyString ) ,
@@ -216,7 +233,7 @@ function parseBitbucketRemoteUrl(remoteUrl: string): BitbucketRepositoryLocator
216233}
217234
218235function normalizeRepositoryCloneUrls (
219- raw : Schema . Schema . Type < typeof RawBitbucketRepositorySchema > ,
236+ raw : typeof RawBitbucketRepositorySchema . Type ,
220237) : SourceControlRepositoryCloneUrls {
221238 const httpClone =
222239 raw . links . clone ?. find ( ( entry ) => entry . name . toLowerCase ( ) === "https" ) ?. href ??
@@ -230,6 +247,24 @@ function normalizeRepositoryCloneUrls(
230247 } ;
231248}
232249
250+ function defaultChangeRequestTargetBranch ( input : {
251+ readonly repository : typeof RawBitbucketRepositorySchema . Type ;
252+ readonly branchingModel : typeof RawBitbucketBranchingModelSchema . Type | null ;
253+ } ) : string | null {
254+ const repositoryMainBranch = input . repository . mainbranch ?. name ?? null ;
255+ const development = input . branchingModel ?. development ;
256+ if ( ! development || development . use_mainbranch === true || development . is_valid === false ) {
257+ return repositoryMainBranch ;
258+ }
259+
260+ const developmentBranch = development . branch ?. name ?. trim ( ) ?? development . name ?. trim ( ) ?? "" ;
261+ if ( developmentBranch . length === 0 || developmentBranch === "null" ) {
262+ return repositoryMainBranch ;
263+ }
264+
265+ return developmentBranch ;
266+ }
267+
233268function shouldPreferSshRemote ( originRemoteUrl : string | null ) : boolean {
234269 const trimmed = originRemoteUrl ?. trim ( ) ?? "" ;
235270 return trimmed . startsWith ( "git@" ) || trimmed . startsWith ( "ssh://" ) ;
@@ -430,23 +465,32 @@ export const make = Effect.fn("makeBitbucketApi")(function* () {
430465 } ) ;
431466 } ) ;
432467
468+ const getRepositoryFromLocator = ( repository : BitbucketRepositoryLocator ) =>
469+ executeJson (
470+ "getRepository" ,
471+ HttpClientRequest . get (
472+ apiUrl (
473+ `/repositories/${ encodeURIComponent ( repository . workspace ) } /${ encodeURIComponent ( repository . repoSlug ) } ` ,
474+ ) ,
475+ ) ,
476+ RawBitbucketRepositorySchema ,
477+ ) ;
478+
433479 const getRepository = ( input : {
434480 readonly cwd : string ;
435481 readonly context ?: SourceControlProvider . SourceControlProviderContext ;
436482 readonly repository ?: string ;
437- } ) =>
438- resolveRepository ( input ) . pipe (
439- Effect . flatMap ( ( repository ) =>
440- executeJson (
441- "getRepository" ,
442- HttpClientRequest . get (
443- apiUrl (
444- `/repositories/${ encodeURIComponent ( repository . workspace ) } /${ encodeURIComponent ( repository . repoSlug ) } ` ,
445- ) ,
446- ) ,
447- RawBitbucketRepositorySchema ,
483+ } ) => resolveRepository ( input ) . pipe ( Effect . flatMap ( getRepositoryFromLocator ) ) ;
484+
485+ const getBranchingModelFromLocator = ( repository : BitbucketRepositoryLocator ) =>
486+ executeJson (
487+ "getBranchingModel" ,
488+ HttpClientRequest . get (
489+ apiUrl (
490+ `/repositories/${ encodeURIComponent ( repository . workspace ) } /${ encodeURIComponent ( repository . repoSlug ) } /branching-model` ,
448491 ) ,
449492 ) ,
493+ RawBitbucketBranchingModelSchema ,
450494 ) ;
451495
452496 const getRawPullRequestFromRepository = (
@@ -628,7 +672,22 @@ export const make = Effect.fn("makeBitbucketApi")(function* () {
628672 ) ;
629673 } ) ,
630674 getDefaultBranch : ( input ) =>
631- getRepository ( input ) . pipe ( Effect . map ( ( repository ) => repository . mainbranch ?. name ?? null ) ) ,
675+ resolveRepository ( input ) . pipe (
676+ Effect . flatMap ( ( locator ) =>
677+ Effect . all (
678+ {
679+ repository : getRepositoryFromLocator ( locator ) ,
680+ branchingModel : getBranchingModelFromLocator ( locator ) . pipe (
681+ Effect . catch ( ( ) =>
682+ Effect . succeed < typeof RawBitbucketBranchingModelSchema . Type | null > ( null ) ,
683+ ) ,
684+ ) ,
685+ } ,
686+ { concurrency : "unbounded" } ,
687+ ) ,
688+ ) ,
689+ Effect . map ( defaultChangeRequestTargetBranch ) ,
690+ ) ,
632691 // Bitbucket Cloud pull requests are Git-backed and Bitbucket does not provide
633692 // an official checkout CLI. This provider-local path uses GitVcsDriver as a
634693 // narrow escape hatch to materialize Bitbucket PR refs. Do not generalize this
0 commit comments