From c4fc23762291ac5c9c1ffbe93f6f62bb87bc2d9d Mon Sep 17 00:00:00 2001 From: Diondra Peck <16376603+diondrapeck@users.noreply.github.com> Date: Mon, 23 Mar 2020 18:44:12 -0700 Subject: [PATCH 1/7] add changelog generator --- .../changelog_generator.js | 100 ++++++++++++++++++ misc/changelog-generator/package.json | 3 + misc/changelog-generator/utils.js | 34 ++++++ 3 files changed, 137 insertions(+) create mode 100644 misc/changelog-generator/changelog_generator.js create mode 100644 misc/changelog-generator/package.json create mode 100644 misc/changelog-generator/utils.js diff --git a/misc/changelog-generator/changelog_generator.js b/misc/changelog-generator/changelog_generator.js new file mode 100644 index 00000000..4c0bd86e --- /dev/null +++ b/misc/changelog-generator/changelog_generator.js @@ -0,0 +1,100 @@ +'use strict'; + +var utils = require("./utils.js"); + +// get log info (and latest tagest if not first release) +const child = require("child_process"); +const fs = require("fs"); +var output; + +const pastTags = child.execSync('git tag').toString('utf-8'); +if (pastTags.length) { + const latestTag = child.execSync('git describe --long').toString('utf-8').split('-')[0]; + + output = child + .execSync(`git log ${latestTag}..HEAD --format=%B%H----DELIMITER----`) + .toString("utf-8"); +} else { + output = child + .execSync(`git log --format=%B%H----DELIMITER----`) + .toString("utf-8"); +} + +if (output.length === 0) { + console.log("No new indicated changes since last tag"); + return process.exit(1); +} + +// get array of commits since last tag +const commitsArray = output +.split("----DELIMITER----\n") +.map(commit => { + const splitCommit = commit.split("\n"); + const sha = splitCommit[1], message = splitCommit[0]; + return { sha, message }; +}) +.filter(commit => Boolean(commit.sha)); + +// get current version info +const currNotes = fs.readFileSync("../../NEWS.md", "utf-8"); +const currVersion = (require("./package.json").version).split('.'); + +var major = Number(currVersion[0]), minor = Number(currVersion[1]), patch = Number(currVersion[2]); + +// sort commits by message tags +var changes = [], features = [], fixes = []; +var breakingChange = false, addedFunctionality = false, bugPatch = false; + +commitsArray.forEach(commit => { + + if (commit.message.startsWith("breaking-change:")) { + changes = utils.parseMessage("breaking-change:", changes, commit); + breakingChange = true; + } else if (commit.message.startsWith("feature:")) { + features = utils.parseMessage("feature:", features, commit); + addedFunctionality = true; + } else if (commit.message.startsWith("fix:")) { + fixes = utils.parseMessage("fix:", fixes, commit); + bugPatch = true; + } +}); + +// update package version (following semantic versioning) +if (changes.length) { + major += 1; + minor = 0; + patch = 0; +} else if (features.length) { + minor += 1; + patch = 0; +} else if (fixes.length) { + patch += 1; +} + +const newVersion = [String(major), String(minor), String(patch)].join('.'); + +// format commits into markdown +let newNotes = `# Version ${newVersion} (${ +new Date().toISOString().split("T")[0] +})\n\n`; + +if (changes.length) { + newNotes = utils.formatUpdates(newNotes, `## Breaking Changes\n`, changes); +} +if (features.length) { + newNotes = utils.formatUpdates(newNotes, `## New Features\n`, features); +} +if (fixes.length) { + newNotes = utils.formatUpdates(newNotes, `## Bug Fixes\n`, fixes); +} + +// prepend the new release notes to the current file +fs.writeFileSync("./NEWS.md", `${newNotes}${currNotes}`); + +// update version in package.json +fs.writeFileSync("./package.json", JSON.stringify({ version: String(newVersion) }, null, 2)); + +// commit and tag new version +child.execSync('git add .'); +child.execSync(`git commit -m "Bump to version ${newVersion}"`); +child.execSync(`git tag -a -m "Tag for version ${newVersion}" version${newVersion}`); diff --git a/misc/changelog-generator/package.json b/misc/changelog-generator/package.json new file mode 100644 index 00000000..5d40f048 --- /dev/null +++ b/misc/changelog-generator/package.json @@ -0,0 +1,3 @@ +{ + "version": "0.6.85" +} \ No newline at end of file diff --git a/misc/changelog-generator/utils.js b/misc/changelog-generator/utils.js new file mode 100644 index 00000000..2711d09f --- /dev/null +++ b/misc/changelog-generator/utils.js @@ -0,0 +1,34 @@ + +function parseMessage() { + const message_prefix = arguments[0]; + var commitArray = arguments[1]; + const commit = arguments[2]; + + commitArray.push( + `* ${commit.message.replace(message_prefix, "")} ([${commit.sha.substring( + 0, + 6 + )}](https://github.com/Azure/azureml-sdk-for-r/commit/${ + commit.sha + }))\n` + ); + + return commitArray +} + +function formatUpdates() { + var notes = arguments[0]; + const sectionHeading = arguments[1]; + const messages = arguments[2]; + + notes += sectionHeading; + messages.forEach(message => { + notes += message; + }); + notes += '\n'; + + return notes +} + +exports.parseMessage = parseMessage; +exports.formatUpdates = formatUpdates; \ No newline at end of file From 82f782802721b17a43db75b40982cca6ce7d103e Mon Sep 17 00:00:00 2001 From: Diondra Peck <16376603+diondrapeck@users.noreply.github.com> Date: Mon, 23 Mar 2020 18:44:37 -0700 Subject: [PATCH 2/7] add instructions --- misc/changelog-generator/instructions.md | 30 ++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 misc/changelog-generator/instructions.md diff --git a/misc/changelog-generator/instructions.md b/misc/changelog-generator/instructions.md new file mode 100644 index 00000000..5b03b7a0 --- /dev/null +++ b/misc/changelog-generator/instructions.md @@ -0,0 +1,30 @@ + +### Creating Pull Requests for Inclusion in NEWS.md + +If a PR is significant enough to warrant a mention in the next release notes update, +its name should begin with a prefix. +There are three options depending on the PR's +purpose. + + * `breaking-change: ` if the change will make the next tag non-backward-compatible + * `feature: ` if the change is a major addition that maintains backward-compatibility + * `fix: ` if the change is a bug fix, security patch, or other improvement + +If the PR does not begin with one of these prefixes, it WILL NOT be included in +the release notes, so make sure to name important PRs accordingly. + +### Generating Notes and Creating a New Tag + +To update release notes for and commit a new git tag: + +1. Navigate to this directory in while on master branch +2. Run `node changelog_generator.js` on the command line +3. Confirm version was updated in package.json and notes were added to NEWS.md +4. Push to **origin/master** (this can only be done by owners/admins). + +The generator follows semantic versioning, so: + + * If there have been breaking changes since the last tag, it will increment the 1st (major) version digit by 1 and set the 2nd (minor) and 3rd (patch) to 0. (e.g. 0.6.8 → 1.0.0) + * If there have been no breaking changes, but there have been feature additions, it will increment the minor digit by 1 and set the patch digit to 0. (e.g. 0.6.8 → 0.7.0) + * If there have been no breaking changes nor feature additions, but there have been bug fixes, it will increment the patch digit by 1. (e.g. 0.6.8 → 0.6.9) + From b062c1fd1c55051e3d46cc4400dcf4573714b602 Mon Sep 17 00:00:00 2001 From: Diondra Peck <16376603+diondrapeck@users.noreply.github.com> Date: Tue, 24 Mar 2020 08:42:35 -0700 Subject: [PATCH 3/7] make message parser case-insensitive --- misc/changelog-generator/changelog_generator.js | 6 +++--- misc/changelog-generator/utils.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/misc/changelog-generator/changelog_generator.js b/misc/changelog-generator/changelog_generator.js index 4c0bd86e..634761b8 100644 --- a/misc/changelog-generator/changelog_generator.js +++ b/misc/changelog-generator/changelog_generator.js @@ -47,13 +47,13 @@ var breakingChange = false, addedFunctionality = false, bugPatch = false; commitsArray.forEach(commit => { - if (commit.message.startsWith("breaking-change:")) { + if (commit.message.toLowerCase().startsWith("breaking-change:")) { changes = utils.parseMessage("breaking-change:", changes, commit); breakingChange = true; - } else if (commit.message.startsWith("feature:")) { + } else if (commit.message.toLowerCase().startsWith("feature:")) { features = utils.parseMessage("feature:", features, commit); addedFunctionality = true; - } else if (commit.message.startsWith("fix:")) { + } else if (commit.message.toLowerCase().startsWith("fix:")) { fixes = utils.parseMessage("fix:", fixes, commit); bugPatch = true; } diff --git a/misc/changelog-generator/utils.js b/misc/changelog-generator/utils.js index 2711d09f..9b5fdaed 100644 --- a/misc/changelog-generator/utils.js +++ b/misc/changelog-generator/utils.js @@ -5,7 +5,7 @@ function parseMessage() { const commit = arguments[2]; commitArray.push( - `* ${commit.message.replace(message_prefix, "")} ([${commit.sha.substring( + `* ${commit.message.substring(message_prefix)} ([${commit.sha.substring( 0, 6 )}](https://github.com/Azure/azureml-sdk-for-r/commit/${ From 951adeeaa08cab0bd7f19eee0ff8403d927ab799 Mon Sep 17 00:00:00 2001 From: Diondra Peck <16376603+diondrapeck@users.noreply.github.com> Date: Tue, 24 Mar 2020 08:45:11 -0700 Subject: [PATCH 4/7] fix typo --- misc/changelog-generator/changelog_generator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/changelog-generator/changelog_generator.js b/misc/changelog-generator/changelog_generator.js index 634761b8..e2435eda 100644 --- a/misc/changelog-generator/changelog_generator.js +++ b/misc/changelog-generator/changelog_generator.js @@ -2,7 +2,7 @@ var utils = require("./utils.js"); -// get log info (and latest tagest if not first release) +// get log info (and latest tag if not first release) const child = require("child_process"); const fs = require("fs"); var output; From aa3a28111d0dd18b1340c9cf39a226c384463ff4 Mon Sep 17 00:00:00 2001 From: Diondra Peck <16376603+diondrapeck@users.noreply.github.com> Date: Tue, 24 Mar 2020 08:50:48 -0700 Subject: [PATCH 5/7] add utils function descriptions and pass in args directly --- misc/changelog-generator/utils.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/misc/changelog-generator/utils.js b/misc/changelog-generator/utils.js index 9b5fdaed..2f802cd4 100644 --- a/misc/changelog-generator/utils.js +++ b/misc/changelog-generator/utils.js @@ -1,9 +1,9 @@ -function parseMessage() { - const message_prefix = arguments[0]; - var commitArray = arguments[1]; - const commit = arguments[2]; - +function parseMessage(message_prefix, commitArray, commit) { +/* + Strips commit message of prefix and pushes to returned array +*/ + commitArray.push( `* ${commit.message.substring(message_prefix)} ([${commit.sha.substring( 0, @@ -16,11 +16,11 @@ function parseMessage() { return commitArray } -function formatUpdates() { - var notes = arguments[0]; - const sectionHeading = arguments[1]; - const messages = arguments[2]; - +function formatUpdates(notes, sectionHeading, messages) { +/* + Format a section with a heading a corresponding commit messages +*/ + notes += sectionHeading; messages.forEach(message => { notes += message; From c6e573274a74e4a4301b053591844f7d4d6bcea8 Mon Sep 17 00:00:00 2001 From: Diondra Peck <16376603+diondrapeck@users.noreply.github.com> Date: Tue, 24 Mar 2020 09:39:07 -0700 Subject: [PATCH 6/7] replace "Version" with package name, edit headers to match current NEWS.md formatting --- misc/changelog-generator/changelog_generator.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/misc/changelog-generator/changelog_generator.js b/misc/changelog-generator/changelog_generator.js index e2435eda..16e71ece 100644 --- a/misc/changelog-generator/changelog_generator.js +++ b/misc/changelog-generator/changelog_generator.js @@ -74,18 +74,18 @@ if (changes.length) { const newVersion = [String(major), String(minor), String(patch)].join('.'); // format commits into markdown -let newNotes = `# Version ${newVersion} (${ +let newNotes = `# azuremlsdk ${newVersion} (${ new Date().toISOString().split("T")[0] })\n\n`; if (changes.length) { - newNotes = utils.formatUpdates(newNotes, `## Breaking Changes\n`, changes); + newNotes = utils.formatUpdates(newNotes, `## Breaking changes\n`, changes); } if (features.length) { - newNotes = utils.formatUpdates(newNotes, `## New Features\n`, features); + newNotes = utils.formatUpdates(newNotes, `## New features\n`, features); } if (fixes.length) { - newNotes = utils.formatUpdates(newNotes, `## Bug Fixes\n`, fixes); + newNotes = utils.formatUpdates(newNotes, `## Bug fixes\n`, fixes); } // prepend the new release notes to the current file From f7f0f37ed5518320d2d7aa88669112a4b06766cf Mon Sep 17 00:00:00 2001 From: Diondra Peck <16376603+diondrapeck@users.noreply.github.com> Date: Tue, 24 Mar 2020 14:36:57 -0700 Subject: [PATCH 7/7] remove booleans (unnecessary) --- misc/changelog-generator/changelog_generator.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/misc/changelog-generator/changelog_generator.js b/misc/changelog-generator/changelog_generator.js index 16e71ece..393b53b4 100644 --- a/misc/changelog-generator/changelog_generator.js +++ b/misc/changelog-generator/changelog_generator.js @@ -43,19 +43,17 @@ var major = Number(currVersion[0]), minor = Number(currVersion[1]), patch = Numb // sort commits by message tags var changes = [], features = [], fixes = []; -var breakingChange = false, addedFunctionality = false, bugPatch = false; commitsArray.forEach(commit => { if (commit.message.toLowerCase().startsWith("breaking-change:")) { changes = utils.parseMessage("breaking-change:", changes, commit); - breakingChange = true; + } else if (commit.message.toLowerCase().startsWith("feature:")) { features = utils.parseMessage("feature:", features, commit); - addedFunctionality = true; + } else if (commit.message.toLowerCase().startsWith("fix:")) { fixes = utils.parseMessage("fix:", fixes, commit); - bugPatch = true; } });