feat: autodetect changelog file name (#1770)

Improves changelog detection algorithm to look for different upper/lower case options as well as alternative filenames like `History.md`.

Resolves #1754
This commit is contained in:
Ayoub Kaanich 2018-04-01 21:41:26 +02:00 committed by Rhys Arkins
parent 1ba12ef59c
commit 57ffec14cb
4 changed files with 72 additions and 33 deletions

View file

@ -1,4 +1,5 @@
const ghGot = require('../../platform/github/gh-got-wrapper'); const ghGot = require('../../platform/github/gh-got-wrapper');
const changelogFilenameRegex = require('changelog-filename-regex');
const MarkdownIt = require('markdown-it'); const MarkdownIt = require('markdown-it');
const markdown = new MarkdownIt('zero'); const markdown = new MarkdownIt('zero');
@ -101,20 +102,30 @@ function sectionize(text, level) {
async function getReleaseNotesMd(repository, version) { async function getReleaseNotesMd(repository, version) {
logger.debug(`getReleaseNotes(${repository}, ${version})`); logger.debug(`getReleaseNotes(${repository}, ${version})`);
let changelogMd; let changelogMd = '';
try { try {
const res = await ghGot( const apiPrefix = `https://api.github.com/repos/${repository}/contents/`;
`https://api.github.com/repos/${repository}/contents/CHANGELOG.md` const filesRes = await ghGot(apiPrefix);
); const files = filesRes.body
changelogMd = .map(f => f.name)
Buffer.from(res.body.content, 'base64').toString() + '\n#\n##'; .filter(f => changelogFilenameRegex.test(f));
} catch (err) { if (!files.length) {
// Probably a 404 logger.debug('no changelog file found');
}
if (!changelogMd) {
logger.debug('CHANGELOG.md not found');
return null; return null;
} }
const file = files[0];
/* istanbul ignore if */
if (files.length > 1) {
logger.info(`Multiple candidates for changelog file, using ${file}`);
}
const fileRes = await ghGot(`${apiPrefix}/${file}`);
changelogMd =
Buffer.from(fileRes.body.content, 'base64').toString() + '\n#\n##';
} catch (err) {
// Probably a 404?
return null;
}
changelogMd = changelogMd.replace(/\n\s*<a name="[^"]*">.*?<\/a>\n/g, '\n'); changelogMd = changelogMd.replace(/\n\s*<a name="[^"]*">.*?<\/a>\n/g, '\n');
for (const level of [1, 2, 3, 4, 5, 6, 7]) { for (const level of [1, 2, 3, 4, 5, 6, 7]) {
const changelogParsed = sectionize(changelogMd, level); const changelogParsed = sectionize(changelogMd, level);

View file

@ -53,6 +53,7 @@
"cacache": "10.0.4", "cacache": "10.0.4",
"chalk": "2.3.2", "chalk": "2.3.2",
"changelog": "1.4.2", "changelog": "1.4.2",
"changelog-filename-regex": "1.1.1",
"child-process-promise": "2.2.1", "child-process-promise": "2.2.1",
"clean-git-ref": "1.0.3", "clean-git-ref": "1.0.3",
"commander": "2.15.1", "commander": "2.15.1",

View file

@ -19,6 +19,12 @@ const jsYamlChangelogMd = fs.readFileSync(
'utf8' 'utf8'
); );
const contentsResponse = [
{ name: 'lib' },
{ name: 'CHANGELOG.md' },
{ name: 'README.md' },
];
jest.mock('gh-got'); jest.mock('gh-got');
describe('workers/pr/release-notes', () => { describe('workers/pr/release-notes', () => {
@ -36,8 +42,17 @@ describe('workers/pr/release-notes', () => {
const res = await getReleaseNotesMd('chalk', '2.0.0'); const res = await getReleaseNotesMd('chalk', '2.0.0');
expect(res).toBe(null); expect(res).toBe(null);
}); });
it('handles wrong format', async () => { it('handles files mismatch', async () => {
ghGot.mockReturnValueOnce({ ghGot.mockReturnValueOnce({
body: [{ name: 'lib' }, { name: 'README.md' }],
});
const res = await getReleaseNotesMd('chalk', '2.0.0');
expect(res).toBe(null);
});
it('handles wrong format', async () => {
ghGot
.mockReturnValueOnce({ body: contentsResponse })
.mockReturnValueOnce({
body: { body: {
content: Buffer.from('not really markdown').toString('base64'), content: Buffer.from('not really markdown').toString('base64'),
}, },
@ -46,7 +61,9 @@ describe('workers/pr/release-notes', () => {
expect(res).toBe(null); expect(res).toBe(null);
}); });
it('handles bad markdown', async () => { it('handles bad markdown', async () => {
ghGot.mockReturnValueOnce({ ghGot
.mockReturnValueOnce({ body: contentsResponse })
.mockReturnValueOnce({
body: { body: {
content: Buffer.from(`#\nha\nha\n#\nha\nha`).toString('base64'), content: Buffer.from(`#\nha\nha\n#\nha\nha`).toString('base64'),
}, },
@ -55,7 +72,9 @@ describe('workers/pr/release-notes', () => {
expect(res).toBe(null); expect(res).toBe(null);
}); });
it('parses angular.js', async () => { it('parses angular.js', async () => {
ghGot.mockReturnValueOnce({ ghGot
.mockReturnValueOnce({ body: contentsResponse })
.mockReturnValueOnce({
body: { body: {
content: Buffer.from(angularJsChangelogMd).toString('base64'), content: Buffer.from(angularJsChangelogMd).toString('base64'),
}, },
@ -65,7 +84,9 @@ describe('workers/pr/release-notes', () => {
expect(res).toMatchSnapshot(); expect(res).toMatchSnapshot();
}); });
it('parses jest', async () => { it('parses jest', async () => {
ghGot.mockReturnValueOnce({ ghGot
.mockReturnValueOnce({ body: contentsResponse })
.mockReturnValueOnce({
body: { body: {
content: Buffer.from(jestChangelogMd).toString('base64'), content: Buffer.from(jestChangelogMd).toString('base64'),
}, },
@ -75,7 +96,9 @@ describe('workers/pr/release-notes', () => {
expect(res).toMatchSnapshot(); expect(res).toMatchSnapshot();
}); });
it('parses js-yaml', async () => { it('parses js-yaml', async () => {
ghGot.mockReturnValueOnce({ ghGot
.mockReturnValueOnce({ body: contentsResponse })
.mockReturnValueOnce({
body: { body: {
content: Buffer.from(jsYamlChangelogMd).toString('base64'), content: Buffer.from(jsYamlChangelogMd).toString('base64'),
}, },

View file

@ -895,6 +895,10 @@ chalk@^1.1.3:
strip-ansi "^3.0.0" strip-ansi "^3.0.0"
supports-color "^2.0.0" supports-color "^2.0.0"
changelog-filename-regex@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/changelog-filename-regex/-/changelog-filename-regex-1.1.1.tgz#8a2eb3049a652e3c03c8b601e3cbb032ee9f4e6d"
changelog@1.4.2: changelog@1.4.2:
version "1.4.2" version "1.4.2"
resolved "https://registry.yarnpkg.com/changelog/-/changelog-1.4.2.tgz#618abaecfaff42cf2452d52c195ff83b5589d2fe" resolved "https://registry.yarnpkg.com/changelog/-/changelog-1.4.2.tgz#618abaecfaff42cf2452d52c195ff83b5589d2fe"