@@ -249,6 +249,7 @@ function pushWithToken(rootDir: string, branch: string, config: BumpyConfig): vo
249249 // Both must be cleared for our custom token to be used.
250250 const extraHeaderKey = `http.${ server } /.extraheader` ;
251251 const savedHeader = tryRunArgs ( [ 'git' , 'config' , '--local' , extraHeaderKey ] , { cwd : rootDir } ) ;
252+ log . dim ( ` extraheader present: ${ ! ! savedHeader } ` ) ;
252253
253254 // Collect includeIf entries that point to credential config files
254255 // git config --get-regexp outputs keys in lowercase, so match accordingly
@@ -264,26 +265,96 @@ function pushWithToken(rootDir: string, branch: string, config: BumpyConfig): vo
264265 }
265266 }
266267 }
268+ log . dim ( ` includeIf entries found: ${ savedIncludeIfs . length } ` ) ;
269+ for ( const entry of savedIncludeIfs ) {
270+ log . dim ( ` ${ entry . key } ` ) ;
271+ }
272+
273+ // Dump full git config for debugging
274+ const fullConfig = tryRunArgs ( [ 'git' , 'config' , '--local' , '--list' ] , { cwd : rootDir } ) ;
275+ if ( fullConfig ) {
276+ for ( const line of fullConfig . split ( '\n' ) ) {
277+ if ( / i n c l u d e i f | e x t r a h e a d e r / i. test ( line ) ) {
278+ log . dim ( ` [git config] ${ line } ` ) ;
279+ }
280+ }
281+ }
267282
268283 try {
269284 if ( savedHeader ) {
270285 runArgs ( [ 'git' , 'config' , '--local' , '--unset-all' , extraHeaderKey ] , { cwd : rootDir } ) ;
271286 }
272287 for ( const entry of savedIncludeIfs ) {
288+ log . dim ( ` Unsetting: ${ entry . key } ` ) ;
273289 tryRunArgs ( [ 'git' , 'config' , '--local' , '--unset' , entry . key ] , { cwd : rootDir } ) ;
274290 }
291+
292+ // Verify cleanup
293+ const remainingIncludeIf = tryRunArgs ( [ 'git' , 'config' , '--local' , '--get-regexp' , '^includeif\\.gitdir:' ] , {
294+ cwd : rootDir ,
295+ } ) ;
296+ if ( remainingIncludeIf ) {
297+ log . warn ( ` includeIf entries still present after cleanup:\n${ remainingIncludeIf } ` ) ;
298+ } else {
299+ log . dim ( ' All includeIf entries cleared' ) ;
300+ }
301+
302+ // Set both fetch and push URLs to the authed URL
275303 runArgs ( [ 'git' , 'remote' , 'set-url' , 'origin' , authedUrl ] , { cwd : rootDir } ) ;
304+ runArgs ( [ 'git' , 'remote' , 'set-url' , 'origin' , authedUrl , '--push' ] , { cwd : rootDir } ) ;
305+ // Verify URLs (redact token)
306+ const verifyFetch = tryRunArgs ( [ 'git' , 'remote' , 'get-url' , 'origin' ] , { cwd : rootDir } ) ;
307+ const verifyPush = tryRunArgs ( [ 'git' , 'remote' , 'get-url' , 'origin' , '--push' ] , { cwd : rootDir } ) ;
308+ log . dim ( ` Fetch URL: ${ verifyFetch ?. replace ( token , '***' ) } ` ) ;
309+ log . dim ( ` Push URL: ${ verifyPush ?. replace ( token , '***' ) } ` ) ;
310+
311+ // Check for url.*.insteadOf rewrites (across all config levels)
312+ const insteadOf = tryRunArgs ( [ 'git' , 'config' , '--get-regexp' , '^url\\..*\\.insteadof' ] , { cwd : rootDir } ) ;
313+ if ( insteadOf ) {
314+ log . dim ( ` url.*.insteadOf rules:\n${ insteadOf } ` ) ;
315+ }
316+
317+ // Dump the effective resolved push URL from git's perspective
318+ const resolvedRemote = tryRunArgs ( [ 'git' , 'ls-remote' , '--get-url' , 'origin' ] , { cwd : rootDir } ) ;
319+ log . dim ( ` Resolved remote: ${ resolvedRemote ?. replace ( token , '***' ) } ` ) ;
320+
321+ // Check what credential helpers are active
322+ const credHelper = tryRunArgs ( [ 'git' , 'config' , '--show-origin' , '--get-all' , 'credential.helper' ] , {
323+ cwd : rootDir ,
324+ } ) ;
325+ if ( credHelper ) {
326+ log . dim ( ` credential.helper:\n${ credHelper } ` ) ;
327+ }
328+
329+ // Test token validity via API before pushing
330+ const origGhToken = process . env . GH_TOKEN ;
331+ process . env . GH_TOKEN = token ;
332+ const tokenCheck = tryRunArgs (
333+ [ 'gh' , 'api' , 'repos/' + repo , '--jq' , '.permissions' ] ,
334+ { cwd : rootDir } ,
335+ ) ;
336+ log . dim ( ` BUMPY_GH_TOKEN permissions: ${ tokenCheck } ` ) ;
337+ if ( origGhToken !== undefined ) {
338+ process . env . GH_TOKEN = origGhToken ;
339+ } else {
340+ delete process . env . GH_TOKEN ;
341+ }
342+
276343 try {
277- runArgs ( [ 'git' , 'push' , '-u' , 'origin' , branch , '--force' ] , { cwd : rootDir } ) ;
344+ runArgs ( [ 'git' , 'push' , '-u' , 'origin' , branch , '--force' , '--verbose' ] , { cwd : rootDir } ) ;
278345 } catch ( err ) {
279346 // Redact token from error messages to prevent leakage in CI logs
280347 const msg = err instanceof Error ? err . message : String ( err ) ;
281- throw new Error ( msg . replaceAll ( token , '***' ) ) ;
348+ // Log the redacted stderr for debugging
349+ const redacted = msg . replaceAll ( token , '***' ) ;
350+ log . error ( redacted ) ;
351+ throw new Error ( redacted ) ;
282352 }
283353 } finally {
284- // Restore original URL, extraheader, and includeIf entries
354+ // Restore original URL (both fetch and push) , extraheader, and includeIf entries
285355 if ( originalUrl ) {
286356 runArgs ( [ 'git' , 'remote' , 'set-url' , 'origin' , originalUrl ] , { cwd : rootDir } ) ;
357+ runArgs ( [ 'git' , 'remote' , 'set-url' , 'origin' , originalUrl , '--push' ] , { cwd : rootDir } ) ;
287358 }
288359 if ( savedHeader ) {
289360 runArgs ( [ 'git' , 'config' , '--local' , extraHeaderKey , savedHeader ] , { cwd : rootDir } ) ;
0 commit comments