Skip to content
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

feat(lifecycle): add support for lifecycle hooks stor… #167

Closed
33 changes: 29 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ var objectAssign = require('object-assign')
module.exports = function standardVersion (argv, done) {
var pkgPath = path.resolve(process.cwd(), './package.json')
var pkg = require(pkgPath)
var hooks = pkg['standard-version'] && pkg['standard-version']['hooks'] ? pkg['standard-version']['hooks'] : {}
var defaults = require('./defaults')
var args = objectAssign({}, defaults, argv)

Expand All @@ -32,16 +33,28 @@ module.exports = function standardVersion (argv, done) {
} else {
checkpoint(args, 'skip version bump on first release', [], chalk.red(figures.cross))
}

outputChangelog(args, function (err) {
runLifecycleHook(args, 'post-bump', newVersion, hooks, function (err) {
if (err) {
printError(args, err.message)
return done(err)
}
commit(args, newVersion, function (err) {

outputChangelog(args, function (err) {
if (err) {
return done(err)
}
return tag(newVersion, pkg.private, args, done)
runLifecycleHook(args, 'pre-commit', newVersion, hooks, function (err) {
if (err) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a suggestion here, as this would help my own use case which I will outline below. If you allow the lifecycle hook to mutate/return a modified args struct that could allow more flexibility. (I'm currently considering using a prepare-commit-message hook to achieve this).

My company uses PivotalTracker which uses [(Fixes|Finishes) #12312] to indicate a story is fixed in a commit and then '[Delivers #12312]to mark it as delivered and a github integration to detect the commit message and update the stories. What I'd want to do in this feature is change themessage` argument depending on all "fixed" commits since last version. (It'd be awesome if standard-version/conventional-changelog could pass all the commits it builds the changelog off to the hook as well but that might be asking for too much).

Example

Git History:

fix: Some Issue [Fixes #123]
feat: Shiny Feature [Finishes #333]
chore(release): v1.1.2

On running standard-version I ideally want the release commit to be as follows so my stories automatically get updated to the delivered (for QA) state.

chore(release): v1.2.0

[Delivers #123]
[Delivers #333]

Assuming the hook allowed us to return a modified args I could append the new messages onto the message argument.

printError(args, err.message)
return done(err)
}
commit(args, newVersion, function (err) {
if (err) {
return done(err)
}
return tag(newVersion, pkg.private, args, done)
})
})
})
})
})
Expand Down Expand Up @@ -198,6 +211,18 @@ function handledExec (argv, cmd, errorCb, successCb) {
successCb()
})
}
function runLifecycleHook (argv, hookName, newVersion, hooks, cb) {
if (!hooks[hookName]) {
cb()
return
}
var command = hooks[hookName] + ' --new-version="' + newVersion + '"'
checkpoint(argv, 'Running lifecycle hook "%s"', [hookName])
checkpoint(argv, '- hook command: "%s"', [command], chalk.blue(figures.info))
handledExec(argv, command, cb, function () {
cb()
})
}

function commit (argv, newVersion, cb) {
var msg = 'committing %s'
Expand Down
86 changes: 85 additions & 1 deletion test.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ function writePackageJson (version, option) {

function writeBowerJson (version, option) {
option = option || {}
var bower = objectAssign(option, { version: version })
var bower = objectAssign(option, {version: version})
fs.writeFileSync('bower.json', JSON.stringify(bower), 'utf-8')
}

Expand All @@ -60,6 +60,18 @@ function writeGitPreCommitHook () {
fs.chmodSync('.git/hooks/pre-commit', '755')
}

function writePostBumpHook (causeError) {
writeHook('post-bump', causeError)
}

function writeHook (hookName, causeError) {
shell.mkdir('-p', 'scripts')
var content = 'console.error("' + hookName + ' ran")'
content += causeError ? '\nthrow new Error("' + hookName + '-failure")' : ''
fs.writeFileSync('scripts/' + hookName + '.js', content, 'utf-8')
fs.chmodSync('scripts/' + hookName + '.js', '755')
}

function initInTempFolder () {
shell.rm('-rf', 'tmp')
shell.config.silent = true
Expand Down Expand Up @@ -216,6 +228,78 @@ describe('cli', function () {
})
})

describe('post-bump hook', function () {
it('should run the post-bump hook when provided', function () {
writePackageJson('1.0.0', {
'standard-version': {
'hooks': {
'post-bump': 'node scripts/post-bump'
}
}
})
writePostBumpHook()
fs.writeFileSync('CHANGELOG.md', 'legacy header format<a name="1.0.0">\n', 'utf-8')

commit('feat: first commit')
var result = execCli('--patch')
result.code.should.equal(0)
result.stderr.should.match(/post-bump ran/)
})

it('should run the post-bump and exit with error when post-bump fails', function () {
writePackageJson('1.0.0', {
'standard-version': {
'hooks': {
'post-bump': 'node scripts/post-bump'
}
}
})
writePostBumpHook(true)
fs.writeFileSync('CHANGELOG.md', 'legacy header format<a name="1.0.0">\n', 'utf-8')

commit('feat: first commit')
var result = execCli('--patch')
result.code.should.equal(1)
result.stderr.should.match(/post-bump-failure/)
})
})

describe('pre-commit hook', function () {
it('should run the pre-commit hook when provided', function () {
writePackageJson('1.0.0', {
'standard-version': {
'hooks': {
'pre-commit': 'node scripts/pre-commit'
}
}
})
writeHook('pre-commit')
fs.writeFileSync('CHANGELOG.md', 'legacy header format<a name="1.0.0">\n', 'utf-8')

commit('feat: first commit')
var result = execCli('--patch')
result.code.should.equal(0)
result.stderr.should.match(/pre-commit ran/)
})

it('should run the pre-commit hook and exit with error when pre-commit fails', function () {
writePackageJson('1.0.0', {
'standard-version': {
'hooks': {
'pre-commit': 'node scripts/pre-commit'
}
}
})
writeHook('pre-commit', true)
fs.writeFileSync('CHANGELOG.md', 'legacy header format<a name="1.0.0">\n', 'utf-8')

commit('feat: first commit')
var result = execCli('--patch')
result.code.should.equal(1)
result.stderr.should.match(/pre-commit-failure/)
})
})

describe('pre-release', function () {
it('works fine without specifying a tag id when prereleasing', function () {
writePackageJson('1.0.0')
Expand Down