Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b47311d565 | ||
|
|
810b3533dd | ||
|
|
b397ffe91f | ||
|
|
471a67fc31 | ||
|
|
557c46b8dd | ||
|
|
7ceac76689 | ||
|
|
77349fcdf1 | ||
|
|
aae79cab72 |
@@ -1,7 +1,15 @@
|
|||||||
# semantic-release
|
# semantic-release
|
||||||
|
|
||||||
| [](https://gitter.im/semantic-release/semantic-release?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) | [](https://travis-ci.org/semantic-release/semantic-release) | [](https://coveralls.io/github/semantic-release/semantic-release?branch=next) | [](https://david-dm.org/semantic-release/semantic-release/next) | [](https://david-dm.org/semantic-release/semantic-release/next#info=devDependencies) | [](https://github.com/feross/standard) |
|
|
||||||
| --- | --- | --- | --- | --- | --- |
|
[](https://github.com/semantic-release/semantic-release)
|
||||||
|
[](https://github.com/feross/standard)
|
||||||
|
[](https://gitter.im/semantic-release/semantic-release?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
|
|
||||||
|
[](https://travis-ci.org/semantic-release/semantic-release)
|
||||||
|
[](https://coveralls.io/github/semantic-release/semantic-release?branch=next)
|
||||||
|
|
||||||
|
[](https://david-dm.org/semantic-release/semantic-release/next)
|
||||||
|
[](https://david-dm.org/semantic-release/semantic-release/next#info=devDependencies)
|
||||||
|
|
||||||
`semantic-release` builds upon a set of conventions to give you **fully automated, semver-compliant package publishing**. It's mostly about _commit-messages_, but you can define more _heuristics_.
|
`semantic-release` builds upon a set of conventions to give you **fully automated, semver-compliant package publishing**. It's mostly about _commit-messages_, but you can define more _heuristics_.
|
||||||
|
|
||||||
@@ -93,7 +101,7 @@ _A few notes on `npm` config_:
|
|||||||
|
|
||||||
## Plugins
|
## Plugins
|
||||||
|
|
||||||
There are four steps where you can customize the `semantic-release` behavior using plugins. A plugin is a regular [option](#options), but inside the `package.json` you can pass additional config.
|
There are numerous steps where you can customize `semantic-release`'s behaviour using plugins. A plugin is a regular [option](#options), but passed inside the `release` block of `package.json`:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -143,6 +151,10 @@ This plugins is responsible for verifying that a release should happen in the fi
|
|||||||
|
|
||||||
This plugin is responsible for verifying a release that was determined before and is about to be published. There is no default implementation. It additionally receives `nextRelease`, `lastRelease` and `commits` inside `config`. While `commits` is the same as with analyzeCommits, `nextRelease` contains a `type` (e.g. `'major'`) and the new version (e.g. `'1.0.0'`) and `lastRelease` contains the old `version`, the `gitHead` at the time of the release and the npm dist-`tag` (e.g. `'latest'`). Using this information you could [detect breaking changes](https://github.com/semantic-release/cracks) or hold back certain types of releases. Again: Be creative.
|
This plugin is responsible for verifying a release that was determined before and is about to be published. There is no default implementation. It additionally receives `nextRelease`, `lastRelease` and `commits` inside `config`. While `commits` is the same as with analyzeCommits, `nextRelease` contains a `type` (e.g. `'major'`) and the new version (e.g. `'1.0.0'`) and `lastRelease` contains the old `version`, the `gitHead` at the time of the release and the npm dist-`tag` (e.g. `'latest'`). Using this information you could [detect breaking changes](https://github.com/semantic-release/cracks) or hold back certain types of releases. Again: Be creative.
|
||||||
|
|
||||||
|
### `getLastRelease`
|
||||||
|
|
||||||
|
This plugin is responsible for determining a package's last release version. The [default implementation](https://github.com/semantic-release/last-release-npm) uses the last published version on a npm registry.
|
||||||
|
|
||||||
## ITYM*FAQ*LT
|
## ITYM*FAQ*LT
|
||||||
> I think you might frequently ask questions like these
|
> I think you might frequently ask questions like these
|
||||||
|
|
||||||
@@ -177,6 +189,28 @@ It is indeed a great idea because it _forces_ you to follow best practices. If y
|
|||||||
|
|
||||||
Note: Currently integration-tests don't run on Travis CI. If you know stuff about npm/Travis/Couch: Please help!
|
Note: Currently integration-tests don't run on Travis CI. If you know stuff about npm/Travis/Couch: Please help!
|
||||||
|
|
||||||
|
## Badge
|
||||||
|
|
||||||
|
Use this in one of your projects? Include one of these badges in your README.md to let people know that your package is published using `semantic-release`.
|
||||||
|
|
||||||
|
[](https://github.com/semantic-release/semantic-release)
|
||||||
|
|
||||||
|
```md
|
||||||
|
[](https://github.com/semantic-release/semantic-release)
|
||||||
|
```
|
||||||
|
|
||||||
|
[](https://github.com/semantic-release/semantic-release)
|
||||||
|
|
||||||
|
```md
|
||||||
|
[](https://github.com/semantic-release/semantic-release)
|
||||||
|
```
|
||||||
|
|
||||||
|
[](https://github.com/semantic-release/semantic-release)
|
||||||
|
|
||||||
|
```md
|
||||||
|
[](https://github.com/semantic-release/semantic-release)
|
||||||
|
```
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
MIT License
|
MIT License
|
||||||
|
|||||||
+2
-1
@@ -24,12 +24,13 @@
|
|||||||
"@semantic-release/commit-analyzer": "^2.0.0",
|
"@semantic-release/commit-analyzer": "^2.0.0",
|
||||||
"@semantic-release/condition-travis": "^4.0.0",
|
"@semantic-release/condition-travis": "^4.0.0",
|
||||||
"@semantic-release/error": "^1.0.0",
|
"@semantic-release/error": "^1.0.0",
|
||||||
|
"@semantic-release/last-release-npm": "^1.1.1",
|
||||||
"@semantic-release/release-notes-generator": "^2.0.0",
|
"@semantic-release/release-notes-generator": "^2.0.0",
|
||||||
"git-head": "^1.2.1",
|
"git-head": "^1.2.1",
|
||||||
"github": "^0.2.4",
|
"github": "^0.2.4",
|
||||||
"lodash": "^3.9.3",
|
"lodash": "^3.9.3",
|
||||||
|
"nerf-dart": "^1.0.0",
|
||||||
"nopt": "^3.0.3",
|
"nopt": "^3.0.3",
|
||||||
"npm-registry-client": "^6.4.0",
|
|
||||||
"npmconf": "^2.1.2",
|
"npmconf": "^2.1.2",
|
||||||
"npmlog": "^1.2.1",
|
"npmlog": "^1.2.1",
|
||||||
"parse-github-repo-url": "^1.0.0",
|
"parse-github-repo-url": "^1.0.0",
|
||||||
|
|||||||
+5
-4
@@ -52,9 +52,10 @@ npmconf.load({}, (err, conf) => {
|
|||||||
|
|
||||||
const config = {PREFIX, log, env, pkg, options, plugins, npm}
|
const config = {PREFIX, log, env, pkg, options, plugins, npm}
|
||||||
|
|
||||||
log.verbose(PREFIX, 'options:', _.assign({
|
let hide = {}
|
||||||
githubToken: options.githubToken ? '***' : undefined
|
if (options.githubToken) hide.githubToken = '***'
|
||||||
}), options)
|
|
||||||
|
log.verbose(PREFIX, 'options:', _.assign({}, options, hide))
|
||||||
log.verbose(PREFIX, 'Verifying config.')
|
log.verbose(PREFIX, 'Verifying config.')
|
||||||
|
|
||||||
const errors = require('./lib/verify')(config)
|
const errors = require('./lib/verify')(config)
|
||||||
@@ -71,7 +72,7 @@ npmconf.load({}, (err, conf) => {
|
|||||||
if (!options.debug) process.exit(1)
|
if (!options.debug) process.exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
const nerfDart = require('./lib/nerf-dart')(npm.registry)
|
const nerfDart = require('nerf-dart')(npm.registry)
|
||||||
let wroteNpmRc = false
|
let wroteNpmRc = false
|
||||||
|
|
||||||
if (env.NPM_TOKEN) {
|
if (env.NPM_TOKEN) {
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
const SemanticReleaseError = require('@semantic-release/error')
|
|
||||||
|
|
||||||
const npmlog = require('npmlog')
|
|
||||||
const RegClient = require('npm-registry-client')
|
|
||||||
|
|
||||||
module.exports = function ({pkg, npm}, cb) {
|
|
||||||
npmlog.level = npm.loglevel || 'error'
|
|
||||||
const client = new RegClient({log: npmlog})
|
|
||||||
|
|
||||||
client.get(`${npm.registry}${pkg.name.replace('/', '%2F')}`, {
|
|
||||||
auth: npm.auth
|
|
||||||
}, (err, data) => {
|
|
||||||
if (err && err.statusCode === 404) return cb(null, {})
|
|
||||||
if (err) return cb(err)
|
|
||||||
|
|
||||||
const version = data['dist-tags'][npm.tag]
|
|
||||||
|
|
||||||
if (!version) return cb(new SemanticReleaseError(`There is no release with the dist-tag "${npm.tag}" yet. Tag a version first.`, 'ENODISTTAG'))
|
|
||||||
|
|
||||||
cb(null, {
|
|
||||||
version,
|
|
||||||
gitHead: data.versions[version].gitHead,
|
|
||||||
tag: npm.tag
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
// borrowed from https://github.com/npm/npm/blob/master/lib/config/nerf-dart.js
|
|
||||||
const url = require('url')
|
|
||||||
|
|
||||||
/* istanbul ignore next */
|
|
||||||
module.exports = function toNerfDart (uri) {
|
|
||||||
let parsed = url.parse(uri)
|
|
||||||
delete parsed.protocol
|
|
||||||
delete parsed.auth
|
|
||||||
delete parsed.query
|
|
||||||
delete parsed.search
|
|
||||||
delete parsed.hash
|
|
||||||
|
|
||||||
return url.resolve(url.format(parsed), '.')
|
|
||||||
}
|
|
||||||
+2
-1
@@ -5,7 +5,8 @@ let exports = module.exports = function (options) {
|
|||||||
analyzeCommits: exports.normalize(options.analyzeCommits, '@semantic-release/commit-analyzer'),
|
analyzeCommits: exports.normalize(options.analyzeCommits, '@semantic-release/commit-analyzer'),
|
||||||
generateNotes: exports.normalize(options.generateNotes, '@semantic-release/release-notes-generator'),
|
generateNotes: exports.normalize(options.generateNotes, '@semantic-release/release-notes-generator'),
|
||||||
verifyConditions: exports.normalize(options.verifyConditions, '@semantic-release/condition-travis'),
|
verifyConditions: exports.normalize(options.verifyConditions, '@semantic-release/condition-travis'),
|
||||||
verifyRelease: exports.normalize(options.verifyRelease, './plugin-noop')
|
verifyRelease: exports.normalize(options.verifyRelease, './plugin-noop'),
|
||||||
|
getLastRelease: exports.normalize(options.getLastRelease, '@semantic-release/last-release-npm')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -2,14 +2,14 @@ const _ = require('lodash')
|
|||||||
const auto = require('run-auto')
|
const auto = require('run-auto')
|
||||||
const semver = require('semver')
|
const semver = require('semver')
|
||||||
|
|
||||||
const getLastRelease = require('./lib/last-release')
|
|
||||||
const getCommits = require('./lib/commits')
|
const getCommits = require('./lib/commits')
|
||||||
const getType = require('./lib/type')
|
const getType = require('./lib/type')
|
||||||
|
|
||||||
module.exports = function (config, cb) {
|
module.exports = function (config, cb) {
|
||||||
const {plugins} = config
|
const { plugins } = config
|
||||||
|
|
||||||
auto({
|
auto({
|
||||||
lastRelease: getLastRelease.bind(null, config),
|
lastRelease: plugins.getLastRelease.bind(null, config),
|
||||||
commits: ['lastRelease', (cb, results) => {
|
commits: ['lastRelease', (cb, results) => {
|
||||||
getCommits(_.assign({
|
getCommits(_.assign({
|
||||||
lastRelease: results.lastRelease
|
lastRelease: results.lastRelease
|
||||||
|
|||||||
@@ -1,79 +0,0 @@
|
|||||||
const { defaults } = require('lodash')
|
|
||||||
const test = require('tap').test
|
|
||||||
|
|
||||||
require('../mocks/registry')
|
|
||||||
const lastRelease = require('../../dist/lib/last-release')
|
|
||||||
|
|
||||||
const npm = {
|
|
||||||
registry: 'http://registry.npmjs.org/',
|
|
||||||
tag: 'latest'
|
|
||||||
}
|
|
||||||
|
|
||||||
test('last release from registry', (t) => {
|
|
||||||
t.plan(5)
|
|
||||||
|
|
||||||
t.test('get release from package name', (tt) => {
|
|
||||||
lastRelease({
|
|
||||||
pkg: {name: 'available'},
|
|
||||||
npm
|
|
||||||
}, (err, release) => {
|
|
||||||
tt.error(err)
|
|
||||||
tt.is(release.version, '1.33.7', 'version')
|
|
||||||
tt.is(release.gitHead, 'HEAD', 'gitHead')
|
|
||||||
tt.is(release.tag, 'latest', 'dist-tag')
|
|
||||||
|
|
||||||
tt.end()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
t.test('get release from a tagged package\'s name', (tt) => {
|
|
||||||
lastRelease({
|
|
||||||
pkg: {name: 'tagged'},
|
|
||||||
npm: defaults({tag: 'foo'}, npm)
|
|
||||||
}, (err, release) => {
|
|
||||||
tt.error(err)
|
|
||||||
tt.is(release.version, '0.8.15', 'version')
|
|
||||||
tt.is(release.gitHead, 'bar', 'gitHead')
|
|
||||||
tt.is(release.tag, 'foo', 'dist-tag')
|
|
||||||
|
|
||||||
tt.end()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
t.test('get error from an untagged package\'s name', (tt) => {
|
|
||||||
lastRelease({
|
|
||||||
pkg: {name: 'untagged'},
|
|
||||||
npm: defaults({tag: 'bar'}, npm)
|
|
||||||
}, (err) => {
|
|
||||||
tt.is(err.code, 'ENODISTTAG', 'error')
|
|
||||||
|
|
||||||
tt.end()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
t.test('get release from scoped package name', (tt) => {
|
|
||||||
lastRelease({
|
|
||||||
pkg: {name: '@scoped/available'},
|
|
||||||
npm
|
|
||||||
}, (err, release) => {
|
|
||||||
tt.error(err)
|
|
||||||
tt.is(release.version, '1.33.7', 'version')
|
|
||||||
tt.is(release.gitHead, 'HEAD', 'gitHead')
|
|
||||||
tt.is(release.tag, 'latest', 'dist-tag')
|
|
||||||
|
|
||||||
tt.end()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
t.test('get nothing from not yet published package name', (tt) => {
|
|
||||||
lastRelease({
|
|
||||||
pkg: {name: 'unavailable'},
|
|
||||||
npm
|
|
||||||
}, (err, release) => {
|
|
||||||
tt.error(err)
|
|
||||||
tt.is(release.version, undefined, 'no version')
|
|
||||||
|
|
||||||
tt.end()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
+8
-1
@@ -6,9 +6,16 @@ const pre = proxyquire('../../dist/pre', {
|
|||||||
'child_process': require('../mocks/child-process')
|
'child_process': require('../mocks/child-process')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const versions = {
|
||||||
|
available: '1.0.0'
|
||||||
|
}
|
||||||
|
|
||||||
const plugins = {
|
const plugins = {
|
||||||
verifyRelease: (release, cb) => cb(null, release),
|
verifyRelease: (release, cb) => cb(null, release),
|
||||||
analyzeCommits: (commits, cb) => cb(null, 'major')
|
analyzeCommits: (commits, cb) => cb(null, 'major'),
|
||||||
|
getLastRelease: ({ pkg }, cb) => {
|
||||||
|
cb(null, { version: versions[pkg.name] || null, gitHead: 'HEAD' })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const npm = {
|
const npm = {
|
||||||
|
|||||||
Reference in New Issue
Block a user