-
Notifications
You must be signed in to change notification settings - Fork 40
Add changelog generator #296
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
c4fc237
82f7828
b062c1f
951adee
aa3a281
c6e5732
f7f0f37
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| 'use strict'; | ||
|
|
||
| var utils = require("./utils.js"); | ||
|
|
||
| // get log info (and latest tag 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 = []; | ||
|
|
||
| commitsArray.forEach(commit => { | ||
|
|
||
| if (commit.message.toLowerCase().startsWith("breaking-change:")) { | ||
| changes = utils.parseMessage("breaking-change:", changes, commit); | ||
|
|
||
| } else if (commit.message.toLowerCase().startsWith("feature:")) { | ||
| features = utils.parseMessage("feature:", features, commit); | ||
|
|
||
| } else if (commit.message.toLowerCase().startsWith("fix:")) { | ||
| fixes = utils.parseMessage("fix:", fixes, commit); | ||
| } | ||
| }); | ||
|
|
||
| // 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 = `# azuremlsdk ${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}`); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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. | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @diondrapeck should we add a prefix for documentation? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good point - i'll add a "documentation: " tag that won't affect the version number. |
||
| ### 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) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is likely that we will have some breaking changes while we are still in preview, but where we do not yet want to increment the major release to 1.0 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. how do you want to handle those? We could create another tag prefix specifically for this, but which digit should we increment and how? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is it possible to just not increment the major version? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if we do this: until we do a major release, we keep the major at 0, use minor to indicate breaking changes, and use the two digits of patch to indicate new features and patches. e.g. breaking change: 0.6.85 --> 0.7.00 Then, once we do our release, we can do 1.0.0 and do traditional semantic versioning from then on. @heemanshusuri for his thoughts |
||
| * 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) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought we wanted to align part of the version to the Python SDK version that we use right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe? I remember Paul asking for semantic versioning during our meeting. The issue would then be replacing the logic for generating a version # with whatever scheme the Python SDK is using - which won't really match since not all of our of breaking changes = a Python SDK breaking change. I'm not sure how we align with the Python SDK numbers while maintaining semantic versioning vis a vis our own changes. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's keep the patch and minor version increments as you have here. For major version can we just keep it at 0 for now? |
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| { | ||
| "version": "0.6.85" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
|
|
||
| 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, | ||
| 6 | ||
| )}](https://github.com/Azure/azureml-sdk-for-r/commit/${ | ||
| commit.sha | ||
| }))\n` | ||
| ); | ||
|
|
||
| return commitArray | ||
| } | ||
|
|
||
| function formatUpdates(notes, sectionHeading, messages) { | ||
| /* | ||
| Format a section with a heading a corresponding commit messages | ||
| */ | ||
|
|
||
| notes += sectionHeading; | ||
| messages.forEach(message => { | ||
| notes += message; | ||
| }); | ||
| notes += '\n'; | ||
|
|
||
| return notes | ||
| } | ||
|
|
||
| exports.parseMessage = parseMessage; | ||
| exports.formatUpdates = formatUpdates; |
Uh oh!
There was an error while loading. Please reload this page.