mirror of
				https://github.com/actions/checkout.git
				synced 2025-10-30 23:10:31 +00:00 
			
		
		
		
	Persist creds to a separate file
This commit is contained in:
		| @@ -86,16 +86,29 @@ describe('git-auth-helper tests', () => { | ||||
|     // Act | ||||
|     await authHelper.configureAuth() | ||||
|  | ||||
|     // Assert config | ||||
|     const configContent = ( | ||||
|     // Assert config - check that .git/config contains includeIf entries | ||||
|     const localConfigContent = ( | ||||
|       await fs.promises.readFile(localGitConfigPath) | ||||
|     ).toString() | ||||
|     expect( | ||||
|       localConfigContent.indexOf('includeIf.gitdir:') | ||||
|     ).toBeGreaterThanOrEqual(0) | ||||
|  | ||||
|     // Assert credentials config file contains the actual credentials | ||||
|     const credentialsFiles = (await fs.promises.readdir(runnerTemp)).filter( | ||||
|       f => f.startsWith('git-credentials-') && f.endsWith('.config') | ||||
|     ) | ||||
|     expect(credentialsFiles.length).toBe(1) | ||||
|     const credentialsConfigPath = path.join(runnerTemp, credentialsFiles[0]) | ||||
|     const credentialsContent = ( | ||||
|       await fs.promises.readFile(credentialsConfigPath) | ||||
|     ).toString() | ||||
|     const basicCredential = Buffer.from( | ||||
|       `x-access-token:${settings.authToken}`, | ||||
|       'utf8' | ||||
|     ).toString('base64') | ||||
|     expect( | ||||
|       configContent.indexOf( | ||||
|       credentialsContent.indexOf( | ||||
|         `http.${expectedServerUrl}/.extraheader AUTHORIZATION: basic ${basicCredential}` | ||||
|       ) | ||||
|     ).toBeGreaterThanOrEqual(0) | ||||
| @@ -120,7 +133,7 @@ describe('git-auth-helper tests', () => { | ||||
|     'inject https://github.com as github server url' | ||||
|   it(configureAuth_AcceptsGitHubServerUrlSetToGHEC, async () => { | ||||
|     await testAuthHeader( | ||||
|       configureAuth_AcceptsGitHubServerUrl, | ||||
|       configureAuth_AcceptsGitHubServerUrlSetToGHEC, | ||||
|       'https://github.com' | ||||
|     ) | ||||
|   }) | ||||
| @@ -141,12 +154,17 @@ describe('git-auth-helper tests', () => { | ||||
|       // Act | ||||
|       await authHelper.configureAuth() | ||||
|  | ||||
|       // Assert config | ||||
|       const configContent = ( | ||||
|         await fs.promises.readFile(localGitConfigPath) | ||||
|       // Assert config - check credentials config file (not local .git/config) | ||||
|       const credentialsFiles = (await fs.promises.readdir(runnerTemp)).filter( | ||||
|         f => f.startsWith('git-credentials-') && f.endsWith('.config') | ||||
|       ) | ||||
|       expect(credentialsFiles.length).toBe(1) | ||||
|       const credentialsConfigPath = path.join(runnerTemp, credentialsFiles[0]) | ||||
|       const credentialsContent = ( | ||||
|         await fs.promises.readFile(credentialsConfigPath) | ||||
|       ).toString() | ||||
|       expect( | ||||
|         configContent.indexOf( | ||||
|         credentialsContent.indexOf( | ||||
|           `http.https://github.com/.extraheader AUTHORIZATION` | ||||
|         ) | ||||
|       ).toBeGreaterThanOrEqual(0) | ||||
| @@ -251,13 +269,16 @@ describe('git-auth-helper tests', () => { | ||||
|       expectedSshCommand | ||||
|     ) | ||||
|  | ||||
|     // Asserty git config | ||||
|     // Assert git config | ||||
|     const gitConfigLines = (await fs.promises.readFile(localGitConfigPath)) | ||||
|       .toString() | ||||
|       .split('\n') | ||||
|       .filter(x => x) | ||||
|     expect(gitConfigLines).toHaveLength(1) | ||||
|     expect(gitConfigLines[0]).toMatch(/^http\./) | ||||
|     // Should have includeIf entries pointing to credentials file | ||||
|     expect(gitConfigLines.length).toBeGreaterThan(0) | ||||
|     expect( | ||||
|       gitConfigLines.some(line => line.indexOf('includeIf.gitdir:') >= 0) | ||||
|     ).toBeTruthy() | ||||
|   }) | ||||
|  | ||||
|   const configureAuth_setsSshCommandWhenPersistCredentialsTrue = | ||||
| @@ -419,8 +440,20 @@ describe('git-auth-helper tests', () => { | ||||
|     expect( | ||||
|       configContent.indexOf('value-from-global-config') | ||||
|     ).toBeGreaterThanOrEqual(0) | ||||
|     // Global config should have include.path pointing to credentials file | ||||
|     expect(configContent.indexOf('include.path')).toBeGreaterThanOrEqual(0) | ||||
|  | ||||
|     // Check credentials in the separate config file | ||||
|     const credentialsFiles = (await fs.promises.readdir(runnerTemp)).filter( | ||||
|       f => f.startsWith('git-credentials-') && f.endsWith('.config') | ||||
|     ) | ||||
|     expect(credentialsFiles.length).toBeGreaterThan(0) | ||||
|     const credentialsConfigPath = path.join(runnerTemp, credentialsFiles[0]) | ||||
|     const credentialsContent = ( | ||||
|       await fs.promises.readFile(credentialsConfigPath) | ||||
|     ).toString() | ||||
|     expect( | ||||
|       configContent.indexOf( | ||||
|       credentialsContent.indexOf( | ||||
|         `http.https://github.com/.extraheader AUTHORIZATION: basic ${basicCredential}` | ||||
|       ) | ||||
|     ).toBeGreaterThanOrEqual(0) | ||||
| @@ -463,8 +496,20 @@ describe('git-auth-helper tests', () => { | ||||
|       const configContent = ( | ||||
|         await fs.promises.readFile(path.join(git.env['HOME'], '.gitconfig')) | ||||
|       ).toString() | ||||
|       // Global config should have include.path pointing to credentials file | ||||
|       expect(configContent.indexOf('include.path')).toBeGreaterThanOrEqual(0) | ||||
|  | ||||
|       // Check credentials in the separate config file | ||||
|       const credentialsFiles = (await fs.promises.readdir(runnerTemp)).filter( | ||||
|         f => f.startsWith('git-credentials-') && f.endsWith('.config') | ||||
|       ) | ||||
|       expect(credentialsFiles.length).toBeGreaterThan(0) | ||||
|       const credentialsConfigPath = path.join(runnerTemp, credentialsFiles[0]) | ||||
|       const credentialsContent = ( | ||||
|         await fs.promises.readFile(credentialsConfigPath) | ||||
|       ).toString() | ||||
|       expect( | ||||
|         configContent.indexOf( | ||||
|         credentialsContent.indexOf( | ||||
|           `http.https://github.com/.extraheader AUTHORIZATION: basic ${basicCredential}` | ||||
|         ) | ||||
|       ).toBeGreaterThanOrEqual(0) | ||||
| @@ -550,15 +595,15 @@ describe('git-auth-helper tests', () => { | ||||
|       await authHelper.configureSubmoduleAuth() | ||||
|  | ||||
|       // Assert | ||||
|       expect(mockSubmoduleForeach).toHaveBeenCalledTimes(4) | ||||
|       // Should configure insteadOf (2 calls for two values) | ||||
|       expect(mockSubmoduleForeach).toHaveBeenCalledTimes(3) | ||||
|       expect(mockSubmoduleForeach.mock.calls[0][0]).toMatch( | ||||
|         /unset-all.*insteadOf/ | ||||
|       ) | ||||
|       expect(mockSubmoduleForeach.mock.calls[1][0]).toMatch(/http.*extraheader/) | ||||
|       expect(mockSubmoduleForeach.mock.calls[2][0]).toMatch( | ||||
|       expect(mockSubmoduleForeach.mock.calls[1][0]).toMatch( | ||||
|         /url.*insteadOf.*git@github.com:/ | ||||
|       ) | ||||
|       expect(mockSubmoduleForeach.mock.calls[3][0]).toMatch( | ||||
|       expect(mockSubmoduleForeach.mock.calls[2][0]).toMatch( | ||||
|         /url.*insteadOf.*org-123456@github.com:/ | ||||
|       ) | ||||
|     } | ||||
| @@ -589,12 +634,12 @@ describe('git-auth-helper tests', () => { | ||||
|       await authHelper.configureSubmoduleAuth() | ||||
|  | ||||
|       // Assert | ||||
|       expect(mockSubmoduleForeach).toHaveBeenCalledTimes(3) | ||||
|       // Should configure sshCommand (1 call) | ||||
|       expect(mockSubmoduleForeach).toHaveBeenCalledTimes(2) | ||||
|       expect(mockSubmoduleForeach.mock.calls[0][0]).toMatch( | ||||
|         /unset-all.*insteadOf/ | ||||
|       ) | ||||
|       expect(mockSubmoduleForeach.mock.calls[1][0]).toMatch(/http.*extraheader/) | ||||
|       expect(mockSubmoduleForeach.mock.calls[2][0]).toMatch(/core\.sshCommand/) | ||||
|       expect(mockSubmoduleForeach.mock.calls[1][0]).toMatch(/core\.sshCommand/) | ||||
|     } | ||||
|   ) | ||||
|  | ||||
| @@ -660,19 +705,201 @@ describe('git-auth-helper tests', () => { | ||||
|     await setup(removeAuth_removesToken) | ||||
|     const authHelper = gitAuthHelper.createAuthHelper(git, settings) | ||||
|     await authHelper.configureAuth() | ||||
|     let gitConfigContent = ( | ||||
|  | ||||
|     // Verify includeIf entries exist in local config | ||||
|     let localConfigContent = ( | ||||
|       await fs.promises.readFile(localGitConfigPath) | ||||
|     ).toString() | ||||
|     expect(gitConfigContent.indexOf('http.')).toBeGreaterThanOrEqual(0) // sanity check | ||||
|     expect( | ||||
|       localConfigContent.indexOf('includeIf.gitdir:') | ||||
|     ).toBeGreaterThanOrEqual(0) | ||||
|  | ||||
|     // Verify both host and container includeIf entries are present | ||||
|     const hostGitDir = path.join(workspace, '.git').replace(/\\/g, '/') | ||||
|     expect( | ||||
|       localConfigContent.indexOf(`includeIf.gitdir:${hostGitDir}.path`) | ||||
|     ).toBeGreaterThanOrEqual(0) | ||||
|     expect( | ||||
|       localConfigContent.indexOf('includeIf.gitdir:/github/workspace/.git.path') | ||||
|     ).toBeGreaterThanOrEqual(0) | ||||
|  | ||||
|     // Verify credentials file exists | ||||
|     let credentialsFiles = (await fs.promises.readdir(runnerTemp)).filter( | ||||
|       f => f.startsWith('git-credentials-') && f.endsWith('.config') | ||||
|     ) | ||||
|     expect(credentialsFiles.length).toBe(1) | ||||
|     const credentialsFilePath = path.join(runnerTemp, credentialsFiles[0]) | ||||
|  | ||||
|     // Verify credentials file contains the auth token | ||||
|     let credentialsContent = ( | ||||
|       await fs.promises.readFile(credentialsFilePath) | ||||
|     ).toString() | ||||
|     const basicCredential = Buffer.from( | ||||
|       `x-access-token:${settings.authToken}`, | ||||
|       'utf8' | ||||
|     ).toString('base64') | ||||
|     expect( | ||||
|       credentialsContent.indexOf( | ||||
|         `http.https://github.com/.extraheader AUTHORIZATION: basic ${basicCredential}` | ||||
|       ) | ||||
|     ).toBeGreaterThanOrEqual(0) | ||||
|  | ||||
|     // Verify the includeIf entries point to the credentials file | ||||
|     const containerCredentialsPath = path.posix.join( | ||||
|       '/github/runner_temp', | ||||
|       path.basename(credentialsFilePath) | ||||
|     ) | ||||
|     expect( | ||||
|       localConfigContent.indexOf(credentialsFilePath) | ||||
|     ).toBeGreaterThanOrEqual(0) | ||||
|     expect( | ||||
|       localConfigContent.indexOf(containerCredentialsPath) | ||||
|     ).toBeGreaterThanOrEqual(0) | ||||
|  | ||||
|     // Act | ||||
|     await authHelper.removeAuth() | ||||
|  | ||||
|     // Assert git config | ||||
|     gitConfigContent = ( | ||||
|     // Assert all includeIf entries removed from local git config | ||||
|     localConfigContent = ( | ||||
|       await fs.promises.readFile(localGitConfigPath) | ||||
|     ).toString() | ||||
|     expect(gitConfigContent.indexOf('http.')).toBeLessThan(0) | ||||
|     expect(localConfigContent.indexOf('includeIf.gitdir:')).toBeLessThan(0) | ||||
|     expect( | ||||
|       localConfigContent.indexOf(`includeIf.gitdir:${hostGitDir}.path`) | ||||
|     ).toBeLessThan(0) | ||||
|     expect( | ||||
|       localConfigContent.indexOf('includeIf.gitdir:/github/workspace/.git.path') | ||||
|     ).toBeLessThan(0) | ||||
|     expect(localConfigContent.indexOf(credentialsFilePath)).toBeLessThan(0) | ||||
|     expect(localConfigContent.indexOf(containerCredentialsPath)).toBeLessThan(0) | ||||
|  | ||||
|     // Assert credentials config file deleted | ||||
|     credentialsFiles = (await fs.promises.readdir(runnerTemp)).filter( | ||||
|       f => f.startsWith('git-credentials-') && f.endsWith('.config') | ||||
|     ) | ||||
|     expect(credentialsFiles.length).toBe(0) | ||||
|  | ||||
|     // Verify credentials file no longer exists on disk | ||||
|     try { | ||||
|       await fs.promises.stat(credentialsFilePath) | ||||
|       throw new Error('Credentials file should have been deleted') | ||||
|     } catch (err) { | ||||
|       if ((err as any)?.code !== 'ENOENT') { | ||||
|         throw err | ||||
|       } | ||||
|     } | ||||
|   }) | ||||
|  | ||||
|   const removeAuth_removesTokenFromSubmodules = | ||||
|     'removeAuth removes token from submodules' | ||||
|   it(removeAuth_removesTokenFromSubmodules, async () => { | ||||
|     // Arrange | ||||
|     await setup(removeAuth_removesTokenFromSubmodules) | ||||
|  | ||||
|     // Create fake submodule config paths | ||||
|     const submodule1Dir = path.join(workspace, '.git', 'modules', 'submodule-1') | ||||
|     const submodule2Dir = path.join(workspace, '.git', 'modules', 'submodule-2') | ||||
|     const submodule1ConfigPath = path.join(submodule1Dir, 'config') | ||||
|     const submodule2ConfigPath = path.join(submodule2Dir, 'config') | ||||
|  | ||||
|     await fs.promises.mkdir(submodule1Dir, {recursive: true}) | ||||
|     await fs.promises.mkdir(submodule2Dir, {recursive: true}) | ||||
|     await fs.promises.writeFile(submodule1ConfigPath, '') | ||||
|     await fs.promises.writeFile(submodule2ConfigPath, '') | ||||
|  | ||||
|     // Mock getSubmoduleConfigPaths to return our fake submodules (for both configure and remove) | ||||
|     const mockGetSubmoduleConfigPaths = | ||||
|       git.getSubmoduleConfigPaths as jest.Mock<any, any> | ||||
|     mockGetSubmoduleConfigPaths.mockResolvedValue([ | ||||
|       submodule1ConfigPath, | ||||
|       submodule2ConfigPath | ||||
|     ]) | ||||
|  | ||||
|     const authHelper = gitAuthHelper.createAuthHelper(git, settings) | ||||
|     await authHelper.configureAuth() | ||||
|     await authHelper.configureSubmoduleAuth() | ||||
|  | ||||
|     // Verify credentials file exists | ||||
|     let credentialsFiles = (await fs.promises.readdir(runnerTemp)).filter( | ||||
|       f => f.startsWith('git-credentials-') && f.endsWith('.config') | ||||
|     ) | ||||
|     expect(credentialsFiles.length).toBe(1) | ||||
|     const credentialsFilePath = path.join(runnerTemp, credentialsFiles[0]) | ||||
|  | ||||
|     // Verify submodule 1 config has includeIf entries | ||||
|     let submodule1Content = ( | ||||
|       await fs.promises.readFile(submodule1ConfigPath) | ||||
|     ).toString() | ||||
|     const submodule1GitDir = submodule1Dir.replace(/\\/g, '/') | ||||
|     expect( | ||||
|       submodule1Content.indexOf(`includeIf.gitdir:${submodule1GitDir}.path`) | ||||
|     ).toBeGreaterThanOrEqual(0) | ||||
|     expect( | ||||
|       submodule1Content.indexOf(credentialsFilePath) | ||||
|     ).toBeGreaterThanOrEqual(0) | ||||
|  | ||||
|     // Verify submodule 2 config has includeIf entries | ||||
|     let submodule2Content = ( | ||||
|       await fs.promises.readFile(submodule2ConfigPath) | ||||
|     ).toString() | ||||
|     const submodule2GitDir = submodule2Dir.replace(/\\/g, '/') | ||||
|     expect( | ||||
|       submodule2Content.indexOf(`includeIf.gitdir:${submodule2GitDir}.path`) | ||||
|     ).toBeGreaterThanOrEqual(0) | ||||
|     expect( | ||||
|       submodule2Content.indexOf(credentialsFilePath) | ||||
|     ).toBeGreaterThanOrEqual(0) | ||||
|  | ||||
|     // Verify both host and container paths are in each submodule config | ||||
|     const containerCredentialsPath = path.posix.join( | ||||
|       '/github/runner_temp', | ||||
|       path.basename(credentialsFilePath) | ||||
|     ) | ||||
|     expect( | ||||
|       submodule1Content.indexOf(containerCredentialsPath) | ||||
|     ).toBeGreaterThanOrEqual(0) | ||||
|     expect( | ||||
|       submodule2Content.indexOf(containerCredentialsPath) | ||||
|     ).toBeGreaterThanOrEqual(0) | ||||
|  | ||||
|     // Act - ensure mock persists for removeAuth | ||||
|     mockGetSubmoduleConfigPaths.mockResolvedValue([ | ||||
|       submodule1ConfigPath, | ||||
|       submodule2ConfigPath | ||||
|     ]) | ||||
|     await authHelper.removeAuth() | ||||
|  | ||||
|     // Assert submodule 1 includeIf entries removed | ||||
|     submodule1Content = ( | ||||
|       await fs.promises.readFile(submodule1ConfigPath) | ||||
|     ).toString() | ||||
|     expect(submodule1Content.indexOf('includeIf.gitdir:')).toBeLessThan(0) | ||||
|     expect(submodule1Content.indexOf(credentialsFilePath)).toBeLessThan(0) | ||||
|     expect(submodule1Content.indexOf(containerCredentialsPath)).toBeLessThan(0) | ||||
|  | ||||
|     // Assert submodule 2 includeIf entries removed | ||||
|     submodule2Content = ( | ||||
|       await fs.promises.readFile(submodule2ConfigPath) | ||||
|     ).toString() | ||||
|     expect(submodule2Content.indexOf('includeIf.gitdir:')).toBeLessThan(0) | ||||
|     expect(submodule2Content.indexOf(credentialsFilePath)).toBeLessThan(0) | ||||
|     expect(submodule2Content.indexOf(containerCredentialsPath)).toBeLessThan(0) | ||||
|  | ||||
|     // Assert credentials config file deleted | ||||
|     credentialsFiles = (await fs.promises.readdir(runnerTemp)).filter( | ||||
|       f => f.startsWith('git-credentials-') && f.endsWith('.config') | ||||
|     ) | ||||
|     expect(credentialsFiles.length).toBe(0) | ||||
|  | ||||
|     // Verify credentials file no longer exists on disk | ||||
|     try { | ||||
|       await fs.promises.stat(credentialsFilePath) | ||||
|       throw new Error('Credentials file should have been deleted') | ||||
|     } catch (err) { | ||||
|       if ((err as any)?.code !== 'ENOENT') { | ||||
|         throw err | ||||
|       } | ||||
|     } | ||||
|   }) | ||||
|  | ||||
|   const removeGlobalConfig_removesOverride = | ||||
| @@ -701,6 +928,52 @@ describe('git-auth-helper tests', () => { | ||||
|       } | ||||
|     } | ||||
|   }) | ||||
|  | ||||
|   const testCredentialsConfigPath_matchesCredentialsConfigPaths = | ||||
|     'testCredentialsConfigPath matches credentials config paths' | ||||
|   it(testCredentialsConfigPath_matchesCredentialsConfigPaths, async () => { | ||||
|     // Arrange | ||||
|     await setup(testCredentialsConfigPath_matchesCredentialsConfigPaths) | ||||
|     const authHelper = gitAuthHelper.createAuthHelper(git, settings) | ||||
|  | ||||
|     // Get a real credentials config path | ||||
|     const credentialsConfigPath = await ( | ||||
|       authHelper as any | ||||
|     ).getCredentialsConfigPath() | ||||
|  | ||||
|     // Act & Assert | ||||
|     expect( | ||||
|       (authHelper as any).testCredentialsConfigPath(credentialsConfigPath) | ||||
|     ).toBe(true) | ||||
|     expect( | ||||
|       (authHelper as any).testCredentialsConfigPath( | ||||
|         '/some/path/git-credentials-12345678-abcd-1234-5678-123456789012.config' | ||||
|       ) | ||||
|     ).toBe(true) | ||||
|     expect( | ||||
|       (authHelper as any).testCredentialsConfigPath( | ||||
|         '/some/path/git-credentials-abcdef12-3456-7890-abcd-ef1234567890.config' | ||||
|       ) | ||||
|     ).toBe(true) | ||||
|  | ||||
|     // Test invalid paths | ||||
|     expect( | ||||
|       (authHelper as any).testCredentialsConfigPath( | ||||
|         '/some/path/other-config.config' | ||||
|       ) | ||||
|     ).toBe(false) | ||||
|     expect( | ||||
|       (authHelper as any).testCredentialsConfigPath( | ||||
|         '/some/path/git-credentials-invalid.config' | ||||
|       ) | ||||
|     ).toBe(false) | ||||
|     expect( | ||||
|       (authHelper as any).testCredentialsConfigPath( | ||||
|         '/some/path/git-credentials-.config' | ||||
|       ) | ||||
|     ).toBe(false) | ||||
|     expect((authHelper as any).testCredentialsConfigPath('')).toBe(false) | ||||
|   }) | ||||
| }) | ||||
|  | ||||
| async function setup(testName: string): Promise<void> { | ||||
| @@ -715,6 +988,7 @@ async function setup(testName: string): Promise<void> { | ||||
|   await fs.promises.mkdir(tempHomedir, {recursive: true}) | ||||
|   process.env['RUNNER_TEMP'] = runnerTemp | ||||
|   process.env['HOME'] = tempHomedir | ||||
|   process.env['GITHUB_WORKSPACE'] = workspace | ||||
|  | ||||
|   // Create git config | ||||
|   globalGitConfigPath = path.join(tempHomedir, '.gitconfig') | ||||
| @@ -733,10 +1007,20 @@ async function setup(testName: string): Promise<void> { | ||||
|     checkout: jest.fn(), | ||||
|     checkoutDetach: jest.fn(), | ||||
|     config: jest.fn( | ||||
|       async (key: string, value: string, globalConfig?: boolean) => { | ||||
|         const configPath = globalConfig | ||||
|           ? path.join(git.env['HOME'] || tempHomedir, '.gitconfig') | ||||
|           : localGitConfigPath | ||||
|       async ( | ||||
|         key: string, | ||||
|         value: string, | ||||
|         globalConfig?: boolean, | ||||
|         add?: boolean, | ||||
|         configFile?: string | ||||
|       ) => { | ||||
|         const configPath = | ||||
|           configFile || | ||||
|           (globalConfig | ||||
|             ? path.join(git.env['HOME'] || tempHomedir, '.gitconfig') | ||||
|             : localGitConfigPath) | ||||
|         // Ensure directory exists | ||||
|         await fs.promises.mkdir(path.dirname(configPath), {recursive: true}) | ||||
|         await fs.promises.appendFile(configPath, `\n${key} ${value}`) | ||||
|       } | ||||
|     ), | ||||
| @@ -756,6 +1040,7 @@ async function setup(testName: string): Promise<void> { | ||||
|     env: {}, | ||||
|     fetch: jest.fn(), | ||||
|     getDefaultBranch: jest.fn(), | ||||
|     getSubmoduleConfigPaths: jest.fn(async () => []), | ||||
|     getWorkingDirectory: jest.fn(() => workspace), | ||||
|     init: jest.fn(), | ||||
|     isDetached: jest.fn(), | ||||
| @@ -794,8 +1079,72 @@ async function setup(testName: string): Promise<void> { | ||||
|         return true | ||||
|       } | ||||
|     ), | ||||
|     tryConfigUnsetValue: jest.fn( | ||||
|       async ( | ||||
|         key: string, | ||||
|         value: string, | ||||
|         globalConfig?: boolean, | ||||
|         configPath?: string | ||||
|       ): Promise<boolean> => { | ||||
|         const targetConfigPath = | ||||
|           configPath || | ||||
|           (globalConfig | ||||
|             ? path.join(git.env['HOME'] || tempHomedir, '.gitconfig') | ||||
|             : localGitConfigPath) | ||||
|         let content = await fs.promises.readFile(targetConfigPath) | ||||
|         let lines = content | ||||
|           .toString() | ||||
|           .split('\n') | ||||
|           .filter(x => x) | ||||
|           .filter(x => !(x.startsWith(key) && x.includes(value))) | ||||
|         await fs.promises.writeFile(targetConfigPath, lines.join('\n')) | ||||
|         return true | ||||
|       } | ||||
|     ), | ||||
|     tryDisableAutomaticGarbageCollection: jest.fn(), | ||||
|     tryGetFetchUrl: jest.fn(), | ||||
|     tryGetConfigValues: jest.fn( | ||||
|       async ( | ||||
|         key: string, | ||||
|         globalConfig?: boolean, | ||||
|         configPath?: string | ||||
|       ): Promise<string[]> => { | ||||
|         const targetConfigPath = | ||||
|           configPath || | ||||
|           (globalConfig | ||||
|             ? path.join(git.env['HOME'] || tempHomedir, '.gitconfig') | ||||
|             : localGitConfigPath) | ||||
|         const content = await fs.promises.readFile(targetConfigPath) | ||||
|         const lines = content | ||||
|           .toString() | ||||
|           .split('\n') | ||||
|           .filter(x => x && x.startsWith(key)) | ||||
|           .map(x => x.substring(key.length).trim()) | ||||
|         return lines | ||||
|       } | ||||
|     ), | ||||
|     tryGetConfigKeys: jest.fn( | ||||
|       async ( | ||||
|         pattern: string, | ||||
|         globalConfig?: boolean, | ||||
|         configPath?: string | ||||
|       ): Promise<string[]> => { | ||||
|         const targetConfigPath = | ||||
|           configPath || | ||||
|           (globalConfig | ||||
|             ? path.join(git.env['HOME'] || tempHomedir, '.gitconfig') | ||||
|             : localGitConfigPath) | ||||
|         const content = await fs.promises.readFile(targetConfigPath) | ||||
|         const lines = content | ||||
|           .toString() | ||||
|           .split('\n') | ||||
|           .filter(x => x) | ||||
|         const keys = lines | ||||
|           .filter(x => new RegExp(pattern).test(x.split(' ')[0])) | ||||
|           .map(x => x.split(' ')[0]) | ||||
|         return [...new Set(keys)] // Remove duplicates | ||||
|       } | ||||
|     ), | ||||
|     tryReset: jest.fn(), | ||||
|     version: jest.fn() | ||||
|   } | ||||
| @@ -830,6 +1179,7 @@ async function setup(testName: string): Promise<void> { | ||||
|  | ||||
| async function getActualSshKeyPath(): Promise<string> { | ||||
|   let actualTempFiles = (await fs.promises.readdir(runnerTemp)) | ||||
|     .filter(x => !x.startsWith('git-credentials-')) // Exclude credentials config file | ||||
|     .sort() | ||||
|     .map(x => path.join(runnerTemp, x)) | ||||
|   if (actualTempFiles.length === 0) { | ||||
| @@ -843,6 +1193,7 @@ async function getActualSshKeyPath(): Promise<string> { | ||||
|  | ||||
| async function getActualSshKnownHostsPath(): Promise<string> { | ||||
|   let actualTempFiles = (await fs.promises.readdir(runnerTemp)) | ||||
|     .filter(x => !x.startsWith('git-credentials-')) // Exclude credentials config file | ||||
|     .sort() | ||||
|     .map(x => path.join(runnerTemp, x)) | ||||
|   if (actualTempFiles.length === 0) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 eric sciple
					eric sciple