diff --git a/lib/datasource/go/__snapshots__/index.spec.ts.snap b/lib/datasource/go/__snapshots__/index.spec.ts.snap
index 7a5a6c3853..f897c9532e 100644
--- a/lib/datasource/go/__snapshots__/index.spec.ts.snap
+++ b/lib/datasource/go/__snapshots__/index.spec.ts.snap
@@ -398,6 +398,48 @@ Array [
]
`;
+exports[`datasource/go getReleases support self hosted gitlab private repositories 1`] = `
+Object {
+ "releases": Array [
+ Object {
+ "gitRef": "v1.0.0",
+ "version": "v1.0.0",
+ },
+ Object {
+ "gitRef": "v2.0.0",
+ "version": "v2.0.0",
+ },
+ ],
+ "sourceUrl": "https://my.custom.domain/golang/myrepo",
+}
+`;
+
+exports[`datasource/go getReleases support self hosted gitlab private repositories 2`] = `
+Array [
+ Object {
+ "headers": Object {
+ "accept-encoding": "gzip, deflate",
+ "authorization": "Bearer some-token",
+ "host": "my.custom.domain",
+ "user-agent": "https://github.com/renovatebot/renovate",
+ },
+ "method": "GET",
+ "url": "https://my.custom.domain/golang/myrepo?go-get=1",
+ },
+ Object {
+ "headers": Object {
+ "accept": "application/json",
+ "accept-encoding": "gzip, deflate",
+ "authorization": "Bearer some-token",
+ "host": "my.custom.domain",
+ "user-agent": "https://github.com/renovatebot/renovate",
+ },
+ "method": "GET",
+ "url": "https://my.custom.domain/api/v4/projects/golang%2Fmyrepo/repository/tags?per_page=100",
+ },
+]
+`;
+
exports[`datasource/go getReleases unknown datasource returns null 1`] = `null`;
exports[`datasource/go getReleases unknown datasource returns null 2`] = `
diff --git a/lib/datasource/go/index.spec.ts b/lib/datasource/go/index.spec.ts
index 660896cad1..276712b1b8 100644
--- a/lib/datasource/go/index.spec.ts
+++ b/lib/datasource/go/index.spec.ts
@@ -1,8 +1,13 @@
import { getPkgReleases } from '..';
import * as httpMock from '../../../test/http-mock';
-import { logger } from '../../../test/util';
+import { logger, mocked } from '../../../test/util';
+import * as _hostRules from '../../util/host-rules';
import { id as datasource, getDigest } from '.';
+jest.mock('../../util/host-rules');
+
+const hostRules = mocked(_hostRules);
+
const res1 = `
@@ -16,6 +21,17 @@ Nothing to see here; move along
`;
+const resGitLabEE = `
+
+
+
+
+
+go get https://my.custom.domain/golang/myrepo
+
+`;
+
const resGitHubEnterprise = `
@@ -33,10 +49,13 @@ const resGitHubEnterprise = `
describe('datasource/go', () => {
beforeEach(() => {
httpMock.setup();
+ hostRules.find.mockReturnValue({});
+ hostRules.hosts.mockReturnValue([]);
});
afterEach(() => {
httpMock.reset();
+ jest.resetAllMocks();
});
describe('getDigest', () => {
@@ -194,6 +213,25 @@ describe('datasource/go', () => {
expect(res).toBeDefined();
expect(httpMock.getTrace()).toMatchSnapshot();
});
+ it('support self hosted gitlab private repositories', async () => {
+ hostRules.find.mockReturnValue({ token: 'some-token' });
+ httpMock
+ .scope('https://my.custom.domain/')
+ .get('/golang/myrepo?go-get=1')
+ .reply(200, resGitLabEE);
+ httpMock
+ .scope('https://my.custom.domain/')
+ .get('/api/v4/projects/golang%2Fmyrepo/repository/tags?per_page=100')
+ .reply(200, [{ name: 'v1.0.0' }, { name: 'v2.0.0' }]);
+ const res = await getPkgReleases({
+ datasource,
+ depName: 'my.custom.domain/golang/myrepo',
+ });
+ expect(res).toMatchSnapshot();
+ expect(res).not.toBeNull();
+ expect(res).toBeDefined();
+ expect(httpMock.getTrace()).toMatchSnapshot();
+ });
it('support bitbucket tags', async () => {
httpMock
.scope('https://api.bitbucket.org/')
@@ -216,7 +254,7 @@ describe('datasource/go', () => {
httpMock
.scope('https://some.unknown.website/')
.get('/example/module?go-get=1')
- .reply(404);
+ .reply(200);
const res = await getPkgReleases({
datasource,
depName: 'some.unknown.website/example/module',
@@ -224,11 +262,11 @@ describe('datasource/go', () => {
expect(res).toMatchSnapshot();
expect(res).toBeNull();
expect(httpMock.getTrace()).toMatchSnapshot();
- expect(logger.logger.warn).toHaveBeenCalled();
- expect(logger.logger.error).not.toHaveBeenCalledWith(
- { lookupName: 'golang.org/foo/something' },
+ expect(logger.logger.warn).toHaveBeenCalledWith(
+ { lookupName: 'some.unknown.website/example/module' },
'Unsupported dependency.'
);
+ expect(logger.logger.error).not.toHaveBeenCalled();
expect(logger.logger.fatal).not.toHaveBeenCalled();
});
it('support ghe', async () => {
diff --git a/lib/datasource/go/index.ts b/lib/datasource/go/index.ts
index 47e268253a..1d0290b227 100644
--- a/lib/datasource/go/index.ts
+++ b/lib/datasource/go/index.ts
@@ -1,5 +1,7 @@
import URL from 'url';
+import { PLATFORM_TYPE_GITLAB } from '../../constants/platforms';
import { logger } from '../../logger';
+import * as hostRules from '../../util/host-rules';
import { Http } from '../../util/http';
import { regEx } from '../../util/regex';
import * as bitbucket from '../bitbucket-tags';
@@ -75,6 +77,27 @@ async function getDatasource(goModule: string): Promise {
lookupName: gitlabRes[2].replace(/\/$/, ''),
};
}
+
+ const opts = hostRules.find({
+ hostType: PLATFORM_TYPE_GITLAB,
+ url: goSourceUrl,
+ });
+ if (opts.token) {
+ // get server base url from import url
+ const parsedUrl = URL.parse(goSourceUrl);
+
+ // split the go module from the URL: host/go/module -> go/module
+ const split = goModule.split('/');
+ const lookupName = split[1] + '/' + split[2];
+
+ const registryUrl = `${parsedUrl.protocol}//${parsedUrl.host}`;
+
+ return {
+ datasource: gitlab.id,
+ registryUrl,
+ lookupName,
+ };
+ }
} else {
// GitHub Enterprise only returns a go-import meta
const importMatch = regEx(
diff --git a/lib/workers/pr/changelog/__snapshots__/release-notes.spec.ts.snap b/lib/workers/pr/changelog/__snapshots__/release-notes.spec.ts.snap
index fe71e95fbc..e4f5476016 100644
--- a/lib/workers/pr/changelog/__snapshots__/release-notes.spec.ts.snap
+++ b/lib/workers/pr/changelog/__snapshots__/release-notes.spec.ts.snap
@@ -104,6 +104,39 @@ Array [
]
`;
+exports[`workers/pr/changelog/release-notes getReleaseList() should return release list for self hosted gitlab project 1`] = `
+Array [
+ Object {
+ "body": undefined,
+ "name": undefined,
+ "tag": "v1.0.0",
+ "url": "https://my.custom.domain/api/v4/projects/some%2fyet-other-repository/releases/v1.0.0",
+ },
+ Object {
+ "body": undefined,
+ "name": undefined,
+ "tag": "v1.0.1",
+ "url": "https://my.custom.domain/api/v4/projects/some%2fyet-other-repository/releases/v1.0.1",
+ },
+]
+`;
+
+exports[`workers/pr/changelog/release-notes getReleaseList() should return release list for self hosted gitlab project 2`] = `
+Array [
+ Object {
+ "headers": Object {
+ "accept": "application/json",
+ "accept-encoding": "gzip, deflate",
+ "authorization": "Bearer some-token",
+ "host": "my.custom.domain",
+ "user-agent": "https://github.com/renovatebot/renovate",
+ },
+ "method": "GET",
+ "url": "https://my.custom.domain/api/v4/projects/some%2fyet-other-repository/releases?per_page=100",
+ },
+]
+`;
+
exports[`workers/pr/changelog/release-notes getReleaseNotes() gets release notes with body 1`] = `
Object {
"body": "some body [#123](https://github.com/some/other-repository/issues/123), [#124](https://github.com/some/yet-other-repository/issues/124)
@@ -923,3 +956,45 @@ Object {
"url": "https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md#3100--2017-09-10",
}
`;
+
+exports[`workers/pr/changelog/release-notes getReleaseNotesMd() parses self hosted gitlab 1`] = `
+Array [
+ Object {
+ "headers": Object {
+ "accept": "application/json",
+ "accept-encoding": "gzip, deflate",
+ "authorization": "Bearer some-token",
+ "host": "my.custom.domain",
+ "user-agent": "https://github.com/renovatebot/renovate",
+ },
+ "method": "GET",
+ "url": "https://my.custom.domain/projects/gitlab-org%2fgitter%2fwebapp/repository/tree?per_page=100",
+ },
+ Object {
+ "headers": Object {
+ "accept-encoding": "gzip, deflate",
+ "authorization": "Bearer some-token",
+ "host": "my.custom.domain",
+ "user-agent": "https://github.com/renovatebot/renovate",
+ },
+ "method": "GET",
+ "url": "https://my.custom.domain/projects/gitlab-org%2fgitter%2fwebapp/repository/blobs/abcd/raw",
+ },
+]
+`;
+
+exports[`workers/pr/changelog/release-notes getReleaseNotesMd() parses self hosted gitlab 2`] = `
+Object {
+ "body": "- Removing markup from a part of the French translation,
+- Fix typo documentation -> documentation,
+ - Thanks to [@auua](https://gitlab.com/auua) for the contribution
+- Fix \`/channel\` slash command name regex to accept hyphenated names,
+ - Thanks to [@auua](https://gitlab.com/auua) for the contribution
+- Add GitLab branding to the left-menu,
+- Fix left-menu search state showing all rooms,
+- Update Polish translation,
+ - Thanks to [@biesiad](https://gitlab.com/biesiad) for the contribution
+",
+ "url": "https://my.custom.domain/gitlab-org/gitter/webapp/blob/master/CHANGELOG.md#20260---2020-05-18",
+}
+`;
diff --git a/lib/workers/pr/changelog/release-notes.spec.ts b/lib/workers/pr/changelog/release-notes.spec.ts
index a39870f100..e732f7e2a0 100644
--- a/lib/workers/pr/changelog/release-notes.spec.ts
+++ b/lib/workers/pr/changelog/release-notes.spec.ts
@@ -1,7 +1,8 @@
import fs from 'fs-extra';
import { DateTime } from 'luxon';
import * as httpMock from '../../../../test/http-mock';
-import { getName } from '../../../../test/util';
+import { getName, mocked } from '../../../../test/util';
+import * as _hostRules from '../../../util/host-rules';
import { ChangeLogNotes } from './common';
import {
addReleaseNotes,
@@ -11,6 +12,10 @@ import {
releaseNotesCacheMinutes,
} from './release-notes';
+jest.mock('../../../util/host-rules');
+
+const hostRules = mocked(_hostRules);
+
const angularJsChangelogMd = fs.readFileSync(
'lib/workers/pr/__fixtures__/angular-js.md',
'utf8'
@@ -57,10 +62,13 @@ const gitlabTreeResponse = [
describe(getName(__filename), () => {
beforeEach(() => {
httpMock.setup();
+ hostRules.find.mockReturnValue({});
+ hostRules.hosts.mockReturnValue([]);
});
afterEach(() => {
httpMock.reset();
+ jest.resetAllMocks();
});
describe('releaseNotesCacheMinutes', () => {
@@ -149,6 +157,28 @@ describe(getName(__filename), () => {
expect(res).toMatchSnapshot();
expect(httpMock.getTrace()).toMatchSnapshot();
});
+ it('should return release list for self hosted gitlab project', async () => {
+ hostRules.find.mockReturnValue({ token: 'some-token' });
+ httpMock
+ .scope('https://my.custom.domain/')
+ .get(
+ '/api/v4/projects/some%2fyet-other-repository/releases?per_page=100'
+ )
+ .reply(200, [
+ { tag_name: `v1.0.0` },
+ {
+ tag_name: `v1.0.1`,
+ body:
+ 'some body #123, [#124](https://my.custom.domain/some/yet-other-repository/issues/124)',
+ },
+ ]);
+ const res = await getReleaseList(
+ 'https://my.custom.domain/api/v4/',
+ 'some/yet-other-repository'
+ );
+ expect(res).toMatchSnapshot();
+ expect(httpMock.getTrace()).toMatchSnapshot();
+ });
});
describe('getReleaseNotes()', () => {
it('should return null for release notes without body', async () => {
@@ -343,6 +373,27 @@ describe(getName(__filename), () => {
expect(res).not.toBeNull();
expect(res).toMatchSnapshot();
});
+ it('parses self hosted gitlab', async () => {
+ hostRules.find.mockReturnValue({ token: 'some-token' });
+ jest.setTimeout(0);
+ httpMock
+ .scope('https://my.custom.domain/')
+ .get(
+ '/projects/gitlab-org%2fgitter%2fwebapp/repository/tree?per_page=100'
+ )
+ .reply(200, gitlabTreeResponse)
+ .get('/projects/gitlab-org%2fgitter%2fwebapp/repository/blobs/abcd/raw')
+ .reply(200, gitterWebappChangelogMd);
+ const res = await getReleaseNotesMd(
+ 'gitlab-org/gitter/webapp',
+ '20.26.0',
+ 'https://my.custom.domain/',
+ 'https://my.custom.domain/'
+ );
+ expect(httpMock.getTrace()).toMatchSnapshot();
+ expect(res).not.toBeNull();
+ expect(res).toMatchSnapshot();
+ });
it('parses jest', async () => {
httpMock
.scope('https://api.github.com')
diff --git a/lib/workers/pr/changelog/release-notes.ts b/lib/workers/pr/changelog/release-notes.ts
index e0f45c0c67..9b9e38fe9f 100644
--- a/lib/workers/pr/changelog/release-notes.ts
+++ b/lib/workers/pr/changelog/release-notes.ts
@@ -4,9 +4,11 @@ import { linkify } from 'linkify-markdown';
import { DateTime } from 'luxon';
import MarkdownIt from 'markdown-it';
+import { PLATFORM_TYPE_GITLAB } from '../../../constants/platforms';
import { logger } from '../../../logger';
import * as memCache from '../../../util/cache/memory';
import * as packageCache from '../../../util/cache/package';
+import * as hostRules from '../../../util/host-rules';
import { ChangeLogFile, ChangeLogNotes, ChangeLogResult } from './common';
import * as github from './github';
import * as gitlab from './gitlab';
@@ -28,6 +30,15 @@ export async function getReleaseList(
if (apiBaseUrl.includes('gitlab')) {
return await gitlab.getReleaseList(apiBaseUrl, repository);
}
+
+ const opts = hostRules.find({
+ hostType: PLATFORM_TYPE_GITLAB,
+ url: apiBaseUrl,
+ });
+ if (opts.token) {
+ return await gitlab.getReleaseList(apiBaseUrl, repository);
+ }
+
return await github.getReleaseList(apiBaseUrl, repository);
} catch (err) /* istanbul ignore next */ {
if (err.statusCode === 404) {
@@ -169,6 +180,15 @@ export async function getReleaseNotesMdFileInner(
if (apiBaseUrl.includes('gitlab')) {
return await gitlab.getReleaseNotesMd(repository, apiBaseUrl);
}
+
+ const opts = hostRules.find({
+ hostType: PLATFORM_TYPE_GITLAB,
+ url: apiBaseUrl,
+ });
+ if (opts.token) {
+ return await gitlab.getReleaseNotesMd(repository, apiBaseUrl);
+ }
+
return await github.getReleaseNotesMd(repository, apiBaseUrl);
} catch (err) /* istanbul ignore next */ {
if (err.statusCode === 404) {
diff --git a/lib/workers/pr/changelog/source-github.ts b/lib/workers/pr/changelog/source-github.ts
index 79c5529c29..73c21f0802 100644
--- a/lib/workers/pr/changelog/source-github.ts
+++ b/lib/workers/pr/changelog/source-github.ts
@@ -82,7 +82,7 @@ export async function getChangeLogJSON({
.sort((a, b) => version.sortVersions(a.version, b.version));
if (validReleases.length < 2) {
- logger.debug('Not enough valid releases');
+ logger.debug(`Not enough valid releases for dep ${depName}`);
return null;
}