Skip to content

Commit

Permalink
fix(changelog): add a check for exact match of a release (#15590)
Browse files Browse the repository at this point in the history
  • Loading branch information
hasanwhitesource committed May 19, 2022
1 parent da9b94d commit 00feb72
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 33 deletions.
56 changes: 56 additions & 0 deletions lib/workers/repository/update/pr/changelog/github.spec.ts
Expand Up @@ -294,5 +294,61 @@ 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 upgradeData: BranchUpgradeConfig = {
branchName: undefined,
depName: 'correctPrefix/target',
endpoint: 'https://api.github.com/',
versioning: 'npm',
currentVersion: '1.0.0',
newVersion: '1.0.1',
sourceUrl: 'https://github.com/chalk/chalk',
releases: [
{ version: '1.0.1', gitRef: '123456' },
{ version: '0.1.1', gitRef: 'npm_1.0.0' },
],
};
expect(
await getChangeLogJSON({
...upgradeData,
})
).toMatchObject({
project: {
apiBaseUrl: 'https://api.github.com/',
baseUrl: 'https://github.com/',
type: 'github',
repository: 'chalk/chalk',
sourceUrl: 'https://github.com/chalk/chalk',
sourceDirectory: undefined,
depName: 'correctPrefix/target',
},
versions: [
{
version: '1.0.1',
date: undefined,
changes: [],
compare: {
url: 'https://github.com/chalk/chalk/compare/npm_1.0.0...correctPrefix/target@1.0.1',
},
releaseNotes: {
url: 'https://github.com/chalk/chalk/compare/npm_1.0.0...correctPrefix/target@1.0.1',
notesSourceUrl: '',
},
},
],
hasReleaseNotes: true,
});
});
});
});
35 changes: 35 additions & 0 deletions lib/workers/repository/update/pr/changelog/release-notes.spec.ts
Expand Up @@ -544,6 +544,41 @@ describe('workers/repository/update/pr/changelog/release-notes', () => {
);
expect(res).toBeNull();
});

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`,
},
]);
const res = await getReleaseNotes(
{
...githubProject,
repository: 'some/other-repository',
depName: 'exampleDep',
},
'1.0.0'
);
expect(res).toEqual({
url: 'correct/url/tag.com',
notesSourceUrl:
'https://api.github.com/repos/some/other-repository/releases',
id: undefined,
tag: 'correctTagPrefix/exampleDep@1.0.0',
name: undefined,
body: 'some body\n',
});
});
});

describe('getReleaseNotesMd()', () => {
Expand Down
88 changes: 59 additions & 29 deletions lib/workers/repository/update/pr/changelog/release-notes.ts
Expand Up @@ -97,40 +97,70 @@ export async function getReleaseNotes(
project: ChangeLogProject,
version: string
): Promise<ChangeLogNotes | null> {
const { baseUrl, depName, repository } = project;
const { depName, repository } = project;
logger.trace(`getReleaseNotes(${repository}, ${version}, ${depName})`);
const releaseList = await getCachedReleaseList(project);
logger.trace({ releaseList }, 'Release list from getReleaseList');
const releases = await getCachedReleaseList(project);
logger.trace({ releases }, 'Release list from getReleaseList');
let releaseNotes: ChangeLogNotes | null = null;
for (const release of releaseList) {
if (
release.tag === version ||
release.tag === `v${version}` ||
release.tag === `${depName}-${version}` ||
release.tag === `${depName}_v${version}` ||
release.tag === `${depName}@${version}`
) {
releaseNotes = release;
releaseNotes.url = baseUrl.includes('gitlab')
? `${baseUrl}${repository}/tags/${release.tag}`
: `${baseUrl}${repository}/releases/${release.tag}`;
releaseNotes.body = massageBody(releaseNotes.body, baseUrl);
if (releaseNotes.body.length) {
try {
if (baseUrl !== 'https://gitlab.com/') {
releaseNotes.body = await linkify(releaseNotes.body, {
repository: `${baseUrl}${repository}`,
});
}
} catch (err) /* istanbul ignore next */ {
logger.warn({ err, baseUrl, repository }, 'Error linkifying');
}
} else {
releaseNotes = null;

let matchedRelease = getExactReleaseMatch(depName, version, releases);
if (is.undefined(matchedRelease)) {
// no exact match of a release then check other cases
matchedRelease = releases.find(
(r) => r.tag === version || r.tag === `v${version}`
);
}
releaseNotes = await releaseNotesResult(matchedRelease, project);
logger.trace({ releaseNotes });
return releaseNotes;
}

function getExactReleaseMatch(
depName: string,
version: string,
releases: ChangeLogNotes[]
): ChangeLogNotes | undefined {
const exactReleaseReg = regEx(`${depName}[@_-]v?${version}`);
const candidateReleases = releases.filter((r) => r.tag?.endsWith(version));
const matchedRelease = candidateReleases.find((r) =>
exactReleaseReg.test(r.tag)
);
return matchedRelease;
}

async function releaseNotesResult(
releaseMatch: ChangeLogNotes | undefined,
project: ChangeLogProject
): Promise<ChangeLogNotes | null> {
if (!releaseMatch) {
return null;
}
const { baseUrl, repository } = project;
const releaseNotes: ChangeLogNotes = releaseMatch;
if (releaseMatch.url && !baseUrl.includes('gitlab')) {
// there is a ready link
releaseNotes.url = releaseMatch.url;
} else {
releaseNotes.url = baseUrl.includes('gitlab')
? `${baseUrl}${repository}/tags/${releaseMatch.tag}`
: `${baseUrl}${repository}/releases/${releaseMatch.tag}`;
}
// set body for release notes
releaseNotes.body = massageBody(releaseNotes.body, baseUrl);
if (releaseNotes.body.length) {
try {
if (baseUrl !== 'https://gitlab.com/') {
releaseNotes.body = await linkify(releaseNotes.body, {
repository: `${baseUrl}${repository}`,
});
}
} catch (err) /* istanbul ignore next */ {
logger.warn({ err, baseUrl, repository }, 'Error linkifying');
}
} else {
return null;
}
logger.trace({ releaseNotes });

return releaseNotes;
}

Expand Down
29 changes: 25 additions & 4 deletions lib/workers/repository/update/pr/changelog/source-github.ts
Expand Up @@ -105,10 +105,7 @@ export async function getChangeLogJSON({
if (!tags) {
tags = await getCachedTags(apiBaseUrl, repository);
}
const regex = regEx(`(?:${depName}|release)[@-]`, undefined, false);
const tagName = tags
.filter((tag) => version.isVersion(tag.replace(regex, '')))
.find((tag) => version.equals(tag.replace(regex, ''), release.version));
const tagName = findTagOfRelease(version, depName, release.version, tags);
if (tagName) {
return tagName;
}
Expand Down Expand Up @@ -179,3 +176,27 @@ export async function getChangeLogJSON({

return res;
}

function findTagOfRelease(
version: allVersioning.VersioningApi,
depName: string,
depNewVersion: string,
tags: string[]
): string | undefined {
const regex = regEx(`(?:${depName}|release)[@-]`, undefined, false);
const excactReleaseRegex = regEx(`${depName}[@-_]v?${depNewVersion}`);
const exactTagsList = tags.filter((tag) => {
return excactReleaseRegex.test(tag);
});
let tagName: string | undefined;
if (exactTagsList.length) {
tagName = exactTagsList
.filter((tag) => version.isVersion(tag.replace(regex, '')))
.find((tag) => version.equals(tag.replace(regex, ''), depNewVersion));
} else {
tagName = tags
.filter((tag) => version.isVersion(tag.replace(regex, '')))
.find((tag) => version.equals(tag.replace(regex, ''), depNewVersion));
}
return tagName;
}

0 comments on commit 00feb72

Please sign in to comment.