diff --git a/packages/backend-common/src/reading/GitlabUrlReader.test.ts b/packages/backend-common/src/reading/GitlabUrlReader.test.ts index f422820a29..29ef3f4ce8 100644 --- a/packages/backend-common/src/reading/GitlabUrlReader.test.ts +++ b/packages/backend-common/src/reading/GitlabUrlReader.test.ts @@ -106,7 +106,7 @@ describe('GitlabUrlReader', () => { ); it.each([ - // Project URLs + // Scoped routes { url: 'https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/my/path/to/file.yaml', config: createConfig(), @@ -135,12 +135,12 @@ describe('GitlabUrlReader', () => { }), }, - // Raw URLs + // Unscoped route { url: 'https://gitlab.example.com/a/b/blob/master/c.yaml', config: createConfig(), response: expect.objectContaining({ - url: 'https://gitlab.example.com/a/b/raw/master/c.yaml', + url: 'https://gitlab.example.com/api/v4/projects/12345/repository/files/c.yaml/raw?ref=master', }), }, ])('should handle happy path %#', async ({ url, config, response }) => { diff --git a/packages/integration/src/gitlab/core.test.ts b/packages/integration/src/gitlab/core.test.ts index 0dae905ce4..98fd9b7c13 100644 --- a/packages/integration/src/gitlab/core.test.ts +++ b/packages/integration/src/gitlab/core.test.ts @@ -155,11 +155,11 @@ describe('gitlab core', () => { }); describe('when target has an unscoped route', () => { - it('returns a raw URL', async () => { + it('returns projects API URL', async () => { const target = 'https://gitlab.com/group/project/blob/branch/folder/file.yaml'; const fetchUrl = - 'https://gitlab.com/group/project/raw/branch/folder/file.yaml'; + 'https://gitlab.com/api/v4/projects/12345/repository/files/folder%2Ffile.yaml/raw?ref=branch'; await expect( getGitLabFileFetchUrl(target, configWithNoToken), ).resolves.toBe(fetchUrl); @@ -169,17 +169,7 @@ describe('gitlab core', () => { const target = 'https://gitlab.com/group/subgroup/project/blob/branch/folder/file.yaml'; const fetchUrl = - 'https://gitlab.com/group/subgroup/project/raw/branch/folder/file.yaml'; - await expect( - getGitLabFileFetchUrl(target, configWithNoToken), - ).resolves.toBe(fetchUrl); - }); - - it('supports project named "blob"', async () => { - const target = - 'https://gitlab.com/group/blob/blob/branch/folder/file.yaml'; - const fetchUrl = - 'https://gitlab.com/group/blob/raw/branch/folder/file.yaml'; + 'https://gitlab.com/api/v4/projects/12345/repository/files/folder%2Ffile.yaml/raw?ref=branch'; await expect( getGitLabFileFetchUrl(target, configWithNoToken), ).resolves.toBe(fetchUrl); @@ -189,15 +179,7 @@ describe('gitlab core', () => { const target = 'https://gitlab.com/group/project/blob/blob/folder/file.yaml'; const fetchUrl = - 'https://gitlab.com/group/project/raw/blob/folder/file.yaml'; - await expect( - getGitLabFileFetchUrl(target, configWithNoToken), - ).resolves.toBe(fetchUrl); - }); - - it('removes empty path segment', async () => { - const target = 'https://gitlab.example.com/group//blob/blob/file.yaml'; - const fetchUrl = 'https://gitlab.example.com/group/blob/raw/file.yaml'; + 'https://gitlab.com/api/v4/projects/12345/repository/files/folder%2Ffile.yaml/raw?ref=blob'; await expect( getGitLabFileFetchUrl(target, configWithNoToken), ).resolves.toBe(fetchUrl); diff --git a/packages/integration/src/gitlab/core.ts b/packages/integration/src/gitlab/core.ts index 1fcf15a78f..040ca202d6 100644 --- a/packages/integration/src/gitlab/core.ts +++ b/packages/integration/src/gitlab/core.ts @@ -19,7 +19,6 @@ import { GitLabIntegrationConfig, } from './config'; import fetch from 'cross-fetch'; -import { InputError } from '@backstage/errors'; /** * Given a URL pointing to a file on a provider, returns a URL that is suitable @@ -29,7 +28,7 @@ import { InputError } from '@backstage/errors'; * * Converts * from: https://gitlab.example.com/a/b/blob/master/c.yaml - * to: https://gitlab.example.com/a/b/raw/master/c.yaml + * to: https://gitlab.com/api/v4/projects/projectId/repository/c.yaml?ref=master * -or- * from: https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/filepath * to: https://gitlab.com/api/v4/projects/projectId/repository/files/filepath?ref=branch @@ -42,15 +41,8 @@ export async function getGitLabFileFetchUrl( url: string, config: GitLabIntegrationConfig, ): Promise { - // TODO(Rugvip): From the old GitlabReaderProcessor; used - // the existence of /-/blob/ to switch the logic. Don't know if this - // makes sense and it might require some more work. - - if (url.includes('/-/blob/')) { - const projectID = await getProjectId(url, config); - return buildProjectUrl(url, projectID, config).toString(); - } - return buildRawUrl(url).toString(); + const projectID = await getProjectId(url, config); + return buildProjectUrl(url, projectID, config).toString(); } /** @@ -70,38 +62,6 @@ export function getGitLabRequestOptions(config: GitLabIntegrationConfig): { }; } -// Converts -// from: https://gitlab.example.com/groupA/teams/repoA/blob/master/c.yaml -// to: https://gitlab.example.com/groupA/teams/repoA/raw/master/c.yaml -export function buildRawUrl(target: string): URL { - try { - const url = new URL(target); - - const splitPath = url.pathname.split('/').filter(Boolean); - - // Check blob existence - const blobIndex = splitPath.indexOf('blob', 2); - if (blobIndex < 2 || blobIndex === splitPath.length - 1) { - throw new InputError('Wrong GitLab URL'); - } - - // Take repo path - const repoPath = splitPath.slice(0, blobIndex); - const restOfPath = splitPath.slice(blobIndex + 1); - - if (!restOfPath.join('/').match(/\.(yaml|yml)$/)) { - throw new InputError('Wrong GitLab URL'); - } - - // Replace 'blob' with 'raw' - url.pathname = [...repoPath, 'raw', ...restOfPath].join('/'); - - return url; - } catch (e) { - throw new InputError(`Incorrect url: ${target}, ${e}`); - } -} - // Converts // from: https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/filepath // to: https://gitlab.com/api/v4/projects/projectId/repository/files/filepath?ref=branch @@ -113,7 +73,10 @@ export function buildProjectUrl( try { const url = new URL(target); - const branchAndFilePath = url.pathname.split('/-/blob/')[1]; + const branchAndFilePath = url.pathname + .split('/blob/') + .slice(1) + .join('/blob/'); const [branch, ...filePath] = branchAndFilePath.split('/'); const relativePath = getGitLabIntegrationRelativePath(config); @@ -143,12 +106,12 @@ export async function getProjectId( ): Promise { const url = new URL(target); - if (!url.pathname.includes('/-/blob/')) { + if (!url.pathname.includes('/blob/')) { throw new Error('Please provide full path to yaml file from GitLab'); } try { - let repo = url.pathname.split('/-/blob/')[0]; + let repo = url.pathname.split('/-/blob/')[0].split('/blob/')[0]; // Get gitlab relative path const relativePath = getGitLabIntegrationRelativePath(config);