diff --git a/lib/workers/repository/update/pr/changelog/github.spec.ts b/lib/workers/repository/update/pr/changelog/github.spec.ts index 6ec4b8ac548c7bc378aec96ce5eb4f655c875798..7d1e4c746c72e1a858ca1e17f214408cd925f030 100644 --- a/lib/workers/repository/update/pr/changelog/github.spec.ts +++ b/lib/workers/repository/update/pr/changelog/github.spec.ts @@ -1,6 +1,9 @@ import * as httpMock from '../../../../../../test/http-mock'; +import { partial } from '../../../../../../test/util'; import { GlobalConfig } from '../../../../../config/global'; import * as semverVersioning from '../../../../../modules/versioning/semver'; +import * as githubGraphql from '../../../../../util/github/graphql'; +import type { GithubTagItem } from '../../../../../util/github/graphql/types'; import * as hostRules from '../../../../../util/host-rules'; import type { BranchUpgradeConfig } from '../../../../types'; import { getChangeLogJSON } from '.'; @@ -356,15 +359,15 @@ describe('workers/repository/update/pr/changelog/github', () => { }); it('works with same version releases but different prefix', async () => { - httpMock - .scope('https://api.github.com/') - .get('/repos/chalk/chalk/tags?per_page=100') - .reply(200, [ - { name: 'v1.0.1' }, - { name: '1.0.1' }, - { name: 'correctPrefix/target@1.0.1' }, - { name: 'wrongPrefix/target-1.0.1' }, - ]); + const githubTagsMock = jest.spyOn(githubGraphql, 'queryTags'); + githubTagsMock.mockResolvedValue( + partial<GithubTagItem>([ + { version: 'v1.0.1' }, + { version: '1.0.1' }, + { version: 'correctPrefix/target@1.0.1' }, + { version: 'wrongPrefix/target-1.0.1' }, + ]) + ); const upgradeData: BranchUpgradeConfig = { manager: 'some-manager', diff --git a/lib/workers/repository/update/pr/changelog/github/index.ts b/lib/workers/repository/update/pr/changelog/github/index.ts index 05697a617a85b0bde45ec942955f075efa12e0e6..c989b2fa0b988f14699e3a560905b7306f14ab5c 100644 --- a/lib/workers/repository/update/pr/changelog/github/index.ts +++ b/lib/workers/repository/update/pr/changelog/github/index.ts @@ -5,13 +5,13 @@ import type { GithubGitTree, GithubGitTreeNode, } from '../../../../../../types/platform/github'; -import type { - GithubRestRelease, - GithubRestTag, -} from '../../../../../../util/github/types'; +import { + queryReleases, + queryTags, +} from '../../../../../../util/github/graphql'; import { GithubHttp } from '../../../../../../util/http/github'; import { fromBase64 } from '../../../../../../util/string'; -import { ensureTrailingSlash } from '../../../../../../util/url'; +import { ensureTrailingSlash, joinUrlParts } from '../../../../../../util/url'; import type { ChangeLogFile, ChangeLogNotes, @@ -28,18 +28,20 @@ export async function getTags( ): Promise<string[]> { logger.trace('github.getTags()'); try { - const url = `${endpoint}repos/${repository}/tags?per_page=100`; - const res = await http.getJson<GithubRestTag[]>(url, { - paginate: true, - }); - const tags = res.body; + const tags = await queryTags( + { + registryUrl: endpoint, + packageName: repository, + }, + http + ); // istanbul ignore if if (!tags.length) { logger.debug(`No Github tags found for repository:${repository}`); } - return tags.map((tag) => tag.name).filter(Boolean); + return tags.map(({ version }) => version); } catch (err) { logger.debug( { sourceRepo: repository, err }, @@ -114,23 +116,34 @@ export async function getReleaseNotesMd( export async function getReleaseList( project: ChangeLogProject, - release: ChangeLogRelease + _release: ChangeLogRelease ): Promise<ChangeLogNotes[]> { logger.trace('github.getReleaseList()'); - // TODO #7154 - const apiBaseUrl = project.apiBaseUrl!; + const apiBaseUrl = project.apiBaseUrl!; // TODO #7154 const repository = project.repository; - const url = `${ensureTrailingSlash(apiBaseUrl)}repos/${repository}/releases`; - const res = await http.getJson<GithubRestRelease[]>(`${url}?per_page=100`, { - paginate: true, - }); + const notesSourceUrl = joinUrlParts( + apiBaseUrl, + 'repos', + repository, + 'releases' + ); + const releases = await queryReleases( + { + registryUrl: apiBaseUrl, + packageName: repository, + }, + http + ); - return res.body.map((release) => ({ - url: release.html_url, - notesSourceUrl: url, - id: release.id, - tag: release.tag_name, - name: release.name, - body: release.body, - })); + const result = releases.map( + ({ url, id, version: tag, name, description: body }) => ({ + url, + notesSourceUrl, + id, + tag, + name, + body, + }) + ); + return result; } diff --git a/lib/workers/repository/update/pr/changelog/index.spec.ts b/lib/workers/repository/update/pr/changelog/index.spec.ts index 34ceaa05ddbce65384052ba04e3700d9e65dbe0a..c3a3439f4cc773934f57f34201bdf0876643fa16 100644 --- a/lib/workers/repository/update/pr/changelog/index.spec.ts +++ b/lib/workers/repository/update/pr/changelog/index.spec.ts @@ -2,6 +2,7 @@ import * as httpMock from '../../../../../../test/http-mock'; import { partial } from '../../../../../../test/util'; import { GlobalConfig } from '../../../../../config/global'; import * as semverVersioning from '../../../../../modules/versioning/semver'; +import * as githubGraphql from '../../../../../util/github/graphql'; import * as hostRules from '../../../../../util/host-rules'; import type { BranchConfig } from '../../../../types'; import { getChangeLogJSON } from '.'; @@ -10,6 +11,9 @@ jest.mock('../../../../../modules/datasource/npm'); const githubApiHost = 'https://api.github.com'; +const githubTagsMock = jest.spyOn(githubGraphql, 'queryTags'); +const githubReleasesMock = jest.spyOn(githubGraphql, 'queryReleases'); + const upgrade: BranchConfig = partial<BranchConfig>({ endpoint: 'https://api.github.com/', depName: 'renovate', @@ -81,15 +85,12 @@ describe('workers/repository/update/pr/changelog/index', () => { }); it('works without Github', async () => { + githubTagsMock.mockRejectedValueOnce(new Error('Unknown')); + githubReleasesMock.mockRejectedValueOnce(new Error('Unknown')); httpMock .scope(githubApiHost) .get('/repos/chalk/chalk') .times(4) - .reply(500) - .get('/repos/chalk/chalk/tags?per_page=100') - .reply(500) - .get('/repos/chalk/chalk/releases?per_page=100') - .times(4) .reply(500); expect( await getChangeLogJSON({ @@ -116,20 +117,16 @@ describe('workers/repository/update/pr/changelog/index', () => { }); it('uses GitHub tags', async () => { - httpMock - .scope(githubApiHost) - .get('/repos/chalk/chalk/tags?per_page=100') - .reply(200, [ - { name: '0.9.0' }, - { name: '1.0.0' }, - { name: '1.4.0' }, - { name: 'v2.3.0' }, - { name: '2.2.2' }, - { name: 'v2.4.2' }, - ]) - .persist() - .get(/.*/) - .reply(200, []); + httpMock.scope(githubApiHost).get(/.*/).reply(200, []).persist(); + githubTagsMock.mockResolvedValue([ + { version: '0.9.0' }, + { version: '1.0.0' }, + { version: '1.4.0' }, + { version: 'v2.3.0' }, + { version: '2.2.2' }, + { version: 'v2.4.2' }, + ] as never); + githubReleasesMock.mockResolvedValue([]); expect( await getChangeLogJSON({ ...upgrade, @@ -155,6 +152,10 @@ describe('workers/repository/update/pr/changelog/index', () => { }); it('filters unnecessary warns', async () => { + githubTagsMock.mockRejectedValueOnce(new Error('Unknown Github Repo')); + githubReleasesMock.mockRejectedValueOnce( + new Error('Unknown Github Repo') + ); httpMock.scope(githubApiHost).get(/.*/).reply(200, []).persist(); const res = await getChangeLogJSON({ ...upgrade, @@ -181,6 +182,8 @@ describe('workers/repository/update/pr/changelog/index', () => { }); it('supports node engines', async () => { + githubTagsMock.mockRejectedValueOnce([]); + githubReleasesMock.mockRejectedValueOnce([]); expect( await getChangeLogJSON({ ...upgrade, @@ -255,6 +258,8 @@ describe('workers/repository/update/pr/changelog/index', () => { }); it('supports github enterprise and github.com changelog', async () => { + githubTagsMock.mockRejectedValueOnce([]); + githubReleasesMock.mockRejectedValueOnce([]); httpMock.scope(githubApiHost).persist().get(/.*/).reply(200, []); hostRules.add({ hostType: 'github', @@ -287,6 +292,8 @@ describe('workers/repository/update/pr/changelog/index', () => { }); it('supports github enterprise and github enterprise changelog', async () => { + githubTagsMock.mockRejectedValueOnce([]); + githubReleasesMock.mockRejectedValueOnce([]); httpMock .scope('https://github-enterprise.example.com') .persist() @@ -325,6 +332,8 @@ describe('workers/repository/update/pr/changelog/index', () => { }); it('supports github.com and github enterprise changelog', async () => { + githubTagsMock.mockRejectedValueOnce([]); + githubReleasesMock.mockRejectedValueOnce([]); httpMock .scope('https://github-enterprise.example.com') .persist() diff --git a/lib/workers/repository/update/pr/changelog/release-notes.spec.ts b/lib/workers/repository/update/pr/changelog/release-notes.spec.ts index e4066da18aa5074f116f6538197064874b56a027..c44ff547ecc0da46766a17cbf94825dd6c35db9d 100644 --- a/lib/workers/repository/update/pr/changelog/release-notes.spec.ts +++ b/lib/workers/repository/update/pr/changelog/release-notes.spec.ts @@ -3,6 +3,7 @@ import { Fixtures } from '../../../../../../test/fixtures'; import * as httpMock from '../../../../../../test/http-mock'; import { mocked } from '../../../../../../test/util'; import { clone } from '../../../../../util/clone'; +import * as githubGraphql from '../../../../../util/github/graphql'; import * as _hostRules from '../../../../../util/host-rules'; import { toBase64 } from '../../../../../util/string'; import type { BranchUpgradeConfig } from '../../../../types'; @@ -58,6 +59,8 @@ const gitlabProject = { } as ChangeLogProject; describe('workers/repository/update/pr/changelog/release-notes', () => { + const githubReleasesMock = jest.spyOn(githubGraphql, 'queryReleases'); + beforeEach(() => { hostRules.find.mockReturnValue({}); hostRules.hosts.mockReturnValue([]); @@ -178,17 +181,25 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { }); it('should return release list for github repo', async () => { - httpMock - .scope('https://api.github.com/') - .get('/repos/some/yet-other-repository/releases?per_page=100') - .reply(200, [ - { tag_name: `v1.0.0` }, - { - tag_name: `v1.0.1`, - body: 'some body #123, [#124](https://github.com/some/yet-other-repository/issues/124)', - }, - ]); - + githubReleasesMock.mockResolvedValueOnce([ + { + version: `v1.0.0`, + releaseTimestamp: '2020-01-01', + id: 1, + url: 'https://example.com', + name: 'some/dep', + description: 'some body', + }, + { + version: `v1.0.1`, + releaseTimestamp: '2020-01-01', + id: 1, + url: 'https://example.com', + name: 'some/dep', + description: + 'some body #123, [#124](https://github.com/some/yet-other-repository/issues/124)', + }, + ]); const res = await getReleaseList( { ...githubProject, @@ -289,10 +300,24 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { describe('getReleaseNotes()', () => { it('should return null for release notes without body and name', async () => { - httpMock - .scope('https://api.github.com/') - .get('/repos/some/repository/releases?per_page=100') - .reply(200, [{ tag_name: 'v1.0.0' }, { tag_name: 'v1.0.1' }]); + githubReleasesMock.mockResolvedValueOnce([ + { + version: '1.0.0', + releaseTimestamp: '2020-01-01', + id: 1, + url: 'https://github.com/some/other-repository/releases/1.0.0', + name: '', + description: '', + }, + { + version: '1.0.1', + releaseTimestamp: '2020-01-01', + id: 2, + url: 'https://github.com/some/other-repository/releases/1.0.1', + name: '', + description: '', + }, + ]); const res = await getReleaseNotes( { ...githubProject, @@ -309,17 +334,25 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { }); it('gets release notes with body ""', async () => { - const prefix = ''; - httpMock - .scope('https://api.github.com/') - .get('/repos/some/other-repository/releases?per_page=100') - .reply(200, [ - { tag_name: `${prefix}1.0.0` }, - { - tag_name: `${prefix}1.0.1`, - body: 'some body #123, [#124](https://github.com/some/yet-other-repository/issues/124)', - }, - ]); + githubReleasesMock.mockResolvedValueOnce([ + { + version: '1.0.0', + releaseTimestamp: '2020-01-01', + id: 1, + url: 'https://github.com/some/other-repository/releases/1.0.0', + name: 'some/dep', + description: 'some body', + }, + { + version: '1.0.1', + releaseTimestamp: '2020-01-01', + id: 2, + url: 'https://github.com/some/other-repository/releases/1.0.1', + name: 'some/dep', + description: + 'some body #123, [#124](https://github.com/some/yet-other-repository/issues/124)', + }, + ]); const res = await getReleaseNotes( { ...githubProject, @@ -334,8 +367,8 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { ); expect(res).toEqual({ body: 'some body [#123](https://github.com/some/other-repository/issues/123), [#124](https://github.com/some/yet-other-repository/issues/124)\n', - id: undefined, - name: undefined, + id: 2, + name: 'some/dep', notesSourceUrl: 'https://api.github.com/repos/some/other-repository/releases', tag: '1.0.1', @@ -344,18 +377,24 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { }); it('gets release notes with name ""', async () => { - const prefix = ''; - httpMock - .scope('https://api.github.com/') - .get('/repos/some/other-repository/releases?per_page=100') - .reply(200, [ - { tag_name: `${prefix}1.0.0` }, - { - tag_name: `${prefix}1.0.1`, - name: 'some release name', - body: undefined, - }, - ]); + githubReleasesMock.mockResolvedValueOnce([ + { + version: '1.0.0', + releaseTimestamp: '2020-01-01', + id: 1, + url: 'https://github.com/some/other-repository/releases/1.0.0', + name: 'some/dep', + description: '', + }, + { + version: '1.0.1', + releaseTimestamp: '2020-01-01', + id: 2, + url: 'https://github.com/some/other-repository/releases/1.0.1', + name: 'some release name', + description: '', + }, + ]); const res = await getReleaseNotes( { ...githubProject, @@ -370,7 +409,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { ); expect(res).toEqual({ body: '', - id: undefined, + id: 2, name: 'some release name', notesSourceUrl: 'https://api.github.com/repos/some/other-repository/releases', @@ -380,18 +419,24 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { }); it('filters release note name when same as version', async () => { - const prefix = ''; - httpMock - .scope('https://api.github.com/') - .get('/repos/some/other-repository/releases?per_page=100') - .reply(200, [ - { tag_name: `${prefix}1.0.0`, name: 'Release v1.0.0' }, - { - tag_name: `${prefix}1.0.1`, - name: '1.0.1', - body: 'some body', - }, - ]); + githubReleasesMock.mockResolvedValueOnce([ + { + version: '1.0.0', + releaseTimestamp: '2020-01-01', + id: 1, + url: 'https://github.com/some/other-repository/releases/1.0.0', + name: 'Release v1.0.0', + description: 'some body', + }, + { + version: '1.0.1', + releaseTimestamp: '2020-01-01', + id: 2, + url: 'https://github.com/some/other-repository/releases/1.0.1', + name: '1.0.1', + description: 'some body', + }, + ]); const res = await getReleaseNotes( { ...githubProject, @@ -406,7 +451,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { ); expect(res).toEqual({ body: 'some body\n', - id: undefined, + id: 2, name: undefined, notesSourceUrl: 'https://api.github.com/repos/some/other-repository/releases', @@ -416,18 +461,24 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { }); it('strips release note with version prefixed name', async () => { - const prefix = ''; - httpMock - .scope('https://api.github.com/') - .get('/repos/some/other-repository/releases?per_page=100') - .reply(200, [ - { tag_name: `${prefix}1.0.0` }, - { - tag_name: `${prefix}1.0.1`, - name: 'v1.0.1 some release', - body: 'some body', - }, - ]); + githubReleasesMock.mockResolvedValueOnce([ + { + version: '1.0.0', + releaseTimestamp: '2020-01-01', + id: 1, + url: 'https://github.com/some/other-repository/releases/1.0.1', + name: 'some/dep', + description: 'some body', + }, + { + version: '1.0.1', + releaseTimestamp: '2020-01-01', + id: 2, + url: 'https://github.com/some/other-repository/releases/1.0.1', + name: 'v1.0.1 some release', + description: 'some body', + }, + ]); const res = await getReleaseNotes( { ...githubProject, @@ -442,7 +493,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { ); expect(res).toEqual({ body: 'some body\n', - id: undefined, + id: 2, name: 'some release', notesSourceUrl: 'https://api.github.com/repos/some/other-repository/releases', @@ -452,17 +503,24 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { }); it('release notes without body and name that matches version tag returns null', async () => { - const prefix = ''; - httpMock - .scope('https://api.github.com/') - .get('/repos/some/other-repository/releases?per_page=100') - .reply(200, [ - { tag_name: `${prefix}1.0.0` }, - { - tag_name: `${prefix}1.0.1`, - name: '1.0.1', - }, - ]); + githubReleasesMock.mockResolvedValueOnce([ + { + version: '1.0.0', + releaseTimestamp: '2020-01-01', + id: 1, + url: 'correct/url/tag.com', + name: 'some/dep', + description: '', + }, + { + version: '1.0.1', + releaseTimestamp: '2020-01-01', + id: 2, + url: 'correct/url/tag.com', + name: '1.0.1', + description: '', + }, + ]); const res = await getReleaseNotes( { ...githubProject, @@ -479,17 +537,25 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { }); it('gets release notes with body "v"', async () => { - const prefix = 'v'; - httpMock - .scope('https://api.github.com/') - .get('/repos/some/other-repository/releases?per_page=100') - .reply(200, [ - { tag_name: `${prefix}1.0.0` }, - { - tag_name: `${prefix}1.0.1`, - body: 'some body #123, [#124](https://github.com/some/yet-other-repository/issues/124)', - }, - ]); + githubReleasesMock.mockResolvedValueOnce([ + { + version: 'v1.0.0', + releaseTimestamp: '2020-01-01', + id: 1, + url: 'https://github.com/some/other-repository/releases/v1.0.0', + name: 'some/dep', + description: 'some body', + }, + { + version: 'v1.0.1', + releaseTimestamp: '2020-01-01', + id: 2, + url: 'https://github.com/some/other-repository/releases/v1.0.1', + name: 'some/dep', + description: + 'some body #123, [#124](https://github.com/some/yet-other-repository/issues/124)', + }, + ]); const res = await getReleaseNotes( { ...githubProject, @@ -504,8 +570,8 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { ); expect(res).toEqual({ body: 'some body [#123](https://github.com/some/other-repository/issues/123), [#124](https://github.com/some/yet-other-repository/issues/124)\n', - id: undefined, - name: undefined, + id: 2, + name: 'some/dep', notesSourceUrl: 'https://api.github.com/repos/some/other-repository/releases', tag: 'v1.0.1', @@ -514,17 +580,25 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { }); it('gets release notes with body "other-"', async () => { - const prefix = 'other-'; - httpMock - .scope('https://api.github.com/') - .get('/repos/some/other-repository/releases?per_page=100') - .reply(200, [ - { tag_name: `${prefix}1.0.0` }, - { - tag_name: `${prefix}1.0.1`, - body: 'some body #123, [#124](https://github.com/some/yet-other-repository/issues/124)', - }, - ]); + githubReleasesMock.mockResolvedValueOnce([ + { + version: 'other-1.0.0', + releaseTimestamp: '2020-01-01', + id: 1, + url: 'https://github.com/some/other-repository/releases/other-1.0.0', + name: 'some/dep', + description: 'some body', + }, + { + version: 'other-1.0.1', + releaseTimestamp: '2020-01-01', + id: 2, + url: 'https://github.com/some/other-repository/releases/other-1.0.1', + name: 'some/dep', + description: + 'some body #123, [#124](https://github.com/some/yet-other-repository/issues/124)', + }, + ]); const res = await getReleaseNotes( { @@ -540,8 +614,8 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { ); expect(res).toEqual({ body: 'some body [#123](https://github.com/some/other-repository/issues/123), [#124](https://github.com/some/yet-other-repository/issues/124)\n', - id: undefined, - name: undefined, + id: 2, + name: 'some/dep', notesSourceUrl: 'https://api.github.com/repos/some/other-repository/releases', tag: 'other-1.0.1', @@ -550,17 +624,25 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { }); it('gets release notes with body "other_v"', async () => { - const prefix = 'other_v'; - httpMock - .scope('https://api.github.com/') - .get('/repos/some/other-repository/releases?per_page=100') - .reply(200, [ - { tag_name: `${prefix}1.0.0` }, - { - tag_name: `${prefix}1.0.1`, - body: 'some body #123, [#124](https://github.com/some/yet-other-repository/issues/124)', - }, - ]); + githubReleasesMock.mockResolvedValueOnce([ + { + version: 'other_v1.0.0', + releaseTimestamp: '2020-01-01', + id: 1, + url: 'https://github.com/some/other-repository/releases/other_v1.0.0', + name: 'some/dep', + description: 'some body', + }, + { + version: 'other_v1.0.1', + releaseTimestamp: '2020-01-01', + id: 2, + url: 'https://github.com/some/other-repository/releases/other_v1.0.1', + name: 'some/dep', + description: + 'some body #123, [#124](https://github.com/some/yet-other-repository/issues/124)', + }, + ]); const res = await getReleaseNotes( { @@ -576,8 +658,8 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { ); expect(res).toEqual({ body: 'some body [#123](https://github.com/some/other-repository/issues/123), [#124](https://github.com/some/yet-other-repository/issues/124)\n', - id: undefined, - name: undefined, + id: 2, + name: 'some/dep', notesSourceUrl: 'https://api.github.com/repos/some/other-repository/releases', tag: 'other_v1.0.1', @@ -586,17 +668,25 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { }); it('gets release notes with body "other@"', async () => { - const prefix = 'other@'; - httpMock - .scope('https://api.github.com/') - .get('/repos/some/other-repository/releases?per_page=100') - .reply(200, [ - { tag_name: `${prefix}1.0.0` }, - { - tag_name: `${prefix}1.0.1`, - body: 'some body #123, [#124](https://github.com/some/yet-other-repository/issues/124)', - }, - ]); + githubReleasesMock.mockResolvedValueOnce([ + { + version: 'other@1.0.0', + id: 1, + releaseTimestamp: '2020-01-01', + url: 'https://github.com/some/other-repository/releases/other@1.0.0', + name: 'some/dep', + description: 'some body', + } as never, + { + version: 'other@1.0.1', + description: + 'some body #123, [#124](https://github.com/some/yet-other-repository/issues/124)', + id: 2, + releaseTimestamp: '2020-01-01', + url: 'https://github.com/some/other-repository/releases/other@1.0.1', + name: 'some/dep', + }, + ]); const res = await getReleaseNotes( { ...githubProject, @@ -611,8 +701,8 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { ); expect(res).toEqual({ body: 'some body [#123](https://github.com/some/other-repository/issues/123), [#124](https://github.com/some/yet-other-repository/issues/124)\n', - id: undefined, - name: undefined, + id: 2, + name: 'some/dep', notesSourceUrl: 'https://api.github.com/repos/some/other-repository/releases', tag: 'other@1.0.1', @@ -750,20 +840,32 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { it('handles same version but different repo releases', async () => { const depName = 'correctTagPrefix/exampleDep'; - httpMock - .scope('https://api.github.com/') - .get('/repos/some/other-repository/releases?per_page=100') - .reply(200, [ - { - tag_name: `${depName}@1.0.0`, - html_url: 'correct/url/tag.com', - body: 'some body', - }, - { tag_name: `someOtherRelease1/exampleDep_1.0.0` }, - { - tag_name: `someOtherRelease2/exampleDep-1.0.0`, - }, - ]); + githubReleasesMock.mockResolvedValueOnce([ + { + id: 1, + version: `${depName}@1.0.0`, + releaseTimestamp: '2020-01-01', + url: 'correct/url/tag.com', + name: 'some/dep', + description: 'some body', + }, + { + id: 2, + version: `someOtherRelease1/exampleDep_1.0.0`, + releaseTimestamp: '2020-01-01', + url: 'correct/url/tag.com', + name: 'some/dep', + description: 'some body', + }, + { + id: 3, + version: `someOtherRelease2/exampleDep-1.0.0`, + releaseTimestamp: '2020-01-01', + url: 'correct/url/tag.com', + name: 'some/dep', + description: 'some body', + }, + ]); const res = await getReleaseNotes( { ...githubProject, @@ -780,24 +882,24 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { url: 'correct/url/tag.com', notesSourceUrl: 'https://api.github.com/repos/some/other-repository/releases', - id: undefined, + id: 1, tag: 'correctTagPrefix/exampleDep@1.0.0', - name: undefined, + name: 'some/dep', body: 'some body\n', }); }); it('fallback to extractVersion', async () => { - httpMock - .scope('https://api.github.com/') - .get('/repos/some/other-repository/releases?per_page=100') - .reply(200, [ - { - tag_name: `app-1.0.0`, - html_url: 'correct/url/tag.com', - body: 'some body', - }, - ]); + githubReleasesMock.mockResolvedValueOnce([ + { + id: 123, + version: `app-1.0.0`, + releaseTimestamp: '2020-01-01', + url: 'correct/url/tag.com', + description: 'some body', + name: 'some/dep', + }, + ]); const res = await getReleaseNotes( { ...githubProject, @@ -814,9 +916,9 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { url: 'correct/url/tag.com', notesSourceUrl: 'https://api.github.com/repos/some/other-repository/releases', - id: undefined, + id: 123, tag: 'app-1.0.0', - name: undefined, + name: 'some/dep', body: 'some body\n', }); }); diff --git a/lib/workers/repository/update/pr/changelog/release-notes.ts b/lib/workers/repository/update/pr/changelog/release-notes.ts index 1162de48d499a12fa74a87e802e0f78040ac760f..514a46623b1437f3294ddb26000b05cd71c12b95 100644 --- a/lib/workers/repository/update/pr/changelog/release-notes.ts +++ b/lib/workers/repository/update/pr/changelog/release-notes.ts @@ -6,6 +6,7 @@ import MarkdownIt from 'markdown-it'; import { logger } from '../../../../../logger'; import * as memCache from '../../../../../util/cache/memory'; import * as packageCache from '../../../../../util/cache/package'; +import { detectPlatform } from '../../../../../util/common'; import { linkify } from '../../../../../util/markdown'; import { newlineRegex, regEx } from '../../../../../util/regex'; import type { BranchUpgradeConfig } from '../../../../types'; @@ -178,14 +179,13 @@ async function releaseNotesResult( } const { baseUrl, repository } = project; const releaseNotes: ChangeLogNotes = releaseMatch; - if (releaseMatch.url && !baseUrl.includes('gitlab')) { - // there is a ready link - releaseNotes.url = releaseMatch.url; + if (detectPlatform(baseUrl) === 'gitlab') { + releaseNotes.url = `${baseUrl}${repository}/tags/${releaseMatch.tag!}`; } else { - // TODO: types (#7154) - releaseNotes.url = baseUrl.includes('gitlab') - ? `${baseUrl}${repository}/tags/${releaseMatch.tag!}` - : `${baseUrl}${repository}/releases/${releaseMatch.tag!}`; + releaseNotes.url = releaseMatch.url + ? releaseMatch.url + : /* istanbul ignore next */ + `${baseUrl}${repository}/releases/${releaseMatch.tag!}`; } // set body for release notes releaseNotes.body = massageBody(releaseNotes.body, baseUrl);