Skip to content

Commit

Permalink
Chore: Add release script (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
zertosh authored May 19, 2017
1 parent 56873bf commit 8fbfe73
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 2 deletions.
10 changes: 10 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,13 @@ npm test
This is an [ESLint](http://eslint.org) plugin. Documentation for the APIs that it uses can be found on ESLint's [Working with Plugins](http://eslint.org/docs/developer-guide/working-with-plugins) page.

This plugin is used to lint itself. The style is checked when `npm test` is run, and the build will fail if there are any linting errors. You can use `npm run lint -- --fix` to fix some linting errors. To run the tests without running the linter, you can use `node_modules/.bin/mocha`.

## Publishing

```bash
node build/release.js
git push --follow-tags
npm publish
```

`build/release.js` will generate a commit and tag like https://github.com/prettier/eslint-plugin-prettier/commit/56873bf2.
97 changes: 97 additions & 0 deletions build/release.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
'use strict';

const fs = require('fs');
const childProcess = require('child_process');
const path = require('path');
const semver = require('semver');
const moment = require('moment');
const PACKAGE_JSON_PATH = path.join(process.cwd(), 'package.json');
const CHANGELOG_PATH = path.join(process.cwd(), 'CHANGELOG.md');
const packageFile = require(PACKAGE_JSON_PATH);

function exec(command) {
return childProcess.execSync(command).toString().slice(0, -1);
}

const githubRepoUrl = exec('git config --get remote.origin.url').replace(
/\.git$/,
''
);

function updatePackageJson(version) {
fs.writeFileSync(
PACKAGE_JSON_PATH,
JSON.stringify(Object.assign({}, packageFile, { version }), null, 2) + '\n'
);
}

function updateChangelog(newText) {
fs.writeFileSync(CHANGELOG_PATH, newText);
}

function createGitCommit(version) {
exec(
`git commit -am 'Build: update package.json and changelog for v${version}'`
);
}

function createGitTag(version) {
exec(`git tag v${version}`);
}

function getCommitSubject(commitHash) {
return exec(`git --no-pager show -s --oneline --format=%s ${commitHash}`);
}

function getAbbreviatedCommitHash(commitHash) {
return exec(`git --no-pager show -s --oneline --format=%h ${commitHash}`);
}

function getCommitLink(commitHash) {
return `[${getAbbreviatedCommitHash(commitHash)}](${githubRepoUrl}/commit/${commitHash})`;
}

function replaceIssueLinks(message) {
return message.replace(/#(\d+)/g, `[#$1](${githubRepoUrl}/issues/$1)`);
}

const commitHashes = exec(`git log --format=%H v${packageFile.version}...HEAD`)
.split('\n')
.filter(hash => hash);

if (!commitHashes.length) {
throw new RangeError('No commits since last release');
}

const commitSubjects = commitHashes.map(getCommitSubject);
let newVersion;

if (commitSubjects.some(subject => subject.startsWith('Breaking'))) {
newVersion = semver.inc(packageFile.version, 'major');
} else if (
commitSubjects.some(
subject => subject.startsWith('Update') || subject.startsWith('New')
)
) {
newVersion = semver.inc(packageFile.version, 'minor');
} else {
newVersion = semver.inc(packageFile.version, 'patch');
}

const newChangelogHeader = `## v${newVersion} (${moment
.utc()
.format('YYYY[-]MM[-]DD')})`;
const commitLines = commitHashes.map(
hash =>
`* ${replaceIssueLinks(getCommitSubject(hash))} (${getCommitLink(hash)})`
);
const oldChangelog = fs.readFileSync(CHANGELOG_PATH).toString();
const newChangelog = oldChangelog.replace(
/^(# Changelog\n\n)/,
`$1${newChangelogHeader}\n\n${commitLines.join('\n')}\n\n`
);

updatePackageJson(newVersion);
updateChangelog(newChangelog);
createGitCommit(newVersion);
createGitTag(newVersion);
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@
"eslint-plugin-eslint-plugin": "^0.7.1",
"eslint-plugin-node": "^4.2.2",
"mocha": "^3.1.2",
"prettier": "^1.3.1"
"moment": "^2.18.1",
"prettier": "^1.3.1",
"semver": "^5.3.0"
},
"engines": {
"node": ">=4.0.0"
Expand Down
6 changes: 5 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,10 @@ mocha@^3.1.2:
mkdirp "0.5.1"
supports-color "3.1.2"

moment@^2.18.1:
version "2.18.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.18.1.tgz#c36193dd3ce1c2eed2adb7c802dbbc77a81b1c0f"

[email protected]:
version "0.7.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765"
Expand Down Expand Up @@ -901,7 +905,7 @@ rx-lite@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102"

[email protected]:
[email protected], semver@^5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"

Expand Down

0 comments on commit 8fbfe73

Please sign in to comment.