diff --git a/src/lib/git-clone.ts b/src/lib/git-clone.ts index 01ff1992..8ae7a7ae 100644 --- a/src/lib/git-clone.ts +++ b/src/lib/git-clone.ts @@ -13,6 +13,7 @@ const debug = debugLib('snyk:git-clone'); const urlGenerators = { [SupportedIntegrationTypesUpdateProject.GITHUB]: github.buildGitCloneUrl, + [SupportedIntegrationTypesUpdateProject.GHE]: github.buildGitCloneUrl, }; interface GitCloneResponse { @@ -21,7 +22,7 @@ interface GitCloneResponse { gitResponse: string; } export async function gitClone( - integrationType: SupportedIntegrationTypesUpdateProject.GITHUB, + integrationType: SupportedIntegrationTypesUpdateProject, meta: RepoMetaData, ): Promise { const repoClonePath = await fs.mkdtempSync( diff --git a/src/lib/source-handlers/github/git-clone-url.ts b/src/lib/source-handlers/github/git-clone-url.ts index 1dc785c0..e86da722 100644 --- a/src/lib/source-handlers/github/git-clone-url.ts +++ b/src/lib/source-handlers/github/git-clone-url.ts @@ -4,5 +4,7 @@ import { getGithubToken } from './get-github-token'; export function buildGitCloneUrl(meta: RepoMetaData): string { const { cloneUrl } = meta; const url = new URL(cloneUrl); - return `${url.protocol}//${getGithubToken()}@${url.hostname}${url.pathname}`; + return `${url.protocol}//${getGithubToken()}:x-oauth-basic@${url.hostname}${ + url.pathname + }`; } diff --git a/test/lib/git-clone.spec.ts b/test/lib/git-clone.spec.ts index a36a729a..736c34cd 100644 --- a/test/lib/git-clone.spec.ts +++ b/test/lib/git-clone.spec.ts @@ -3,22 +3,22 @@ import { gitClone } from '../../src/lib'; import { SupportedIntegrationTypesUpdateProject } from '../../src/lib/types'; describe('gitClone', () => { - const OLD_ENV = process.env; - const removeFolders: string[] = []; - afterAll(() => { - process.env = { ...OLD_ENV }; - }); + describe('Github', () => { + const OLD_ENV = process.env; + const removeFolders: string[] = []; + afterEach(() => { + process.env = { ...OLD_ENV }; + }); - afterEach(() => { - for (const f of removeFolders) { - try { - fs.rmdirSync(f, { recursive: true }); - } catch (e) { - console.log('Failed to clean up test', e); + afterEach(() => { + for (const f of removeFolders) { + try { + fs.rmdirSync(f, { recursive: true }); + } catch (e) { + console.log('Failed to clean up test', e); + } } - } - }); - describe('Github', () => { + }); it('successfully clones a repo', async () => { process.env.GITHUB_TOKEN = process.env.GH_TOKEN; process.env.SNYK_LOG_PATH = __dirname; @@ -59,7 +59,77 @@ describe('gitClone', () => { ), success: false, }); + }, 70000); + }); + describe('Github Enterprise', () => { + const OLD_ENV = process.env; + const removeFolders: string[] = []; + const GHE_URL = new URL(process.env.TEST_GHE_URL!); + + afterAll(() => { + process.env = { ...OLD_ENV }; + }); + beforeEach(() => { + process.env.GITHUB_TOKEN = process.env.TEST_GHE_TOKEN; + }); + + afterEach(() => { + for (const f of removeFolders) { + try { + fs.rmdirSync(f, { recursive: true }); + } catch (e) { + console.log('Failed to clean up test', e); + } + } + }); + + it('successfully clones a repo', async () => { + process.env.SNYK_LOG_PATH = __dirname; + const res = await gitClone(SupportedIntegrationTypesUpdateProject.GHE, { + branch: 'master', + cloneUrl: `https://${GHE_URL.host}/snyk-fixtures/mono-repo.git`, + sshUrl: `git@${GHE_URL.host}/snyk-fixtures/mono-repo.git`, + }); + + expect(res).toEqual({ + gitResponse: '', + repoPath: expect.any(String), + success: true, + }); removeFolders.push(res.repoPath!); }, 70000); + + it('fails to clone a repo for non-existent branch', async () => { + process.env.SNYK_LOG_PATH = __dirname; + + const res = await gitClone(SupportedIntegrationTypesUpdateProject.GHE, { + branch: 'non-existent', + cloneUrl: `https://${GHE_URL.host}/snyk-fixtures/mono-repo.git`, + sshUrl: `git@${GHE_URL.host}/snyk-fixtures/mono-repo.git`, + }); + + expect(res).toEqual({ + gitResponse: expect.stringContaining( + 'Remote branch non-existent not found in upstream origin', + ), + success: false, + }); + }, 70000); + + it('fails to clone a repo with invalid token', async () => { + process.env.SNYK_LOG_PATH = __dirname; + process.env.GITHUB_TOKEN = 'bad-token'; + + const res = await gitClone(SupportedIntegrationTypesUpdateProject.GHE, { + branch: 'non-existent', + cloneUrl: `https://${GHE_URL.host}/snyk-fixtures/mono-repo.git`, + sshUrl: `git@${GHE_URL.host}/snyk-fixtures/mono-repo.git`, + }); + + expect(res).toEqual({ + gitResponse: expect.stringContaining('Authentication failed'), + success: false, + }); + }, 70000); }); }); diff --git a/test/lib/source-handlers/github/github.test.ts b/test/lib/source-handlers/github/github.test.ts index 06ddbcda..7822b5f5 100644 --- a/test/lib/source-handlers/github/github.test.ts +++ b/test/lib/source-handlers/github/github.test.ts @@ -99,7 +99,7 @@ describe('buildGitCloneUrl', () => { cloneUrl: 'https://github.com/snyk-tech-services/snyk-api-import.git', }); expect(url).toEqual( - `https://secret_token@github.com/snyk-tech-services/snyk-api-import.git`, + `https://secret_token:x-oauth-basic@github.com/snyk-tech-services/snyk-api-import.git`, ); }); });