@@ -20,12 +20,9 @@ export function pushWithTags(opts?: { cwd?: string }): void {
2020 * Temporarily configure git credentials using BUMPY_GH_TOKEN (or GH_TOKEN),
2121 * execute a callback, then restore the original config.
2222 *
23- * Uses the http.extraheader approach (same as actions/checkout) rather than
24- * embedding tokens in the remote URL, because extraheader takes priority over
25- * any credential manager that may be installed on the runner.
26- *
27- * Also clears any existing credential config set by actions/checkout (extraheader
28- * or includeIf entries) so our token is used instead of the default GITHUB_TOKEN.
23+ * Embeds the token in the remote URL and clears any existing credential config
24+ * set by actions/checkout (extraheader or includeIf entries) so our token is
25+ * used instead of the default GITHUB_TOKEN.
2926 */
3027export function withGitToken ( cwd : string | undefined , fn : ( ) => void ) : void {
3128 const token = process . env . BUMPY_GH_TOKEN || process . env . GH_TOKEN ;
@@ -37,8 +34,6 @@ export function withGitToken(cwd: string | undefined, fn: () => void): void {
3734 }
3835
3936 const extraHeaderKey = `http.${ server } /.extraheader` ;
40- // Authorization: bearer works for both GitHub PATs and GITHUB_TOKEN
41- const authHeader = `Authorization: bearer ${ token } ` ;
4237
4338 // Save and clear any existing credential config set by actions/checkout:
4439 // 1. Direct http.<server>/.extraheader in local config
@@ -56,15 +51,21 @@ export function withGitToken(cwd: string | undefined, fn: () => void): void {
5651 }
5752 }
5853
54+ // Rewrite the remote URL to embed the token — this is the most reliable
55+ // auth method as it bypasses all credential helpers and extraheader issues
56+ const originalUrl = tryRunArgs ( [ 'git' , 'remote' , 'get-url' , 'origin' ] , { cwd } ) ;
57+ const authedUrl = originalUrl ? originalUrl . replace ( / ^ h t t p s : \/ \/ / , `https://x-access-token:${ token } @` ) : null ;
58+
5959 try {
6060 if ( savedHeader ) {
6161 runArgs ( [ 'git' , 'config' , '--local' , '--unset-all' , extraHeaderKey ] , { cwd } ) ;
6262 }
6363 for ( const entry of savedIncludeIfs ) {
6464 tryRunArgs ( [ 'git' , 'config' , '--local' , '--unset' , entry . key ] , { cwd } ) ;
6565 }
66- // Set our token as the Authorization header — this takes priority over credential managers
67- runArgs ( [ 'git' , 'config' , '--local' , extraHeaderKey , authHeader ] , { cwd } ) ;
66+ if ( authedUrl ) {
67+ runArgs ( [ 'git' , 'remote' , 'set-url' , 'origin' , authedUrl ] , { cwd } ) ;
68+ }
6869 try {
6970 fn ( ) ;
7071 } catch ( err ) {
@@ -73,8 +74,10 @@ export function withGitToken(cwd: string | undefined, fn: () => void): void {
7374 throw new Error ( msg . replaceAll ( token , '***' ) ) ;
7475 }
7576 } finally {
76- // Remove our injected header
77- tryRunArgs ( [ 'git' , 'config' , '--local' , '--unset-all' , extraHeaderKey ] , { cwd } ) ;
77+ // Restore original remote URL
78+ if ( originalUrl ) {
79+ runArgs ( [ 'git' , 'remote' , 'set-url' , 'origin' , originalUrl ] , { cwd } ) ;
80+ }
7881 // Restore previous credential config
7982 if ( savedHeader ) {
8083 runArgs ( [ 'git' , 'config' , '--local' , extraHeaderKey , savedHeader ] , { cwd } ) ;
0 commit comments