Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1db531b511 | ||
|
|
db39c796a6 | ||
|
|
1591608f83 | ||
|
|
3250b9a1af | ||
|
|
96757ac645 | ||
|
|
25828960bc | ||
|
|
8244fe9f7d | ||
|
|
d0032de737 | ||
|
|
6c6562249b | ||
|
|
25cb545ea3 | ||
|
|
0930a6e33d | ||
|
|
890255692f |
@@ -9,12 +9,14 @@
|
||||
|
||||
It fully automates your package's releases. It will determine not only which version to release, but also when – all without you wasting [cognitive resources](https://www.youtube.com/watch?v=FKTxC9pl-WM) on it.
|
||||
|
||||
[](https://www.youtube.com/watch?v=tc2UgG5L7WM&index=6&list=PLFZ5NyC0xHDaaTy6tY9p0C0jd_rRRl5Zm)
|
||||
|
||||
> This talk gives you a complete introduction to the underlying concepts plus a live demo at the end.
|
||||
|
||||
It is fully integrated into the `npm` lifecycle, so all you need to do is to configure your CI to regularly `npm publish` (i.e. for every commit).
|
||||
|
||||
It removes human decisions and emotions from version numbers and releases – suddenly, strictly following the [SemVer](http://semver.org/) spec isn't a problem anymore.
|
||||
|
||||

|
||||
|
||||
## How does it work?
|
||||
|
||||
Meaningful conventions. Instead of dumping [lols](http://whatthecommit.com/) into our commit messages, we can take some time to think about what we changed in the codebase and write it down. Following formalized conventions it this then possible to not only generate a helpful changelog, but to determine whether a new version should be released.
|
||||
@@ -40,7 +42,7 @@ After `npm` published the new version the `postpublish` step does this:
|
||||
- Generate release notes
|
||||
- Create a new [GitHub Release](https://help.github.com/articles/about-releases/) (including a git tag) with the release notes
|
||||
|
||||
Note: The default release notes are a [changelog](https://github.com/ajoslin/conventional-changelog) that is generated from git metadata, using the AngularJS commit conventions. You can [specify your own release note generator](https://github.com/boennemann/semantic-release/wiki/release-note-generation).
|
||||
Note: The default release notes are a [changelog](https://github.com/ajoslin/conventional-changelog) that is generated from git metadata, using the AngularJS commit conventions. You can [specify your own release note generator](https://github.com/boennemann/semantic-release/wiki/release-note-generation).
|
||||
|
||||
Note: This is tied to GitHub, feel free to send PRs for other services.
|
||||
|
||||
@@ -85,16 +87,19 @@ It would be preferable not to have a version field in the `package.json` at all,
|
||||
|
||||
#### Repository
|
||||
|
||||
If you haven't defined your GitHub repository in the `package.json`s [repository field](https://docs.npmjs.com/files/package.json#repository) the remote `origin`'s repository is used.
|
||||
If you haven't defined your GitHub repository in the `package.json`s [repository field](https://docs.npmjs.com/files/package.json#repository) the remote `origin`'s repository is used.
|
||||
|
||||
### CI Server
|
||||
|
||||
Inside your `.travis.yml`:
|
||||
|
||||
```yml
|
||||
```yml
|
||||
language: node_js
|
||||
node_js:
|
||||
- iojs-v1
|
||||
# If you have a more sophisticated build with multiple jobs you should have a look at
|
||||
# https://github.com/dmakhno/travis_after_all which is also configured for this
|
||||
# package. (Check the .travis.yml)
|
||||
sudo: false
|
||||
cache:
|
||||
directories:
|
||||
@@ -129,11 +134,9 @@ Note: This isn't tied to a specific service, but example configuration is provid
|
||||
|
||||
Note: You should [encrypt](http://docs.travis-ci.com/user/environment-variables/#sts=Secure Variables) your api keys and tokens.
|
||||
|
||||
Note: Your CI environment has to export `CI=true` in order for `semantic-release` not to automatically perform a dry run. Travis CI does this by default.
|
||||
Note: Your CI environment has to export `CI=true` in order for `semantic-release` not to automatically perform a dry run. Travis CI does this by default.
|
||||
|
||||
Note: It is crucial that your CI server also fetches all tags when checking out your repository. Travis CI does this by default.
|
||||
|
||||
Note: If you have a more sophisticated build with multiple jobs you should have a look at [travis-after-all](https://github.com/dmakhno/travis_after_all), which is also configured for this [package](.travis.yml).
|
||||
Note: It is crucial that your CI server also fetches all tags when checking out your repository. Travis CI does this by default.
|
||||
|
||||
## ITYM*FAQ*LT
|
||||
> I think you might frequently ask questions like these
|
||||
@@ -171,9 +174,11 @@ It is indeed a great idea because it _forces_ you to follow best practices. If y
|
||||
|
||||
### Why should I trust `semantic-release` with my releases? What if it breaks?
|
||||
|
||||
`semantic-release` has a full integration-test suite that tests _actual_ `npm` publishes and _actual_ GitHub Releases (with private registry/API) on node.js `^0.10`, `^0.12` and io.js `^1`. A new version won't get published if it doesn't pass on all these engines.
|
||||
`semantic-release` has a full integration-test suite that tests _actual_ `npm` publishes and _actual_ GitHub Releases (with private registry/API) on node.js `^0.10`, `^0.12` and io.js `^1`, `^2`. A new version won't get published if it doesn't pass on all these engines.
|
||||
|
||||
## License
|
||||
|
||||
MIT License
|
||||
MIT License
|
||||
2015 © Stephan Bönnemann and [contributors](https://github.com/boennemann/semantic-release/graphs/contributors)
|
||||
|
||||

|
||||
|
||||
@@ -31,7 +31,14 @@ var npmArgv = process.env.npm_config_argv ?
|
||||
|
||||
if (~argv._.indexOf('pre')) {
|
||||
// see src/restart.js
|
||||
if (npmArgv['semantic-release-rerun']) process.exit(0)
|
||||
if (npmArgv['semantic-release-rerun']) {
|
||||
if (!/semantically-released/.test(process.env.npm_package_version)) process.exit(0)
|
||||
|
||||
console.log('There is something wrong with your setup, as a placeholder version is about to be released.')
|
||||
console.log('Please verify that your setup is correct.')
|
||||
console.log('If you think this is a problem with semantic-release please open an issue.')
|
||||
process.exit(1)
|
||||
}
|
||||
// the `prepublish` hook is also executed when the package is installed
|
||||
// in this case we abort the command and do nothing.
|
||||
if (
|
||||
|
||||
+38
-21
@@ -1,28 +1,45 @@
|
||||
'use strict'
|
||||
|
||||
var async = require('async')
|
||||
var npmconf = require('npmconf')
|
||||
var request = require('request')
|
||||
|
||||
var efh = require('./error').efh
|
||||
|
||||
module.exports = function (pkgName, cb) {
|
||||
var encodedPkgName = pkgName.replace(/\//g, '%2F')
|
||||
request(process.env.npm_config_registry + encodedPkgName, efh(cb)(function (response, body) {
|
||||
var res = {
|
||||
version: null,
|
||||
gitHead: null,
|
||||
pkg: null
|
||||
var registry = process.env.npm_config_registry
|
||||
async.waterfall([
|
||||
npmconf.load,
|
||||
function (conf, callback) {
|
||||
var cred = conf.getCredentialsByURI(registry)
|
||||
var reqopts = {
|
||||
url: registry + pkgName.replace(/\//g, '%2F'),
|
||||
headers: {}
|
||||
}
|
||||
if (cred.token) {
|
||||
reqopts.headers.Authorization = 'Bearer ' + cred.token
|
||||
} else if (cred.auth) {
|
||||
reqopts.headers.Authorization = 'Basic ' + cred.auth
|
||||
}
|
||||
callback(null, reqopts)
|
||||
},
|
||||
request,
|
||||
function (response, body, callback) {
|
||||
var res = {
|
||||
version: null,
|
||||
gitHead: null,
|
||||
pkg: null
|
||||
}
|
||||
|
||||
if (response.statusCode === 404 || !body) return callback(null, res)
|
||||
|
||||
var pkg = JSON.parse(body)
|
||||
|
||||
if (pkg.error) return callback(pkg.error)
|
||||
|
||||
res.version = pkg['dist-tags'].latest
|
||||
res.gitHead = pkg.versions[res.version].gitHead
|
||||
res.pkg = pkg
|
||||
|
||||
callback(null, res)
|
||||
}
|
||||
|
||||
if (response.statusCode === 404 || !body) return cb(null, res)
|
||||
|
||||
var pkg = JSON.parse(body)
|
||||
|
||||
if (pkg.error) return cb(pkg.error)
|
||||
|
||||
res.version = pkg['dist-tags'].latest
|
||||
res.gitHead = pkg.versions[res.version].gitHead
|
||||
res.pkg = pkg
|
||||
|
||||
cb(null, res)
|
||||
}))
|
||||
], cb)
|
||||
}
|
||||
|
||||
+4
-1
@@ -9,6 +9,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"abbrev": "^1.0.5",
|
||||
"async": "^1.0.0",
|
||||
"conventional-changelog": "0.0.17",
|
||||
"error-first-handler": "^1.0.1",
|
||||
"git-head": "^1.2.1",
|
||||
@@ -16,6 +17,7 @@
|
||||
"github-url-from-git": "^1.4.0",
|
||||
"ini": "^1.3.2",
|
||||
"minimist": "^1.1.0",
|
||||
"npmconf": "^2.1.2",
|
||||
"parse-github-repo-url": "^1.0.0",
|
||||
"request": "^2.53.0",
|
||||
"semver": "^4.3.3"
|
||||
@@ -26,8 +28,9 @@
|
||||
"lodash.defaults": "^3.0.0",
|
||||
"nano-uid": "^0.2.0",
|
||||
"nixt": "^0.4.1",
|
||||
"nock": "^2.2.0",
|
||||
"sinopia": "^1.0.0",
|
||||
"standard": "^3.2.1",
|
||||
"standard": "^3.11.1",
|
||||
"tap-spec": "^3.0.0",
|
||||
"tape": "^4.0.0"
|
||||
},
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
_auth=dGVzdDpmb28=
|
||||
email=test@example.com
|
||||
registry=http://127.0.0.1:4873/
|
||||
//registry.npmjs.org/:_authToken=testtoken
|
||||
|
||||
@@ -4,6 +4,7 @@ var test = require('tape')
|
||||
|
||||
var createModule = require('./lib/create-module')
|
||||
|
||||
require('./tap/npm-info')(test)
|
||||
require('./scenarios/custom-analyzer')(test, createModule)
|
||||
require('./scenarios/custom-verification')(test, createModule)
|
||||
require('./scenarios/ignore')(test, createModule)
|
||||
|
||||
+26
-10
@@ -4,16 +4,15 @@ var efh = require('error-first-handler')
|
||||
var nixt = require('nixt')
|
||||
|
||||
module.exports = function (test, createModule) {
|
||||
createModule({
|
||||
repository: {},
|
||||
scripts: {
|
||||
prepublish: 'semantic-release pre --no-token'
|
||||
}
|
||||
}, efh()(function (name, cwd) {
|
||||
test('verify', function (t) {
|
||||
test('verify', function (t) {
|
||||
createModule({
|
||||
repository: {},
|
||||
scripts: {
|
||||
prepublish: 'semantic-release pre --no-token'
|
||||
}
|
||||
}, efh()(function (name, cwd) {
|
||||
t.test('verify package and options before publishing', function (t) {
|
||||
t.plan(1)
|
||||
|
||||
nixt()
|
||||
.cwd(cwd)
|
||||
.env('CI', true)
|
||||
@@ -29,6 +28,23 @@ module.exports = function (test, createModule) {
|
||||
t.error(err, 'nixt')
|
||||
})
|
||||
})
|
||||
})
|
||||
}))
|
||||
}))
|
||||
|
||||
createModule({
|
||||
version: '1.0.0-semantically-released'
|
||||
}, efh()(function (name, cwd) {
|
||||
t.test('not publishing placeholder versions', function (t) {
|
||||
t.plan(1)
|
||||
|
||||
nixt()
|
||||
.cwd(cwd)
|
||||
.env('CI', true)
|
||||
.run('npm publish --semantic-release-rerun')
|
||||
.code(1)
|
||||
.end(function (err) {
|
||||
t.error(err, 'nixt')
|
||||
})
|
||||
})
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
'use strict'
|
||||
|
||||
var nock = require('nock')
|
||||
|
||||
var npmInfo = require('../../lib/npm-info.js')
|
||||
|
||||
var registry = 'http://registry.npmjs.org/'
|
||||
|
||||
var defaultModule = {
|
||||
'dist-tags': {
|
||||
latest: '1.0.0'
|
||||
},
|
||||
versions: {
|
||||
'1.0.0': {
|
||||
gitHead: 'HEAD'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
process.env.npm_config_registry = registry
|
||||
|
||||
module.exports = function (test) {
|
||||
test('npm-info', function (t) {
|
||||
var regMock = nock(registry, {
|
||||
reqheaders: {
|
||||
'authorization': 'Bearer testtoken'
|
||||
}
|
||||
})
|
||||
.get('/express')
|
||||
.reply(200, defaultModule)
|
||||
.get('/@user%2Fmodule')
|
||||
.reply(200, defaultModule)
|
||||
|
||||
t.test('get unscoped module', function (t) {
|
||||
t.plan(3)
|
||||
npmInfo('express', function (err, info) {
|
||||
t.error(err, 'error')
|
||||
t.is(info.version, '1.0.0', 'version')
|
||||
t.is(info.gitHead, 'HEAD', 'gitHead')
|
||||
})
|
||||
})
|
||||
t.test('get scoped module', function (t) {
|
||||
t.plan(3)
|
||||
npmInfo('@user/module', function (err, info) {
|
||||
t.error(err, 'error')
|
||||
t.is(info.version, '1.0.0', 'version')
|
||||
t.is(info.gitHead, 'HEAD', 'gitHead')
|
||||
regMock.done()
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user