Skip to content
Navigation Menu
Toggle navigation
Sign in
In this repository
All GitHub Enterprise
↵
Jump to
↵
No suggested jump to results
In this repository
All GitHub Enterprise
↵
Jump to
↵
In this organization
All GitHub Enterprise
↵
Jump to
↵
In this repository
All GitHub Enterprise
↵
Jump to
↵
Sign in
Reseting focus
You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
Dismiss alert
{{ message }}
actions
/
checkout
Public
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Issues
0
Pull requests
0
Actions
Projects
0
Security
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Projects
Security
Insights
Files
1d96c77
.github
.licenses
__test__
git-auth-helper.test.ts
git-command-manager.test.ts
git-directory-helper.test.ts
git-version.test.ts
input-helper.test.ts
modify-work-tree.sh
override-git-version.cmd
override-git-version.sh
ref-helper.test.ts
retry-helper.test.ts
verify-basic.sh
verify-clean.sh
verify-fetch-filter.sh
verify-lfs.sh
verify-no-unstaged-changes.sh
verify-side-by-side.sh
verify-sparse-checkout-non-cone-mode.sh
verify-sparse-checkout.sh
verify-submodules-false.sh
verify-submodules-recursive.sh
verify-submodules-true.sh
adrs
dist
images
src
.eslintignore
.eslintrc.json
.gitattributes
.gitignore
.licensed.yml
.prettierignore
.prettierrc.json
CHANGELOG.md
CODEOWNERS
CONTRIBUTING.md
LICENSE
README.md
action.yml
jest.config.js
package-lock.json
package.json
tsconfig.json
Breadcrumbs
checkout
/
__test__
/
git-auth-helper.test.ts
Blame
Blame
Latest commit
History
History
856 lines (763 loc) · 27.8 KB
Breadcrumbs
checkout
/
__test__
/
git-auth-helper.test.ts
Top
File metadata and controls
Code
Blame
856 lines (763 loc) · 27.8 KB
Raw
import * as core from '@actions/core' import * as fs from 'fs' import * as gitAuthHelper from '../lib/git-auth-helper' import * as io from '@actions/io' import * as os from 'os' import * as path from 'path' import * as stateHelper from '../lib/state-helper' import {IGitCommandManager} from '../lib/git-command-manager' import {IGitSourceSettings} from '../lib/git-source-settings' const isWindows = process.platform === 'win32' const testWorkspace = path.join(__dirname, '_temp', 'git-auth-helper') const originalRunnerTemp = process.env['RUNNER_TEMP'] const originalHome = process.env['HOME'] let workspace: string let localGitConfigPath: string let globalGitConfigPath: string let runnerTemp: string let tempHomedir: string let git: IGitCommandManager & {env: {[key: string]: string}} let settings: IGitSourceSettings let sshPath: string let githubServerUrl: string describe('git-auth-helper tests', () => { beforeAll(async () => { // SSH sshPath = await io.which('ssh') // Clear test workspace await io.rmRF(testWorkspace) }) beforeEach(() => { // Mock setSecret jest.spyOn(core, 'setSecret').mockImplementation((secret: string) => {}) // Mock error/warning/info/debug jest.spyOn(core, 'error').mockImplementation(jest.fn()) jest.spyOn(core, 'warning').mockImplementation(jest.fn()) jest.spyOn(core, 'info').mockImplementation(jest.fn()) jest.spyOn(core, 'debug').mockImplementation(jest.fn()) // Mock state helper jest.spyOn(stateHelper, 'setSshKeyPath').mockImplementation(jest.fn()) jest .spyOn(stateHelper, 'setSshKnownHostsPath') .mockImplementation(jest.fn()) }) afterEach(() => { // Unregister mocks jest.restoreAllMocks() // Restore HOME if (originalHome) { process.env['HOME'] = originalHome } else { delete process.env['HOME'] } }) afterAll(() => { // Restore RUNNER_TEMP delete process.env['RUNNER_TEMP'] if (originalRunnerTemp) { process.env['RUNNER_TEMP'] = originalRunnerTemp } }) async function testAuthHeader( testName: string, serverUrl: string | undefined = undefined ) { // Arrange let expectedServerUrl = 'https://github.com' if (serverUrl) { githubServerUrl = serverUrl expectedServerUrl = githubServerUrl } await setup(testName) expect(settings.authToken).toBeTruthy() // sanity check const authHelper = gitAuthHelper.createAuthHelper(git, settings) // Act await authHelper.configureAuth() // Assert config const configContent = ( await fs.promises.readFile(localGitConfigPath) ).toString() const basicCredential = Buffer.from( `x-access-token:${settings.authToken}`, 'utf8' ).toString('base64') expect( configContent.indexOf( `http.${expectedServerUrl}/.extraheader AUTHORIZATION: basic ${basicCredential}` ) ).toBeGreaterThanOrEqual(0) } const configureAuth_configuresAuthHeader = 'configureAuth configures auth header' it(configureAuth_configuresAuthHeader, async () => { await testAuthHeader(configureAuth_configuresAuthHeader) }) const configureAuth_AcceptsGitHubServerUrl = 'inject https://my-ghes-server.com as github server url' it(configureAuth_AcceptsGitHubServerUrl, async () => { await testAuthHeader( configureAuth_AcceptsGitHubServerUrl, 'https://my-ghes-server.com' ) }) const configureAuth_AcceptsGitHubServerUrlSetToGHEC = 'inject https://github.com as github server url' it(configureAuth_AcceptsGitHubServerUrlSetToGHEC, async () => { await testAuthHeader( configureAuth_AcceptsGitHubServerUrl, 'https://github.com' ) }) const configureAuth_configuresAuthHeaderEvenWhenPersistCredentialsFalse = 'configureAuth configures auth header even when persist credentials false' it( configureAuth_configuresAuthHeaderEvenWhenPersistCredentialsFalse, async () => { // Arrange await setup( configureAuth_configuresAuthHeaderEvenWhenPersistCredentialsFalse ) expect(settings.authToken).toBeTruthy() // sanity check settings.persistCredentials = false const authHelper = gitAuthHelper.createAuthHelper(git, settings) // Act await authHelper.configureAuth() // Assert config const configContent = ( await fs.promises.readFile(localGitConfigPath) ).toString() expect( configContent.indexOf( `http.https://github.com/.extraheader AUTHORIZATION` ) ).toBeGreaterThanOrEqual(0) } ) const configureAuth_copiesUserKnownHosts = 'configureAuth copies user known hosts' it(configureAuth_copiesUserKnownHosts, async () => { if (!sshPath) { process.stdout.write( `Skipped test "${configureAuth_copiesUserKnownHosts}". Executable 'ssh' not found in the PATH.\n` ) return } // Arange await setup(configureAuth_copiesUserKnownHosts) expect(settings.sshKey).toBeTruthy() // sanity check // Mock fs.promises.readFile const realReadFile = fs.promises.readFile jest.spyOn(fs.promises, 'readFile').mockImplementation( async (file: any, options: any): Promise<Buffer> => { const userKnownHostsPath = path.join( os.homedir(), '.ssh', 'known_hosts' ) if (file === userKnownHostsPath) { return Buffer.from('some-domain.com ssh-rsa ABCDEF') } return await realReadFile(file, options) } ) // Act const authHelper = gitAuthHelper.createAuthHelper(git, settings) await authHelper.configureAuth() // Assert known hosts const actualSshKnownHostsPath = await getActualSshKnownHostsPath() const actualSshKnownHostsContent = ( await fs.promises.readFile(actualSshKnownHostsPath) ).toString() expect(actualSshKnownHostsContent).toMatch( /some-domain\.com ssh-rsa ABCDEF/ ) expect(actualSshKnownHostsContent).toMatch(/github\.com ssh-rsa AAAAB3N/) }) const configureAuth_registersBasicCredentialAsSecret = 'configureAuth registers basic credential as secret' it(configureAuth_registersBasicCredentialAsSecret, async () => { // Arrange await setup(configureAuth_registersBasicCredentialAsSecret) expect(settings.authToken).toBeTruthy() // sanity check const authHelper = gitAuthHelper.createAuthHelper(git, settings) // Act await authHelper.configureAuth() // Assert secret const setSecretSpy = core.setSecret as jest.Mock<any, any> expect(setSecretSpy).toHaveBeenCalledTimes(1) const expectedSecret = Buffer.from( `x-access-token:${settings.authToken}`, 'utf8' ).toString('base64') expect(setSecretSpy).toHaveBeenCalledWith(expectedSecret) }) const setsSshCommandEnvVarWhenPersistCredentialsFalse = 'sets SSH command env var when persist-credentials false' it(setsSshCommandEnvVarWhenPersistCredentialsFalse, async () => { if (!sshPath) { process.stdout.write( `Skipped test "${setsSshCommandEnvVarWhenPersistCredentialsFalse}". Executable 'ssh' not found in the PATH.\n` ) return } // Arrange await setup(setsSshCommandEnvVarWhenPersistCredentialsFalse) settings.persistCredentials = false const authHelper = gitAuthHelper.createAuthHelper(git, settings) // Act await authHelper.configureAuth() // Assert git env var const actualKeyPath = await getActualSshKeyPath() const actualKnownHostsPath = await getActualSshKnownHostsPath() const expectedSshCommand = `"${sshPath}" -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 const gitConfigLines = (await fs.promises.readFile(localGitConfigPath)) .toString() .split('\n') .filter(x => x) expect(gitConfigLines).toHaveLength(1) expect(gitConfigLines[0]).toMatch(/^http\./) }) const configureAuth_setsSshCommandWhenPersistCredentialsTrue = 'sets SSH command when persist-credentials true' it(configureAuth_setsSshCommandWhenPersistCredentialsTrue, async () => { if (!sshPath) { process.stdout.write( `Skipped test "${configureAuth_setsSshCommandWhenPersistCredentialsTrue}". Executable 'ssh' not found in the PATH.\n` ) return } // Arrange await setup(configureAuth_setsSshCommandWhenPersistCredentialsTrue) const authHelper = gitAuthHelper.createAuthHelper(git, settings) // Act await authHelper.configureAuth() // Assert git env var const actualKeyPath = await getActualSshKeyPath() const actualKnownHostsPath = await getActualSshKnownHostsPath() const expectedSshCommand = `"${sshPath}" -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) { process.stdout.write( `Skipped test "${configureAuth_writesExplicitKnownHosts}". Executable 'ssh' not found in the PATH.\n` ) return } // Arrange await setup(configureAuth_writesExplicitKnownHosts) expect(settings.sshKey).toBeTruthy() // sanity check settings.sshKnownHosts = 'my-custom-host.com ssh-rsa ABC123' const authHelper = gitAuthHelper.createAuthHelper(git, settings) // Act await authHelper.configureAuth() // Assert known hosts const actualSshKnownHostsPath = await getActualSshKnownHostsPath() const actualSshKnownHostsContent = ( await fs.promises.readFile(actualSshKnownHostsPath) ).toString() expect(actualSshKnownHostsContent).toMatch( /my-custom-host\.com ssh-rsa ABC123/ ) expect(actualSshKnownHostsContent).toMatch(/github\.com ssh-rsa AAAAB3N/) }) const configureAuth_writesSshKeyAndImplicitKnownHosts = 'writes SSH key and implicit known hosts' it(configureAuth_writesSshKeyAndImplicitKnownHosts, async () => { if (!sshPath) { process.stdout.write( `Skipped test "${configureAuth_writesSshKeyAndImplicitKnownHosts}". Executable 'ssh' not found in the PATH.\n` ) return } // Arrange await setup(configureAuth_writesSshKeyAndImplicitKnownHosts) expect(settings.sshKey).toBeTruthy() // sanity check const authHelper = gitAuthHelper.createAuthHelper(git, settings) // Act await authHelper.configureAuth() // Assert SSH key const actualSshKeyPath = await getActualSshKeyPath() expect(actualSshKeyPath).toBeTruthy() const actualSshKeyContent = ( await fs.promises.readFile(actualSshKeyPath) ).toString() expect(actualSshKeyContent).toBe(settings.sshKey + '\n') if (!isWindows) { // Assert read/write for user, not group or others. // Otherwise SSH client will error. expect((await fs.promises.stat(actualSshKeyPath)).mode & 0o777).toBe( 0o600 ) } // Assert known hosts const actualSshKnownHostsPath = await getActualSshKnownHostsPath() const actualSshKnownHostsContent = ( await fs.promises.readFile(actualSshKnownHostsPath) ).toString() expect(actualSshKnownHostsContent).toMatch(/github\.com ssh-rsa AAAAB3N/) }) const configureGlobalAuth_configuresUrlInsteadOfWhenSshKeyNotSet = 'configureGlobalAuth configures URL insteadOf when SSH key not set' it(configureGlobalAuth_configuresUrlInsteadOfWhenSshKeyNotSet, async () => { // Arrange await setup(configureGlobalAuth_configuresUrlInsteadOfWhenSshKeyNotSet) settings.sshKey = '' const authHelper = gitAuthHelper.createAuthHelper(git, settings) // Act await authHelper.configureAuth() await authHelper.configureGlobalAuth() // Assert temporary global config expect(git.env['HOME']).toBeTruthy() const configContent = ( await fs.promises.readFile(path.join(git.env['HOME'], '.gitconfig')) ).toString() expect( configContent.indexOf(`url.https://github.com/.insteadOf git@github.com`) ).toBeGreaterThanOrEqual(0) }) const configureGlobalAuth_copiesGlobalGitConfig = 'configureGlobalAuth copies global git config' it(configureGlobalAuth_copiesGlobalGitConfig, async () => { // Arrange await setup(configureGlobalAuth_copiesGlobalGitConfig) await fs.promises.writeFile(globalGitConfigPath, 'value-from-global-config') const authHelper = gitAuthHelper.createAuthHelper(git, settings) // Act await authHelper.configureAuth() await authHelper.configureGlobalAuth() // Assert original global config not altered let configContent = ( await fs.promises.readFile(globalGitConfigPath) ).toString() expect(configContent).toBe('value-from-global-config') // Assert temporary global config expect(git.env['HOME']).toBeTruthy() const basicCredential = Buffer.from( `x-access-token:${settings.authToken}`, 'utf8' ).toString('base64') configContent = ( await fs.promises.readFile(path.join(git.env['HOME'], '.gitconfig')) ).toString() expect( configContent.indexOf('value-from-global-config') ).toBeGreaterThanOrEqual(0) expect( configContent.indexOf( `http.https://github.com/.extraheader AUTHORIZATION: basic ${basicCredential}` ) ).toBeGreaterThanOrEqual(0) }) const configureGlobalAuth_createsNewGlobalGitConfigWhenGlobalDoesNotExist = 'configureGlobalAuth creates new git config when global does not exist' it( configureGlobalAuth_createsNewGlobalGitConfigWhenGlobalDoesNotExist, async () => { // Arrange await setup( configureGlobalAuth_createsNewGlobalGitConfigWhenGlobalDoesNotExist ) await io.rmRF(globalGitConfigPath) const authHelper = gitAuthHelper.createAuthHelper(git, settings) // Act await authHelper.configureAuth() await authHelper.configureGlobalAuth() // Assert original global config not recreated try { await fs.promises.stat(globalGitConfigPath) throw new Error( `Did not expect file to exist: '${globalGitConfigPath}'` ) } catch (err) { if ((err as any)?.code !== 'ENOENT') { throw err } } // Assert temporary global config expect(git.env['HOME']).toBeTruthy() const basicCredential = Buffer.from( `x-access-token:${settings.authToken}`, 'utf8' ).toString('base64') const configContent = ( await fs.promises.readFile(path.join(git.env['HOME'], '.gitconfig')) ).toString() expect( configContent.indexOf( `http.https://github.com/.extraheader AUTHORIZATION: basic ${basicCredential}` ) ).toBeGreaterThanOrEqual(0) } ) const configureSubmoduleAuth_configuresSubmodulesWhenPersistCredentialsFalseAndSshKeyNotSet = 'configureSubmoduleAuth configures submodules when persist credentials false and SSH key not set' it( configureSubmoduleAuth_configuresSubmodulesWhenPersistCredentialsFalseAndSshKeyNotSet, async () => { // Arrange await setup( configureSubmoduleAuth_configuresSubmodulesWhenPersistCredentialsFalseAndSshKeyNotSet ) settings.persistCredentials = false settings.sshKey = '' const authHelper = gitAuthHelper.createAuthHelper(git, settings) await authHelper.configureAuth() const mockSubmoduleForeach = git.submoduleForeach as jest.Mock<any, any> mockSubmoduleForeach.mockClear() // reset calls // Act await authHelper.configureSubmoduleAuth() // Assert expect(mockSubmoduleForeach).toBeCalledTimes(1) expect(mockSubmoduleForeach.mock.calls[0][0] as string).toMatch( /unset-all.*insteadOf/ ) } ) const configureSubmoduleAuth_configuresSubmodulesWhenPersistCredentialsFalseAndSshKeySet = 'configureSubmoduleAuth configures submodules when persist credentials false and SSH key set' it( configureSubmoduleAuth_configuresSubmodulesWhenPersistCredentialsFalseAndSshKeySet, async () => { if (!sshPath) { process.stdout.write( `Skipped test "${configureSubmoduleAuth_configuresSubmodulesWhenPersistCredentialsFalseAndSshKeySet}". Executable 'ssh' not found in the PATH.\n` ) return } // Arrange await setup( configureSubmoduleAuth_configuresSubmodulesWhenPersistCredentialsFalseAndSshKeySet ) settings.persistCredentials = false const authHelper = gitAuthHelper.createAuthHelper(git, settings) await authHelper.configureAuth() const mockSubmoduleForeach = git.submoduleForeach as jest.Mock<any, any> mockSubmoduleForeach.mockClear() // reset calls // Act await authHelper.configureSubmoduleAuth() // Assert expect(mockSubmoduleForeach).toHaveBeenCalledTimes(1) expect(mockSubmoduleForeach.mock.calls[0][0]).toMatch( /unset-all.*insteadOf/ ) } ) const configureSubmoduleAuth_configuresSubmodulesWhenPersistCredentialsTrueAndSshKeyNotSet = 'configureSubmoduleAuth configures submodules when persist credentials true and SSH key not set' it( configureSubmoduleAuth_configuresSubmodulesWhenPersistCredentialsTrueAndSshKeyNotSet, async () => { // Arrange await setup( configureSubmoduleAuth_configuresSubmodulesWhenPersistCredentialsTrueAndSshKeyNotSet ) settings.sshKey = '' const authHelper = gitAuthHelper.createAuthHelper(git, settings) await authHelper.configureAuth() const mockSubmoduleForeach = git.submoduleForeach as jest.Mock<any, any> mockSubmoduleForeach.mockClear() // reset calls // Act await authHelper.configureSubmoduleAuth() // Assert expect(mockSubmoduleForeach).toHaveBeenCalledTimes(4) 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( /url.*insteadOf.*git@github.com:/ ) expect(mockSubmoduleForeach.mock.calls[3][0]).toMatch( /url.*insteadOf.*org-123456@github.com:/ ) } ) const configureSubmoduleAuth_configuresSubmodulesWhenPersistCredentialsTrueAndSshKeySet = 'configureSubmoduleAuth configures submodules when persist credentials true and SSH key set' it( configureSubmoduleAuth_configuresSubmodulesWhenPersistCredentialsTrueAndSshKeySet, async () => { if (!sshPath) { process.stdout.write( `Skipped test "${configureSubmoduleAuth_configuresSubmodulesWhenPersistCredentialsTrueAndSshKeySet}". Executable 'ssh' not found in the PATH.\n` ) return } // Arrange await setup( configureSubmoduleAuth_configuresSubmodulesWhenPersistCredentialsTrueAndSshKeySet ) const authHelper = gitAuthHelper.createAuthHelper(git, settings) await authHelper.configureAuth() const mockSubmoduleForeach = git.submoduleForeach as jest.Mock<any, any> mockSubmoduleForeach.mockClear() // reset calls // Act await authHelper.configureSubmoduleAuth() // Assert 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(/core\.sshCommand/) } ) const removeAuth_removesSshCommand = 'removeAuth removes SSH command' it(removeAuth_removesSshCommand, async () => { if (!sshPath) { process.stdout.write( `Skipped test "${removeAuth_removesSshCommand}". Executable 'ssh' not found in the PATH.\n` ) return } // Arrange await setup(removeAuth_removesSshCommand) const authHelper = gitAuthHelper.createAuthHelper(git, settings) await authHelper.configureAuth() let gitConfigContent = ( await fs.promises.readFile(localGitConfigPath) ).toString() expect(gitConfigContent.indexOf('core.sshCommand')).toBeGreaterThanOrEqual( 0 ) // sanity check const actualKeyPath = await getActualSshKeyPath() expect(actualKeyPath).toBeTruthy() await fs.promises.stat(actualKeyPath) const actualKnownHostsPath = await getActualSshKnownHostsPath() expect(actualKnownHostsPath).toBeTruthy() await fs.promises.stat(actualKnownHostsPath) // Act await authHelper.removeAuth() // Assert git config gitConfigContent = ( await fs.promises.readFile(localGitConfigPath) ).toString() expect(gitConfigContent.indexOf('core.sshCommand')).toBeLessThan(0) // Assert SSH key file try { await fs.promises.stat(actualKeyPath) throw new Error('SSH key should have been deleted') } catch (err) { if ((err as any)?.code !== 'ENOENT') { throw err } } // Assert known hosts file try { await fs.promises.stat(actualKnownHostsPath) throw new Error('SSH known hosts should have been deleted') } catch (err) { if ((err as any)?.code !== 'ENOENT') { throw err } } }) const removeAuth_removesToken = 'removeAuth removes token' it(removeAuth_removesToken, async () => { // Arrange await setup(removeAuth_removesToken) const authHelper = gitAuthHelper.createAuthHelper(git, settings) await authHelper.configureAuth() let gitConfigContent = ( await fs.promises.readFile(localGitConfigPath) ).toString() expect(gitConfigContent.indexOf('http.')).toBeGreaterThanOrEqual(0) // sanity check // Act await authHelper.removeAuth() // Assert git config gitConfigContent = ( await fs.promises.readFile(localGitConfigPath) ).toString() expect(gitConfigContent.indexOf('http.')).toBeLessThan(0) }) const removeGlobalConfig_removesOverride = 'removeGlobalConfig removes override' it(removeGlobalConfig_removesOverride, async () => { // Arrange await setup(removeGlobalConfig_removesOverride) const authHelper = gitAuthHelper.createAuthHelper(git, settings) await authHelper.configureAuth() await authHelper.configureGlobalAuth() const homeOverride = git.env['HOME'] // Sanity check expect(homeOverride).toBeTruthy() await fs.promises.stat(path.join(git.env['HOME'], '.gitconfig')) // Act await authHelper.removeGlobalConfig() // Assert expect(git.env['HOME']).toBeUndefined() try { await fs.promises.stat(homeOverride) throw new Error(`Should have been deleted '${homeOverride}'`) } catch (err) { if ((err as any)?.code !== 'ENOENT') { throw err } } }) }) async function setup(testName: string): Promise<void> { testName = testName.replace(/[^a-zA-Z0-9_]+/g, '-') // Directories workspace = path.join(testWorkspace, testName, 'workspace') runnerTemp = path.join(testWorkspace, testName, 'runner-temp') tempHomedir = path.join(testWorkspace, testName, 'home-dir') await fs.promises.mkdir(workspace, {recursive: true}) await fs.promises.mkdir(runnerTemp, {recursive: true}) await fs.promises.mkdir(tempHomedir, {recursive: true}) process.env['RUNNER_TEMP'] = runnerTemp process.env['HOME'] = tempHomedir // Create git config globalGitConfigPath = path.join(tempHomedir, '.gitconfig') await fs.promises.writeFile(globalGitConfigPath, '') localGitConfigPath = path.join(workspace, '.git', 'config') await fs.promises.mkdir(path.dirname(localGitConfigPath), {recursive: true}) await fs.promises.writeFile(localGitConfigPath, '') git = { branchDelete: jest.fn(), branchExists: jest.fn(), branchList: jest.fn(), disableSparseCheckout: jest.fn(), sparseCheckout: jest.fn(), sparseCheckoutNonConeMode: jest.fn(), 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 await fs.promises.appendFile(configPath, `\n${key} ${value}`) } ), configExists: jest.fn( async (key: string, globalConfig?: boolean): Promise<boolean> => { 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)) } ), env: {}, fetch: jest.fn(), getDefaultBranch: jest.fn(), getWorkingDirectory: jest.fn(() => workspace), init: jest.fn(), isDetached: jest.fn(), lfsFetch: jest.fn(), lfsInstall: jest.fn(), log1: jest.fn(), remoteAdd: jest.fn(), removeEnvironmentVariable: jest.fn((name: string) => delete git.env[name]), revParse: jest.fn(), setEnvironmentVariable: jest.fn((name: string, value: string) => { git.env[name] = value }), shaExists: jest.fn(), submoduleForeach: jest.fn(async () => { return '' }), submoduleSync: jest.fn(), submoduleStatus: jest.fn(async () => { return true }), submoduleUpdate: jest.fn(), tagExists: jest.fn(), tryClean: jest.fn(), tryConfigUnset: jest.fn( async (key: string, globalConfig?: boolean): Promise<boolean> => { const configPath = globalConfig ? path.join(git.env['HOME'] || tempHomedir, '.gitconfig') : localGitConfigPath let content = await fs.promises.readFile(configPath) let lines = content .toString() .split('\n') .filter(x => x) .filter(x => !x.startsWith(key)) await fs.promises.writeFile(configPath, lines.join('\n')) return true } ), tryDisableAutomaticGarbageCollection: jest.fn(), tryGetFetchUrl: jest.fn(), tryReset: jest.fn(), version: jest.fn() } settings = { authToken: 'some auth token', clean: true, commit: '', filter: undefined, sparseCheckout: [], sparseCheckoutConeMode: true, fetchDepth: 1, fetchTags: false, showProgress: true, lfs: false, submodules: false, nestedSubmodules: false, persistCredentials: true, ref: 'refs/heads/main', repositoryName: 'my-repo', repositoryOwner: 'my-org', repositoryPath: '', sshKey: sshPath ? 'some ssh private key' : '', sshKnownHosts: '', sshStrict: true, sshUser: '', workflowOrganizationId: 123456, setSafeDirectory: true, githubServerUrl: githubServerUrl } } async function getActualSshKeyPath(): Promise<string> { let actualTempFiles = (await fs.promises.readdir(runnerTemp)) .sort() .map(x => path.join(runnerTemp, x)) if (actualTempFiles.length === 0) { return '' } expect(actualTempFiles).toHaveLength(2) expect(actualTempFiles[0].endsWith('_known_hosts')).toBeFalsy() return actualTempFiles[0] } async function getActualSshKnownHostsPath(): Promise<string> { let actualTempFiles = (await fs.promises.readdir(runnerTemp)) .sort() .map(x => path.join(runnerTemp, x)) if (actualTempFiles.length === 0) { return '' } expect(actualTempFiles).toHaveLength(2) expect(actualTempFiles[1].endsWith('_known_hosts')).toBeTruthy() expect(actualTempFiles[1].startsWith(actualTempFiles[0])).toBeTruthy() return actualTempFiles[1] }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
You can’t perform that action at this time.