@@ -27,21 +27,77 @@ function formatBranchName(name: string): string {
2727 return name . replace ( / [ ^ - a - z A - Z 0 - 9 / . _ - ] + / g, '+' )
2828}
2929
30- export function getBaseGitBranch ( ) : string {
31- // Lazily access constants.ENV.GITHUB_REF_NAME.
32- return (
33- constants . ENV . GITHUB_REF_NAME ||
34- // GitHub defaults to branch name "main"
35- // https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-branches#about-the-default-branch
36- 'main'
37- )
30+ export type SocketBranchParser = (
31+ branch : string ,
32+ ) => SocketBranchParseResult | null
33+
34+ export type SocketBranchParseResult = {
35+ fullName : string
36+ newVersion : string
37+ type : string
38+ workspace : string
39+ version : string
3840}
3941
40- export function getSocketBranchPurlTypeComponent (
41- purl : string | PackageURL | SocketArtifact ,
42- ) : string {
43- const purlObj = getPurlObject ( purl )
44- return formatBranchName ( purlObj . type )
42+ export type SocketBranchPatternOptions = {
43+ newVersion ?: string | undefined
44+ purl ?: string | undefined
45+ workspace ?: string | undefined
46+ }
47+
48+ export function createSocketBranchParser (
49+ options ?: SocketBranchPatternOptions | undefined ,
50+ ) : SocketBranchParser {
51+ const pattern = getSocketBranchPattern ( options )
52+ return function parse ( branch : string ) : SocketBranchParseResult | null {
53+ const match = pattern . exec ( branch ) as
54+ | [ string , string , string , string , string , string ]
55+ | null
56+ if ( ! match ) {
57+ return null
58+ }
59+ const {
60+ 1 : type ,
61+ 2 : workspace ,
62+ 3 : fullName ,
63+ 4 : version ,
64+ 5 : newVersion ,
65+ } = match
66+ return {
67+ fullName,
68+ newVersion : semver . coerce ( newVersion . replaceAll ( '+' , '.' ) ) ?. version ,
69+ type,
70+ workspace,
71+ version : semver . coerce ( version . replaceAll ( '+' , '.' ) ) ?. version ,
72+ } as SocketBranchParseResult
73+ }
74+ }
75+
76+ export async function getBaseGitBranch ( cwd = process . cwd ( ) ) : Promise < string > {
77+ // Lazily access constants.ENV properties.
78+ const { GITHUB_BASE_REF , GITHUB_REF_NAME , GITHUB_REF_TYPE } = constants . ENV
79+ // 1. In a pull request, this is always the base branch.
80+ if ( GITHUB_BASE_REF ) {
81+ return GITHUB_BASE_REF
82+ }
83+ // 2. If it's a branch (not a tag), GITHUB_REF_TYPE should be 'branch'.
84+ if ( GITHUB_REF_TYPE === 'branch' && GITHUB_REF_NAME ) {
85+ return GITHUB_REF_NAME
86+ }
87+ // 3. Try to resolve the default remote branch using 'git remote show origin'.
88+ // This handles detached HEADs or workflows triggered by tags/releases.
89+ try {
90+ const stdout = (
91+ await spawn ( 'git' , [ 'remote' , 'show' , 'origin' ] , { cwd } )
92+ ) . stdout . trim ( )
93+ const match = / (?< = H E A D b r a n c h : ) .+ / . exec ( stdout )
94+ if ( match ?. [ 0 ] ) {
95+ return match [ 0 ] . trim ( )
96+ }
97+ } catch { }
98+ // GitHub defaults to branch name "main"
99+ // https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-branches#about-the-default-branch
100+ return 'main'
45101}
46102
47103export function getSocketBranchFullNameComponent (
@@ -58,23 +114,6 @@ export function getSocketBranchFullNameComponent(
58114 return `${ fmtMaybeNamespace } ${ formatBranchName ( purlObj . name ) } `
59115}
60116
61- export function getSocketBranchPackageVersionComponent (
62- version : string | PackageURL | SocketArtifact ,
63- ) : string {
64- const purlObj = getPurlObject (
65- typeof version === 'string' && ! version . startsWith ( 'pkg:' )
66- ? PackageURL . fromString ( `pkg:unknown/unknown@${ version } ` )
67- : version ,
68- )
69- return formatBranchName ( purlObj . version ! )
70- }
71-
72- export function getSocketBranchWorkspaceComponent (
73- workspace : string | undefined ,
74- ) : string {
75- return workspace ? formatBranchName ( workspace ) : 'root'
76- }
77-
78117export function getSocketBranchName (
79118 purl : string | PackageURL | SocketArtifact ,
80119 newVersion : string ,
@@ -89,10 +128,15 @@ export function getSocketBranchName(
89128 return `socket/${ fmtType } /${ fmtWorkspace } /${ fmtFullName } _${ fmtVersion } _${ fmtNewVersion } `
90129}
91130
92- export type SocketBranchPatternOptions = {
93- newVersion ?: string | undefined
94- purl ?: string | undefined
95- workspace ?: string | undefined
131+ export function getSocketBranchPackageVersionComponent (
132+ version : string | PackageURL | SocketArtifact ,
133+ ) : string {
134+ const purlObj = getPurlObject (
135+ typeof version === 'string' && ! version . startsWith ( 'pkg:' )
136+ ? PackageURL . fromString ( `pkg:unknown/unknown@${ version } ` )
137+ : version ,
138+ )
139+ return formatBranchName ( purlObj . version ! )
96140}
97141
98142export function getSocketBranchPattern (
@@ -124,54 +168,27 @@ export function getSocketBranchPattern(
124168 )
125169}
126170
127- export type SocketBranchParser = (
128- branch : string ,
129- ) => SocketBranchParseResult | null
130-
131- export type SocketBranchParseResult = {
132- fullName : string
133- newVersion : string
134- type : string
135- workspace : string
136- version : string
171+ export function getSocketBranchPurlTypeComponent (
172+ purl : string | PackageURL | SocketArtifact ,
173+ ) : string {
174+ const purlObj = getPurlObject ( purl )
175+ return formatBranchName ( purlObj . type )
137176}
138177
139- export function createSocketBranchParser (
140- options ?: SocketBranchPatternOptions | undefined ,
141- ) : SocketBranchParser {
142- const pattern = getSocketBranchPattern ( options )
143- return function parse ( branch : string ) : SocketBranchParseResult | null {
144- const match = pattern . exec ( branch ) as
145- | [ string , string , string , string , string , string ]
146- | null
147- if ( ! match ) {
148- return null
149- }
150- const {
151- 1 : type ,
152- 2 : workspace ,
153- 3 : fullName ,
154- 4 : version ,
155- 5 : newVersion ,
156- } = match
157- return {
158- fullName,
159- newVersion : semver . coerce ( newVersion . replaceAll ( '+' , '.' ) ) ?. version ,
160- type,
161- workspace,
162- version : semver . coerce ( version . replaceAll ( '+' , '.' ) ) ?. version ,
163- } as SocketBranchParseResult
164- }
178+ export function getSocketBranchWorkspaceComponent (
179+ workspace : string | undefined ,
180+ ) : string {
181+ return workspace ? formatBranchName ( workspace ) : 'root'
165182}
166183
167- export function getSocketPullRequestTitle (
184+ export function getSocketCommitMessage (
168185 purl : string | PackageURL | SocketArtifact ,
169186 newVersion : string ,
170187 workspace ?: string | undefined ,
171188) : string {
172189 const purlObj = getPurlObject ( purl )
173190 const fullName = getPkgFullNameFromPurl ( purlObj )
174- return `Bump ${ fullName } from ${ purlObj . version } to ${ newVersion } ${ workspace ? ` in ${ workspace } ` : '' } `
191+ return `socket: Bump ${ fullName } from ${ purlObj . version } to ${ newVersion } ${ workspace ? ` in ${ workspace } ` : '' } `
175192}
176193
177194export function getSocketPullRequestBody (
@@ -185,14 +202,14 @@ export function getSocketPullRequestBody(
185202 return `Bump [${ fullName } ](${ pkgOverviewUrl } ) from ${ purlObj . version } to ${ newVersion } ${ workspace ? ` in ${ workspace } ` : '' } .`
186203}
187204
188- export function getSocketCommitMessage (
205+ export function getSocketPullRequestTitle (
189206 purl : string | PackageURL | SocketArtifact ,
190207 newVersion : string ,
191208 workspace ?: string | undefined ,
192209) : string {
193210 const purlObj = getPurlObject ( purl )
194211 const fullName = getPkgFullNameFromPurl ( purlObj )
195- return `socket: Bump ${ fullName } from ${ purlObj . version } to ${ newVersion } ${ workspace ? ` in ${ workspace } ` : '' } `
212+ return `Bump ${ fullName } from ${ purlObj . version } to ${ newVersion } ${ workspace ? ` in ${ workspace } ` : '' } `
196213}
197214
198215export async function gitCleanFdx ( cwd = process . cwd ( ) ) : Promise < void > {
@@ -227,7 +244,10 @@ export async function gitCreateAndPushBranch(
227244 )
228245 return true
229246 } catch ( e ) {
230- debugFn ( 'catch: unexpected\n' , e )
247+ debugFn (
248+ `catch: git push --force --set-upstream origin ${ branch } failed\n` ,
249+ e ,
250+ )
231251 }
232252 try {
233253 // Will throw with exit code 1 if branch does not exist.
@@ -236,6 +256,40 @@ export async function gitCreateAndPushBranch(
236256 return false
237257}
238258
259+ export type RepoInfo = {
260+ owner : string
261+ repo : string
262+ }
263+
264+ export async function gitRepoInfo (
265+ cwd = process . cwd ( ) ,
266+ ) : Promise < RepoInfo | null > {
267+ try {
268+ const remoteUrl = (
269+ await spawn ( 'git' , [ 'remote' , 'get-url' , 'origin' ] , { cwd } )
270+ ) . stdout . trim ( )
271+ // 1. Handle SSH-style, e.g. git@github.com:owner/repo.git
272+ const sshMatch = / ^ g i t @ [ ^ : ] + : ( [ ^ / ] + ) \/ ( .+ ?) (?: \. g i t ) ? $ / . exec ( remoteUrl )
273+ if ( sshMatch ) {
274+ return { owner : sshMatch [ 1 ] ! , repo : sshMatch [ 2 ] ! }
275+ }
276+ // 2. Handle HTTPS/URL-style, e.g. https://github.com/owner/repo.git
277+ try {
278+ const parsed = new URL ( remoteUrl )
279+ const segments = parsed . pathname . split ( '/' )
280+ const owner = segments . at ( - 2 )
281+ const repo = segments . at ( - 1 ) ?. replace ( / \. g i t $ / , '' )
282+ if ( owner && repo ) {
283+ return { owner, repo }
284+ }
285+ } catch { }
286+ debugFn ( 'git: unmatched git remote URL format' , remoteUrl )
287+ } catch ( e ) {
288+ debugFn ( 'catch: git remote get-url origin failed\n' , e )
289+ }
290+ return null
291+ }
292+
239293export async function gitEnsureIdentity (
240294 name : string ,
241295 email : string ,
@@ -260,7 +314,7 @@ export async function gitEnsureIdentity(
260314 try {
261315 await spawn ( 'git' , [ 'config' , prop , value ] , stdioIgnoreOptions )
262316 } catch ( e ) {
263- debugFn ( ' catch: unexpected\n' , e )
317+ debugFn ( ` catch: git config ${ prop } ${ value } failed\n` , e )
264318 }
265319 }
266320 } ) ,
0 commit comments