From e80f8848f91bb9425a728889a89ea6a015eee544 Mon Sep 17 00:00:00 2001 From: t-kulmburg <89128736+t-kulmburg@users.noreply.github.com> Date: Fri, 24 Sep 2021 11:33:25 +0200 Subject: [PATCH] feat(go): support go modules in gitlab subgroups (#11540) Co-authored-by: Rhys Arkins <rhys@arkins.net> --- .../go/__snapshots__/index.spec.ts.snap | 40 ++++++++++++++++++ lib/datasource/go/index.spec.ts | 32 ++++++++++++++ lib/datasource/go/index.ts | 42 ++++++++++++++----- 3 files changed, 104 insertions(+), 10 deletions(-) diff --git a/lib/datasource/go/__snapshots__/index.spec.ts.snap b/lib/datasource/go/__snapshots__/index.spec.ts.snap index 627971757f..ee720d8d48 100644 --- a/lib/datasource/go/__snapshots__/index.spec.ts.snap +++ b/lib/datasource/go/__snapshots__/index.spec.ts.snap @@ -689,6 +689,46 @@ Array [ ] `; +exports[`datasource/go/index getReleases support gitlab subgroups 1`] = ` +Object { + "releases": Array [ + Object { + "gitRef": "v1.0.0", + "version": "v1.0.0", + }, + Object { + "gitRef": "v2.0.0", + "version": "v2.0.0", + }, + ], + "sourceUrl": "https://gitlab.com/group/subgroup/repo", +} +`; + +exports[`datasource/go/index getReleases support gitlab subgroups 2`] = ` +Array [ + Object { + "headers": Object { + "accept-encoding": "gzip, deflate, br", + "host": "gitlab.com", + "user-agent": "RenovateBot/0.0.0-semantic-release (https://github.com/renovatebot/renovate)", + }, + "method": "GET", + "url": "https://gitlab.com/group/subgroup/repo?go-get=1", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate, br", + "host": "gitlab.com", + "user-agent": "RenovateBot/0.0.0-semantic-release (https://github.com/renovatebot/renovate)", + }, + "method": "GET", + "url": "https://gitlab.com/api/v4/projects/group%2Fsubgroup%2Frepo/repository/tags?per_page=100", + }, +] +`; + exports[`datasource/go/index getReleases support self hosted gitlab private repositories 1`] = ` Object { "releases": Array [ diff --git a/lib/datasource/go/index.spec.ts b/lib/datasource/go/index.spec.ts index 2ec6448601..68be8a79a4 100644 --- a/lib/datasource/go/index.spec.ts +++ b/lib/datasource/go/index.spec.ts @@ -21,6 +21,18 @@ Nothing to see here; <a href="https://godoc.org/golang.org/x/text">move along</a </body> </html>`; +const res2 = `<!DOCTYPE html> +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> +<meta name="go-import" content="gitlab.com/group/subgroup git https://gitlab.com/group/subgroup/repo"> +<meta name="go-source" content="gitlab.com/group/subgroup https://gitlab.com/group/subgroup https://gitlab.com/group/subgroup/-/tree/master{/dir} https://gitlab.com/group/subgroup/-/blob/master{/dir}/{file}#L{line}"> +</head> +<body> +go get https://gitlab.com/group/subgroup +</body> +</html>`; + const resGitLabEE = `<html> <head> <meta name="go-import" content="my.custom.domain/golang/myrepo git https://my.custom.domain/golang/myrepo.git" /> @@ -364,6 +376,26 @@ describe('datasource/go/index', () => { expect(httpCalls).toHaveLength(6); expect(httpCalls).toMatchSnapshot(); }); + it('support gitlab subgroups', async () => { + httpMock + .scope('https://gitlab.com/') + .get('/group/subgroup/repo?go-get=1') + .reply(200, res2); + httpMock + .scope('https://gitlab.com/') + .get( + '/api/v4/projects/group%2Fsubgroup%2Frepo/repository/tags?per_page=100' + ) + .reply(200, [{ name: 'v1.0.0' }, { name: 'v2.0.0' }]); + const res = await getPkgReleases({ + datasource, + depName: 'gitlab.com/group/subgroup/repo', + }); + expect(res).toMatchSnapshot(); + expect(res).not.toBeNull(); + expect(res).toBeDefined(); + expect(httpMock.getTrace()).toMatchSnapshot(); + }); it('works for nested modules on github', async () => { const packages = [ { datasource, depName: 'github.com/x/text/a' }, diff --git a/lib/datasource/go/index.ts b/lib/datasource/go/index.ts index 7dd40a0577..4936c3a721 100644 --- a/lib/datasource/go/index.ts +++ b/lib/datasource/go/index.ts @@ -16,7 +16,9 @@ export { id } from './common'; export const customRegistrySupport = false; -const gitlabRegExp = /^(https:\/\/[^/]*gitlab\.[^/]*)\/(.*)$/; +const gitlabHttpsRegExp = + /^(?<httpsRegExpUrl>https:\/\/[^/]*gitlab\.[^/]*)\/(?<httpsRegExpName>.+?)[/]?$/; +const gitlabRegExp = /^(?<regExpUrl>gitlab\.[^/]*)\/(?<regExpPath>.+?)[/]?$/; const bitbucket = new BitBucketTagsDatasource(); async function getDatasource(goModule: string): Promise<DataSource | null> { @@ -68,12 +70,24 @@ async function getDatasource(goModule: string): Promise<DataSource | null> { .replace(/\/$/, ''), }; } - const gitlabRes = gitlabRegExp.exec(goSourceUrl); - if (gitlabRes) { + const gitlabUrl = + gitlabHttpsRegExp.exec(goSourceUrl)?.groups?.httpsRegExpUrl; + const gitlabUrlName = + gitlabHttpsRegExp.exec(goSourceUrl)?.groups?.httpsRegExpName; + const gitlabModuleName = gitlabRegExp.exec(goModule)?.groups?.regExpPath; + + if (gitlabUrl && gitlabUrlName) { + if (gitlabModuleName?.startsWith(gitlabUrlName)) { + return { + datasource: gitlab.id, + registryUrl: gitlabUrl, + lookupName: gitlabModuleName, + }; + } return { datasource: gitlab.id, - registryUrl: gitlabRes[1], - lookupName: gitlabRes[2].replace(/\/$/, ''), + registryUrl: gitlabUrl, + lookupName: gitlabUrlName, }; } @@ -199,7 +213,7 @@ export async function getReleases( const nameParts = lookupName.replace(/\/v\d+$/, '').split('/'); logger.trace({ nameParts, releases: res.releases }, 'go.getReleases'); - // If it has more than 3 parts it's a submodule + // If it has more than 3 parts it's a submodule or subgroup (gitlab only) if (nameParts.length > 3) { const prefix = nameParts.slice(3, nameParts.length).join('/'); logger.trace(`go.getReleases.prefix:${prefix}`); @@ -215,10 +229,18 @@ export async function getReleases( }); logger.trace({ submodReleases }, 'go.getReleases'); - return { - sourceUrl: res.sourceUrl, - releases: submodReleases, - }; + // If not from gitlab -> no subgroups -> must be submodule + // If from gitlab and directory one level above has tags -> has to be submodule, since groups can't have tags + // If not, it's simply a repo in a subfolder, and the normal tags are used. + if ( + !(source.datasource === gitlab.id) || + (source.datasource === gitlab.id && submodReleases.length) + ) { + return { + sourceUrl: res.sourceUrl, + releases: submodReleases, + }; + } } if (res.releases) { -- GitLab