diff --git a/__test__/git-auth-helper.test.ts b/__test__/git-auth-helper.test.ts index 2acec38..c2db8e6 100644 --- a/__test__/git-auth-helper.test.ts +++ b/__test__/git-auth-helper.test.ts @@ -297,6 +297,41 @@ describe('git-auth-helper tests', () => { ) }) + const configureAuth_setsSshCommandWithCustomCommand = + 'sets SSH command preseving custom command' + it(configureAuth_setsSshCommandWithCustomCommand, async () => { + // Arrange + await setup(configureAuth_setsSshCommandWithCustomCommand) + await fs.promises.writeFile(globalGitConfigPath, 'core.sshCommand fakeSsh') + expect(await git.configExists('core.sshCommand', true)).toBeTruthy() // sanity check + expect(await git.configGet('core.sshCommand', true)).toBe('fakeSsh') // sanity check + + const authHelper = gitAuthHelper.createAuthHelper(git, settings) + + // Act + await authHelper.configureAuth() + expect(git.configGet).toHaveBeenCalledWith('core.sshCommand', true) + + // Assert git env var + const actualKeyPath = await getActualSshKeyPath() + const actualKnownHostsPath = await getActualSshKnownHostsPath() + const expectedSshCommand = `"fakeSsh" -i "$RUNNER_TEMP/${path.basename( + actualKeyPath + )}" -o StrictHostKeyChecking=yes -o CheckHostIP=no -o "UserKnownHostsFile=$RUNNER_TEMP/${path.basename( + actualKnownHostsPath + )}"` + expect(git.setEnvironmentVariable).toHaveBeenCalledWith( + 'GIT_SSH_COMMAND', + expectedSshCommand + ) + + // Asserty git config + expect(git.config).toHaveBeenCalledWith( + 'core.sshCommand', + expectedSshCommand + ) + }) + const configureAuth_writesExplicitKnownHosts = 'writes explicit known hosts' it(configureAuth_writesExplicitKnownHosts, async () => { if (!sshPath) { @@ -739,15 +774,47 @@ async function setup(testName: string): Promise { ), configExists: jest.fn( async (key: string, globalConfig?: boolean): Promise => { - const configPath = globalConfig - ? path.join(git.env['HOME'] || tempHomedir, '.gitconfig') - : localGitConfigPath - const content = await fs.promises.readFile(configPath) - const lines = content - .toString() - .split('\n') - .filter(x => x) - return lines.some(x => x.startsWith(key)) + try { + const configPath = globalConfig + ? path.join(git.env['HOME'] || tempHomedir, '.gitconfig') + : localGitConfigPath + const content = await fs.promises.readFile(configPath) + const lines = content + .toString() + .split('\n') + .filter(x => x) + return lines.some(x => x.startsWith(key)) + } catch (error) { + if ((error as any)?.code === 'ENOENT') { + return false + } + throw error + } + } + ), + configGet: jest.fn( + async (key: string, globalConfig?: boolean): Promise => { + try { + const configPath = globalConfig + ? path.join(git.env['HOME'] || tempHomedir, '.gitconfig') + : localGitConfigPath + const content = await fs.promises.readFile(configPath) + const lines = content + .toString() + .split('\n') + .filter(x => x) + .filter(x => x.startsWith(key)) + if (lines.length) { + return lines[0].split(' ')[1] + } else { + return '' + } + } catch (error) { + if ((error as any)?.code === 'ENOENT') { + return '' + } + throw error + } } ), env: {}, diff --git a/__test__/git-directory-helper.test.ts b/__test__/git-directory-helper.test.ts index 70849b5..25b1244 100644 --- a/__test__/git-directory-helper.test.ts +++ b/__test__/git-directory-helper.test.ts @@ -407,6 +407,7 @@ async function setup(testName: string): Promise { checkoutDetach: jest.fn(), config: jest.fn(), configExists: jest.fn(), + configGet: jest.fn(), fetch: jest.fn(), getDefaultBranch: jest.fn(), getWorkingDirectory: jest.fn(() => repositoryPath), diff --git a/dist/index.js b/dist/index.js index 0a33ea1..ec21012 100644 --- a/dist/index.js +++ b/dist/index.js @@ -7253,7 +7253,9 @@ class GitAuthHelper { stateHelper.setSshKnownHostsPath(this.sshKnownHostsPath); yield fs.promises.writeFile(this.sshKnownHostsPath, knownHosts); // Configure GIT_SSH_COMMAND - const sshPath = yield io.which('ssh', true); + const sshPath = (yield this.git.configExists(SSH_COMMAND_KEY, true)) + ? yield this.git.configGet(SSH_COMMAND_KEY, true) + : yield io.which('ssh', true); this.sshCommand = `"${sshPath}" -i "$RUNNER_TEMP/${path.basename(this.sshKeyPath)}"`; if (this.settings.sshStrict) { this.sshCommand += ' -o StrictHostKeyChecking=yes -o CheckHostIP=no'; @@ -7533,6 +7535,16 @@ class GitCommandManager { return output.exitCode === 0; }); } + configGet(configKey, globalConfig) { + return __awaiter(this, void 0, void 0, function* () { + const output = yield this.execGit([ + 'config', + globalConfig ? '--global' : '--local', + configKey + ]); + return output.stdout.trim(); + }); + } fetch(refSpec, fetchDepth) { return __awaiter(this, void 0, void 0, function* () { const args = ['-c', 'protocol.version=2', 'fetch']; diff --git a/src/git-auth-helper.ts b/src/git-auth-helper.ts index 6e3ad28..484d1ff 100644 --- a/src/git-auth-helper.ts +++ b/src/git-auth-helper.ts @@ -253,7 +253,9 @@ class GitAuthHelper { await fs.promises.writeFile(this.sshKnownHostsPath, knownHosts) // Configure GIT_SSH_COMMAND - const sshPath = await io.which('ssh', true) + const sshPath = (await this.git.configExists(SSH_COMMAND_KEY, true)) + ? await this.git.configGet(SSH_COMMAND_KEY, true) + : await io.which('ssh', true) this.sshCommand = `"${sshPath}" -i "$RUNNER_TEMP/${path.basename( this.sshKeyPath )}"` diff --git a/src/git-command-manager.ts b/src/git-command-manager.ts index 01aedfe..59e6298 100644 --- a/src/git-command-manager.ts +++ b/src/git-command-manager.ts @@ -26,6 +26,7 @@ export interface IGitCommandManager { ): Promise configExists(configKey: string, globalConfig?: boolean): Promise fetch(refSpec: string[], fetchDepth?: number): Promise + configGet(configKey: string, globalConfig?: boolean): Promise getDefaultBranch(repositoryUrl: string): Promise getWorkingDirectory(): string init(): Promise @@ -201,6 +202,15 @@ class GitCommandManager { return output.exitCode === 0 } + async configGet(configKey: string, globalConfig?: boolean): Promise { + const output = await this.execGit([ + 'config', + globalConfig ? '--global' : '--local', + configKey + ]) + return output.stdout.trim() + } + async fetch(refSpec: string[], fetchDepth?: number): Promise { const args = ['-c', 'protocol.version=2', 'fetch'] if (!refSpec.some(x => x === refHelper.tagsRefSpec)) {