123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802 |
- 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
- 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
- }
- })
- const configureAuth_configuresAuthHeader =
- 'configureAuth configures auth header'
- it(configureAuth_configuresAuthHeader, async () => {
- // Arrange
- await setup(configureAuth_configuresAuthHeader)
- 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.https://github.com/.extraheader AUTHORIZATION: basic ${basicCredential}`
- )
- ).toBeGreaterThanOrEqual(0)
- })
- 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.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(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(/url.*insteadOf/)
- }
- )
- 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.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.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 removeGlobalAuth_removesOverride = 'removeGlobalAuth removes override'
- it(removeGlobalAuth_removesOverride, async () => {
- // Arrange
- await setup(removeGlobalAuth_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.removeGlobalAuth()
- // Assert
- expect(git.env['HOME']).toBeUndefined()
- try {
- await fs.promises.stat(homeOverride)
- throw new Error(`Should have been deleted '${homeOverride}'`)
- } catch (err) {
- if (err.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(),
- 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(),
- 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()
- }
- settings = {
- authToken: 'some auth token',
- clean: true,
- commit: '',
- fetchDepth: 1,
- lfs: false,
- submodules: false,
- nestedSubmodules: false,
- persistCredentials: true,
- ref: 'refs/heads/master',
- repositoryName: 'my-repo',
- repositoryOwner: 'my-org',
- repositoryPath: '',
- sshKey: sshPath ? 'some ssh private key' : '',
- sshKnownHosts: '',
- sshStrict: true
- }
- }
- 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]
- }
|