@@ -39,7 +39,18 @@ if (!validSpecifiers.includes(versionSpecifier) && !isValidVersion) {
3939 process . exit ( 1 )
4040}
4141
42+ function safeExec ( cmd : string , opts = { } ) {
43+ try {
44+ return execSync ( cmd , { stdio : 'inherit' , ...opts } )
45+ } catch ( err ) {
46+ console . error ( `❌ Command failed: ${ cmd } ` )
47+ throw err
48+ }
49+ }
50+
4251; ( async ( ) => {
52+ // --- VERSION AND BUILD ---
53+
4354 const { workspaceVersion, projectsVersionData } = await releaseVersion ( {
4455 verbose : true ,
4556 gitCommit : false ,
@@ -49,28 +60,37 @@ if (!validSpecifiers.includes(versionSpecifier) && !isValidVersion) {
4960
5061 // Update version.ts files with the new versions
5162 console . log ( '\n📦 Updating version.ts files...' )
52- execSync ( 'npx tsx scripts/update-version-files.ts' , { stdio : 'inherit' } )
63+ safeExec ( 'npx tsx scripts/update-version-files.ts' )
5364
5465 // Rebuild packages with correct versions
5566 console . log ( '\n🔨 Rebuilding packages with new versions...' )
56- execSync ( 'npx nx run-many --target=build --all' , { stdio : 'inherit' } )
67+ safeExec ( 'npx nx run-many --target=build --all' )
5768 console . log ( '✅ Build complete\n' )
5869
70+ // --- GIT AUTH SETUP FOR TAGGING/CHANGELOG ---
71+
5972 // releaseChangelog should use the GitHub token with permission for tagging
6073 // before switching the token, backup the GITHUB_TOKEN so that it
6174 // can be restored afterwards and used by releasePublish. We can't use the same
6275 // token, because releasePublish wants a token that has the id_token: write permission
6376 // so that we can use OIDC for trusted publishing
77+
6478 const gh_token_bak = process . env . GITHUB_TOKEN
6579 process . env . GITHUB_TOKEN = process . env . RELEASE_GITHUB_TOKEN
66- // backup original auth header
67- const originalAuth = execSync ( 'git config --local http.https://github.com/.extraheader' )
68- . toString ( )
69- . trim ( )
80+
81+ // backup original auth header if exists
82+ let originalAuth = ''
83+ try {
84+ originalAuth = execSync ( 'git config --local http.https://github.com/.extraheader' )
85+ . toString ( )
86+ . trim ( )
87+ } catch { }
88+
7089 // switch the token used
7190 const authHeader = `AUTHORIZATION: basic ${ Buffer . from ( `x-access-token:${ process . env . RELEASE_GITHUB_TOKEN } ` ) . toString ( 'base64' ) } `
72- execSync ( `git config --local http.https://github.com/.extraheader "${ authHeader } "` )
91+ safeExec ( `git config --local http.https://github.com/.extraheader "${ authHeader } "` )
7392
93+ // ---- CHANGELOG GENERATION ---
7494 const result = await releaseChangelog ( {
7595 versionData : projectsVersionData ,
7696 version : workspaceVersion ,
@@ -79,12 +99,18 @@ if (!validSpecifiers.includes(versionSpecifier) && !isValidVersion) {
7999 stageChanges : false ,
80100 } )
81101
102+ // --- RESTORE GIT AUTH FOR PUBLISHING ---
82103 // npm publish with OIDC
83104 // not strictly necessary to restore the header but do it incase we require it later
84- execSync ( `git config --local http.https://github.com/.extraheader "${ originalAuth } "` )
85- // restore the GH token
105+ if ( originalAuth ) {
106+ safeExec ( `git config --local http.https://github.com/.extraheader "${ originalAuth } "` )
107+ } else {
108+ safeExec ( `git config --local --unset http.https://github.com/.extraheader || true` )
109+ }
86110 process . env . GITHUB_TOKEN = gh_token_bak
87111
112+ // --- NPM PUBLISH ---
113+
88114 const publishResult = await releasePublish ( {
89115 registry : 'https://registry.npmjs.org/' ,
90116 access : 'public' ,
@@ -95,20 +121,36 @@ if (!validSpecifiers.includes(versionSpecifier) && !isValidVersion) {
95121 // Publish gotrue-js as legacy mirror of auth-js
96122 console . log ( '\n📦 Publishing @supabase/gotrue-js (legacy mirror)...' )
97123 try {
98- execSync ( 'npx tsx scripts/publish-gotrue-legacy.ts --tag=latest' , { stdio : 'inherit' } )
124+ safeExec ( 'npx tsx scripts/publish-gotrue-legacy.ts --tag=latest' )
99125 } catch ( error ) {
100126 console . error ( '❌ Failed to publish gotrue-js legacy package:' , error )
101127 // Don't fail the entire release if gotrue-js fails
102128 console . log ( '⚠️ Continuing with release despite gotrue-js publish failure' )
103129 }
104130
105- // ---- Create release branch + PR ----
106- // switch back to the releaser GitHub token
131+ // ---- CREATE RELEASE BRANCH + PR ----
107132 process . env . GITHUB_TOKEN = process . env . RELEASE_GITHUB_TOKEN
133+
134+ // REMOVE ALL credential helpers and .extraheader IMMEDIATELY BEFORE PUSH
135+ try {
136+ safeExec ( 'git config --global --unset credential.helper || true' )
137+ } catch { }
138+ try {
139+ safeExec ( 'git config --local --unset credential.helper || true' )
140+ } catch { }
141+ try {
142+ safeExec ( 'git config --local --unset http.https://github.com/.extraheader || true' )
143+ } catch { }
144+
145+ // Ensure remote is set again before push
146+ if ( process . env . RELEASE_GITHUB_TOKEN ) {
147+ const remoteUrl = `https://x-access-token:${ process . env . RELEASE_GITHUB_TOKEN } @github.com/supabase/supabase-js.git`
148+ safeExec ( `git remote set-url origin "${ remoteUrl } "` )
149+ }
150+
108151 const version = result . workspaceChangelog ?. releaseVersion . rawVersion || workspaceVersion
109152
110153 // Validate version to prevent command injection
111- // Version should match semver pattern or be a valid npm version specifier
112154 if (
113155 ! version ||
114156 ! / ^ ( v ? \d + \. \d + \. \d + ( - [ a - z A - Z 0 - 9 . - ] + ) ? | p a t c h | m i n o r | m a j o r | p r e p a t c h | p r e m i n o r | p r e m a j o r | p r e r e l e a s e ) $ / . test (
@@ -122,29 +164,31 @@ if (!validSpecifiers.includes(versionSpecifier) && !isValidVersion) {
122164 const branchName = `release-${ version } `
123165
124166 try {
125- execSync ( `git checkout -b ${ branchName } ` )
126- execSync ( 'git add CHANGELOG.md || true' )
127- execSync ( 'git add packages/**/CHANGELOG.md || true' )
167+ safeExec ( `git checkout -b ${ branchName } ` )
168+ safeExec ( 'git add CHANGELOG.md || true' )
169+ safeExec ( 'git add packages/**/CHANGELOG.md || true' )
128170
129171 // Commit changes if any
130172 try {
131- execSync ( `git commit -m "chore(release): publish version ${ version } "` )
173+ safeExec ( `git commit -m "chore(release): publish version ${ version } "` )
132174 } catch {
133175 console . log ( 'No changes to commit' )
134176 }
135177
136- execSync ( `git push origin ${ branchName } ` )
178+ // DEBUG: Show credential config and remote before push
179+ safeExec ( 'git config --local --get http.https://github.com/.extraheader || true' )
180+
181+ safeExec ( `git push origin ${ branchName } ` )
137182
138183 // Open PR using GitHub CLI
139- execSync (
140- `gh pr create --base master --head ${ branchName } --title "chore(release): ${ version } " --body "Automated release PR for ${ version } "` ,
141- { stdio : 'inherit' }
184+ safeExec (
185+ `gh pr create --base master --head ${ branchName } --title "chore(release): version ${ version } changelogs" --body "Automated PR to update changelogs for version ${ version } ."`
142186 )
143187
144188 // Enable auto-merge
145- execSync ( `gh pr merge --auto --squash` , { stdio : 'inherit' } )
189+ safeExec ( `gh pr merge --auto --squash` )
146190
147- execSync ( 'git stash' )
191+ safeExec ( 'git stash' )
148192 console . log ( '✅ Stashed package.json changes' )
149193 } catch ( err ) {
150194 console . error ( '❌ Failed to push release branch or open PR' , err )
0 commit comments