Compare commits

...
9 Commits
6 changed files with 99 additions and 30 deletions
-2
View File
@@ -7,8 +7,6 @@ cache:
- node_modules
notifications:
email: false
before_deploy:
- ./bin/semantic-release pre
deploy:
provider: npm
email: stephan@boennemann.me
+5 -2
View File
@@ -13,14 +13,17 @@ npm i semantic-release
Run `semantic-release pre` right before `npm publish` and `semantic-release post` right after.
The post hook is automatable in `package.json` with a "postpublish" script:
For maximum comfort you can automate this inside your `package.json`:
```json
"scripts": {
"prepublish": "semantic-release pre",
"postpublish": "semantic-release post"
}
```
This is currently not possible for the "prepublish" hook. See [npm/npm#7118](https://github.com/npm/npm/issues/7118).
Note: Even though `semantic-release` works around a limitation in npm's "prepublish" hook using it prints an error that you can *safely ignore*.
See [npm/npm#7118](https://github.com/npm/npm/issues/7118).
MIT License
2015 Stephan Bönnemann
+56 -23
View File
@@ -1,6 +1,8 @@
#!/usr/bin/env node
'use strict'
var confirm = require('confirm-simple')
var argv = require('minimist')(process.argv.slice(2), {
alias: {
d: 'debug',
@@ -12,37 +14,68 @@ var argv = require('minimist')(process.argv.slice(2), {
}
})
var npmArgv = process.env.npm_config_argv
npmArgv = npmArgv ? JSON.parse(npmArgv).cooked : []
if (~argv._.indexOf('pre')) {
// The prepublish script is also executed when the package's dependencies are installed
// In this case we abort the command and do nothing.
var npmArgv = process.env.npm_config_argv
if (npmArgv) {
npmArgv = JSON.parse(npmArgv)
if (~npmArgv.cooked.indexOf('install')) process.exit(0)
}
var publish = false
console.log('Determining new version')
// see src/restart.js
if (~npmArgv.indexOf('--semantic-release-rerun')) process.exit(0)
// the `prepublish` hook is also executed when the package is installed
// in this case we abort the command and do nothing.
if (~npmArgv.indexOf('install')) process.exit(0)
return require('../src/pre')(argv, function (err, result) {
if (err) {
console.log('Something went wrong.')
throw err
}
return confirmCI(function () {
if (~npmArgv.indexOf('publish')) publish = true
if (!result) {
console.log('Nothing changed. Not publishing.')
process.exit(1)
}
console.log('Determining new version')
console.log('Publishing v' + result)
require('../src/pre')(argv, function (err, result) {
if (err) {
console.log('Something went wrong.')
throw err
}
if (!result) {
console.log('Nothing changed. Not publishing.')
process.exit(1)
}
console.log('Publishing v' + result)
if (publish) require('../src/restart')(function (err) {
if (err) {
console.log('Something went wrong.')
throw err
}
process.exit(1)
})
})
})
}
if (~argv._.indexOf('post')) {
return require('../src/post')(argv, function (err) {
if (err) {
console.log('Something went wrong.')
throw err
}
return confirmCI(function () {
require('../src/post')(argv, function (err) {
if (err) {
console.log('Something went wrong.')
throw err
}
// see src/restart.js
if (~npmArgv.indexOf('--semantic-release-rerun')) {
console.log('Everything is alright :) npm will now print an error message that you can safely ignore.')
}
})
})
}
function confirmCI (cb) {
if (process.env.CI || argv.ci === false) return cb(null, true)
confirm('Not running in a CI enviroment. Are you sure you want to run this hook?', function (ok) {
if (!ok) process.exit(1)
cb(null, ok)
})
}
+4
View File
@@ -1,14 +1,17 @@
{
"name": "semantic-release",
"description": "semantic semver compliant package publishing",
"version": "0.0.5",
"author": "Stephan Bönnemann <stephan@boennemann.me>",
"bin": "./bin/semantic-release",
"bugs": {
"url": "https://github.com/boennemann/semantic-release/issues"
},
"dependencies": {
"confirm-simple": "^1.0.3",
"conventional-changelog": "0.0.11",
"github": "^0.2.3",
"github-url-from-git": "^1.4.0",
"minimist": "^1.1.0",
"parse-github-repo-url": "^1.0.0",
"semver": "^4.2.0"
@@ -33,6 +36,7 @@
"url": "https://github.com/boennemann/semantic-release.git"
},
"scripts": {
"prepublish": "./bin/semantic-release pre",
"postpublish": "./bin/semantic-release post",
"test": "standard"
}
+4 -3
View File
@@ -5,7 +5,8 @@ var readFile = require('fs').readFileSync
var changelog = require('conventional-changelog')
var GitHubApi = require('github')
var parse = require('parse-github-repo-url')
var parseSlug = require('parse-github-repo-url')
var parseUrl = require('github-url-from-git')
var github = new GitHubApi({
version: '3.0.0'
@@ -19,7 +20,7 @@ module.exports = function (options, cb) {
changelog({
version: pkg.version,
repository: repository,
repository: parseUrl(repository),
file: false
}, function(err, log) {
if (err) return cb(err)
@@ -27,7 +28,7 @@ module.exports = function (options, cb) {
exec('git rev-parse HEAD', function(err, hash) {
if (err) return cb(err)
var ghRepo = parse(repository)
var ghRepo = parseSlug(repository)
var release = {
owner: ghRepo[0],
repo: ghRepo[1],
+30
View File
@@ -0,0 +1,30 @@
'use strict'
var spawn = require('child_process').spawn
var exports = module.exports = function (cb) {
// npm loads package.json data before running the `prepublish` hook
// changing the version on `prepublish` has no effect
// see https://github.com/npm/npm/issues/7118
// to circumvent this behavior we are calling `npm publish` inside `prepublish`
// the package.json is then loaded again and the correct version will be published
var child = spawn('npm', ['publish', '--semantic-release-rerun'])
var handler = exports.handleCloseAndExit.bind(null, cb)
child.stdout.pipe(process.stdout)
child.stderr.pipe(process.stderr)
child.on('close', handler)
child.on('exit', handler)
child.on('error', cb)
}
exports.handleCloseAndExit = function (cb, code, signal) {
if (code === 0) return cb(null)
cb({
code: code,
signal: signal,
message: 'npm publish failed'
})
}