Compare commits

...
17 Commits
Author SHA1 Message Date
Stephan Bönnemann 85b35aaed3 chore(package): update last-release-npm to 1.2.1 2015-08-22 21:48:16 +02:00
Stephan Bönnemann 360a514171 feat: add fallbackTag functionality
You can now map dist-tags onto "fallbackTags". E.g. if you want a
development channel like "next" and no version is currently published as "next"
semantic-release could fallback to "latest" to determine the new "next" version.
You can specify your mappings by adding "fallbackTags" to your
`package.json`'s "release" field.
2015-08-22 21:43:22 +02:00
Stephan Bönnemann 90174c80a0 chore: adopt things for being back on master/latest 2015-08-22 20:16:34 +02:00
Stephan Bönnemann 2405453f2d docs(README): nice badge pyramid 2015-08-22 19:53:36 +02:00
Stephan Bönnemann a16c36ed4d style: branch available in options not root of config 2015-08-22 19:49:09 +02:00
Stephan Bönnemann 5cc7da6035 fix(commits): add helpful error when lastRelease not in history
Closes #61, Closes #50
2015-08-22 19:31:29 +02:00
Stephan Bönnemann a2d6db2ce5 docs(README): document verification pipelines 2015-08-22 14:55:25 +02:00
Stephan Bönnemann 700ec9d4ca feat(plugins): run verifications in series
With this new feature you can pass an array of plugin locations/names to
both "verifyConditions" and "verifyRelease" in your `package.json`'s "release"
field. This will run multiple verification plugins in series.
2015-08-22 14:52:01 +02:00
Stephan Bönnemann 7b8f632396 fix: clearer logput 2015-08-22 12:01:42 +02:00
Stephan Bönnemann b47311d565 fix: correctly obfuscate githubToken with verbose loglevel 2015-08-22 11:34:50 +02:00
Stephan Bönnemann 810b3533dd refactor(nerf-dart): use module from npm 2015-08-20 14:31:18 +02:00
Stephan Bönnemann b397ffe91f Merge pull request #58 from tlvince/get-last-release
Document the getLastRelease plugin
2015-08-18 15:13:21 +02:00
Tom Vincent 471a67fc31 docs(readme): document the getLastRelease plugin 2015-08-18 14:04:56 +01:00
Tom Vincent 557c46b8dd docs(readme): enhance plugin section grammar 2015-08-18 13:58:38 +01:00
Ari PoradandStephan Bönnemann 7ceac76689 feat(plugins): add getLastRelease hook
The code to determine the last-release is now in its own repository: https://github.com/semantic-release/last-release-npm
One can overwrite that behavior by defining a "getLastRelease" plugin. This way
one can decouple semantic-release from npm, e.g. by implementing a git-tag
based version. This is already worked on: https://github.com/semantic-release/last-release-git-tag

Closes #56
2015-08-18 13:56:24 +02:00
Stephan Bönnemann 77349fcdf1 docs(readme): add badge section 2015-08-10 22:04:21 +02:00
Stephan Bönnemann aae79cab72 docs(readme): remove table around badges 2015-08-10 21:58:45 +02:00
17 changed files with 243 additions and 179 deletions
+40 -3
View File
@@ -1,7 +1,14 @@
# semantic-release
| [![Join the chat at https://gitter.im/semantic-release/semantic-release](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/semantic-release/semantic-release?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) | [![Build Status](https://travis-ci.org/semantic-release/semantic-release.svg?branch=next)](https://travis-ci.org/semantic-release/semantic-release) | [![Coverage Status](https://coveralls.io/repos/semantic-release/semantic-release/badge.svg?branch=next&service=github)](https://coveralls.io/github/semantic-release/semantic-release?branch=next) | [![Dependency Status](https://david-dm.org/semantic-release/semantic-release/next.svg)](https://david-dm.org/semantic-release/semantic-release/next) | [![devDependency Status](https://david-dm.org/semantic-release/semantic-release/next/dev-status.svg)](https://david-dm.org/semantic-release/semantic-release/next#info=devDependencies) | [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://github.com/feross/standard) |
| --- | --- | --- | --- | --- | --- |
[![Build Status](https://travis-ci.org/semantic-release/semantic-release.svg?branch=master)](https://travis-ci.org/semantic-release/semantic-release)
[![Coverage Status](https://coveralls.io/repos/semantic-release/semantic-release/badge.svg?branch=master&service=github)](https://coveralls.io/github/semantic-release/semantic-release?branch=master)
[![Dependency Status](https://david-dm.org/semantic-release/semantic-release/master.svg)](https://david-dm.org/semantic-release/semantic-release/master)
[![devDependency Status](https://david-dm.org/semantic-release/semantic-release/master/dev-status.svg)](https://david-dm.org/semantic-release/semantic-release/master#info=devDependencies)
[![Join the chat at https://gitter.im/semantic-release/semantic-release](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/semantic-release/semantic-release?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://github.com/feross/standard)
`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 +100,7 @@ _A few notes on `npm` config_:
## 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
{
@@ -139,10 +146,18 @@ This plugin is responsible for generating release notes. Call the callback with
This plugins is responsible for verifying that a release should happen in the first place. For example, the [default implementation](https://github.com/semantic-release/condition-travis/) verifies that the publish is happening on Travis, that it's the right branch, and that all other build jobs succeeded. There are more use cases for this, e.g. verifying that test coverage is above a certain threshold or that there are no [vulnerabilities](https://nodesecurity.io/) in your dependencies. Be creative.
Passing an array of plugins will run them in series.
### `verifyRelease`
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.
Passing an array of plugins will run them in series.
### `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
> I think you might frequently ask questions like these
@@ -177,6 +192,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!
## 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`.
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
```md
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
```
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=plastic)](https://github.com/semantic-release/semantic-release)
```md
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=plastic)](https://github.com/semantic-release/semantic-release)
```
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=flat-square)](https://github.com/semantic-release/semantic-release)
```md
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=flat-square)](https://github.com/semantic-release/semantic-release)
```
## License
MIT License
+3 -7
View File
@@ -24,17 +24,19 @@
"@semantic-release/commit-analyzer": "^2.0.0",
"@semantic-release/condition-travis": "^4.0.0",
"@semantic-release/error": "^1.0.0",
"@semantic-release/last-release-npm": "^1.2.1",
"@semantic-release/release-notes-generator": "^2.0.0",
"git-head": "^1.2.1",
"github": "^0.2.4",
"lodash": "^3.9.3",
"nerf-dart": "^1.0.0",
"nopt": "^3.0.3",
"npm-registry-client": "^6.4.0",
"npmconf": "^2.1.2",
"npmlog": "^1.2.1",
"parse-github-repo-url": "^1.0.0",
"require-relative": "^0.8.7",
"run-auto": "^1.1.2",
"run-series": "^1.1.2",
"semver": "^5.0.1"
},
"devDependencies": {
@@ -64,12 +66,6 @@
],
"license": "MIT",
"main": "dist/index.js",
"publishConfig": {
"tag": "next"
},
"release": {
"branch": "next"
},
"repository": {
"type": "git",
"url": "git+https://github.com/semantic-release/semantic-release.git"
+24 -23
View File
@@ -6,7 +6,7 @@ const log = require('npmlog')
const nopt = require('nopt')
const npmconf = require('npmconf')
const PREFIX = 'semantic-release'
log.heading = 'semantic-release'
const env = process.env
const pkg = JSON.parse(readFileSync('./package.json'))
const knownOptions = {
@@ -33,7 +33,7 @@ const plugins = require('./lib/plugins')(options)
npmconf.load({}, (err, conf) => {
if (err) {
log.error(PREFIX, 'Failed to load npm config.', err)
log.error('init', 'Failed to load npm config.', err)
process.exit(1)
}
@@ -50,28 +50,29 @@ npmconf.load({}, (err, conf) => {
log.level = npm.loglevel
const config = {PREFIX, log, env, pkg, options, plugins, npm}
const config = {env, pkg, options, plugins, npm}
log.verbose(PREFIX, 'options:', _.assign({
githubToken: options.githubToken ? '***' : undefined
}), options)
log.verbose(PREFIX, 'Verifying config.')
let hide = {}
if (options.githubToken) hide.githubToken = '***'
log.verbose('init', 'options:', _.assign({}, options, hide))
log.verbose('init', 'Verifying config.')
const errors = require('./lib/verify')(config)
errors.forEach((err) => log.error(PREFIX, `${err.message} ${err.code}`))
errors.forEach((err) => log.error('init', `${err.message} ${err.code}`))
if (errors.length) process.exit(1)
if (options.argv.remain[0] === 'pre') {
log.verbose(PREFIX, 'Running pre-script.')
log.verbose(PREFIX, 'Veriying conditions.')
log.verbose('pre', 'Running pre-script.')
log.verbose('pre', 'Veriying conditions.')
plugins.verifyConditions(config, (err) => {
if (err) {
log[options.debug ? 'warn' : 'error'](PREFIX, err.message)
log[options.debug ? 'warn' : 'error']('pre', err.message)
if (!options.debug) process.exit(1)
}
const nerfDart = require('./lib/nerf-dart')(npm.registry)
const nerfDart = require('nerf-dart')(npm.registry)
let wroteNpmRc = false
if (env.NPM_TOKEN) {
@@ -86,15 +87,15 @@ npmconf.load({}, (err, conf) => {
}
conf.save('project', (err) => {
if (err) return log.error(PREFIX, 'Failed to save npm config.', err)
if (err) return log.error('pre', 'Failed to save npm config.', err)
if (wroteNpmRc) log.verbose(PREFIX, 'Wrote authToken to .npmrc.')
if (wroteNpmRc) log.verbose('pre', 'Wrote authToken to .npmrc.')
require('./pre')(config, (err, release) => {
if (err) {
log.error(PREFIX, 'Failed to determine new version.')
log.error('pre', 'Failed to determine new version.')
const args = [PREFIX, (err.code ? `${err.code} ` : '') + err.message]
const args = ['pre', (err.code ? `${err.code} ` : '') + err.message]
if (err.stack) args.push(err.stack)
log.error(...args)
process.exit(1)
@@ -102,10 +103,10 @@ npmconf.load({}, (err, conf) => {
const message = `Determined version ${release.version} as "${npm.tag}".`
log.verbose(PREFIX, message)
log.verbose('pre', message)
if (options.debug) {
log.error(PREFIX, `${message} Not publishing in debug mode.`, release)
log.error('pre', `${message} Not publishing in debug mode.`, release)
process.exit(1)
}
@@ -113,22 +114,22 @@ npmconf.load({}, (err, conf) => {
version: release.version
}), null, 2))
log.verbose(PREFIX, `Wrote version ${release.version} to package.json.`)
log.verbose('pre', `Wrote version ${release.version} to package.json.`)
})
})
})
} else if (options.argv.remain[0] === 'post') {
log.verbose(PREFIX, 'Running post-script.')
log.verbose('post', 'Running post-script.')
require('./post')(config, (err, published, release) => {
if (err) {
log.error(PREFIX, 'Failed to publish release notes.', err)
log.error('post', 'Failed to publish release notes.', err)
process.exit(1)
}
log.verbose(PREFIX, `${published ? 'Published' : 'Generated'} release notes.`, release)
log.verbose('post', `${published ? 'Published' : 'Generated'} release notes.`, release)
})
} else {
log.error(PREFIX, `Command "${options.argv.remain[0]}" not recognized. User either "pre" or "post"`)
log.error('post', `Command "${options.argv.remain[0]}" not recognized. User either "pre" or "post"`)
}
})
+55 -15
View File
@@ -1,25 +1,65 @@
const { exec } = require('child_process')
module.exports = function ({lastRelease}, cb) {
const log = require('npmlog')
const SemanticReleaseError = require('@semantic-release/error')
module.exports = function ({lastRelease, options}, cb) {
const branch = options.branch
const from = lastRelease.gitHead
const range = (from ? from + '..' : '') + 'HEAD'
exec(
`git log -E --format=%H==SPLIT==%B==END== ${range}`,
(err, stdout) => {
if (err) return cb(err)
if (!from) return extract()
cb(null, String(stdout).split('==END==\n')
exec(`git branch --contains ${from}`, (err, stdout) => {
if (err) return cb(err)
let inHistory = false
.filter((raw) => !!raw.trim())
const branches = stdout.split('\n')
.map((result) => {
if (branch === result.replace('*', '').trim()) {
inHistory = true
return null
}
return result.trim()
})
.filter(branch => !!branch)
.map((raw) => {
const data = raw.split('==SPLIT==')
return {
hash: data[0],
message: data[1]
}
}))
if (!inHistory) {
log.error('commits',
`The commit the last release of this package was derived from is no longer
in the direct history of the "${branch}" branch.
This means semantic-release can not extract the commits between now and then.
This is usually caused by force pushing or releasing from an unrelated branch.
You can recover from this error by publishing manually or restoring
the commit "${from}".` + (branches.length ?
`\nHere is a list of branches that still contain the commit in question: \n * ${branches.join('\n * ')}` :
''
))
return cb(new SemanticReleaseError('Commit not in history', 'ENOTINHISTORY'))
}
)
extract()
})
function extract () {
exec(
`git log -E --format=%H==SPLIT==%B==END== ${range}`,
(err, stdout) => {
if (err) return cb(err)
cb(null, String(stdout).split('==END==\n')
.filter((raw) => !!raw.trim())
.map((raw) => {
const data = raw.split('==SPLIT==')
return {
hash: data[0],
message: data[1]
}
}))
}
)
}
}
-26
View File
@@ -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
})
})
}
-14
View File
@@ -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), '.')
}
+25 -3
View File
@@ -1,12 +1,34 @@
const relative = require('require-relative')
const series = require('run-series')
let exports = module.exports = function (options) {
return {
var plugins = {
analyzeCommits: exports.normalize(options.analyzeCommits, '@semantic-release/commit-analyzer'),
generateNotes: exports.normalize(options.generateNotes, '@semantic-release/release-notes-generator'),
verifyConditions: exports.normalize(options.verifyConditions, '@semantic-release/condition-travis'),
verifyRelease: exports.normalize(options.verifyRelease, './plugin-noop')
getLastRelease: exports.normalize(options.getLastRelease, '@semantic-release/last-release-npm')
}
;['verifyConditions', 'verifyRelease'].forEach((plugin) => {
if (!Array.isArray(options[plugin])) {
plugins[plugin] = exports.normalize(
options[plugin],
plugin === 'verifyConditions' ?
'@semantic-release/condition-travis' :
'./plugin-noop'
)
return
}
plugins[plugin] = function (pluginOptions, cb) {
var tasks = options[plugin].map((step) => {
return exports.normalize(step, './plugin-noop').bind(null, pluginOptions)
})
series(tasks, cb)
}
})
return plugins
}
exports.normalize = function (pluginConfig, fallback) {
+3 -3
View File
@@ -2,14 +2,14 @@ const _ = require('lodash')
const auto = require('run-auto')
const semver = require('semver')
const getLastRelease = require('./lib/last-release')
const getCommits = require('./lib/commits')
const getType = require('./lib/type')
module.exports = function (config, cb) {
const {plugins} = config
const { plugins } = config
auto({
lastRelease: getLastRelease.bind(null, config),
lastRelease: plugins.getLastRelease.bind(null, config),
commits: ['lastRelease', (cb, results) => {
getCommits(_.assign({
lastRelease: results.lastRelease
+4
View File
@@ -5,6 +5,10 @@ const rawCommits = [
module.exports = {
exec: (command, cb) => {
if (/contains/.test(command)) {
return cb(null, `whatever\nmaster\n`)
}
cb(
null,
/\.\.HEAD/.test(command) ?
+3
View File
@@ -0,0 +1,3 @@
module.exports = function (config, options, cb) {
cb(new Error('a'))
}
+3
View File
@@ -0,0 +1,3 @@
module.exports = function (config, options, cb) {
cb(new Error('b'))
}
+3
View File
@@ -0,0 +1,3 @@
module.exports = function (config, options, cb) {
cb(null, 'a')
}
+3
View File
@@ -0,0 +1,3 @@
module.exports = function (config, options, cb) {
cb(null, 'b')
}
+10 -2
View File
@@ -7,7 +7,7 @@ const commits = proxyquire('../../dist/lib/commits', {
test('commits since last release', (t) => {
t.test('get all commits', (tt) => {
commits({lastRelease: {}}, (err, commits) => {
commits({lastRelease: {}, options: {branch: 'master'}}, (err, commits) => {
tt.error(err)
tt.is(commits.length, 2, 'all commits')
tt.is(commits[0].hash, 'hash-one', 'parsed hash')
@@ -18,7 +18,7 @@ test('commits since last release', (t) => {
})
t.test('get commits since hash', (tt) => {
commits({lastRelease: {gitHead: 'hash'}}, (err, commits) => {
commits({lastRelease: {gitHead: 'hash'}, options: {branch: 'master'}}, (err, commits) => {
tt.error(err)
tt.is(commits.length, 1, 'specified commits')
tt.is(commits[0].hash, 'hash-one', 'parsed hash')
@@ -28,5 +28,13 @@ test('commits since last release', (t) => {
})
})
t.test('get commits since hash', (tt) => {
commits({lastRelease: {gitHead: 'notinhistory'}, options: {branch: 'notmaster'}}, (err, commits) => {
tt.ok(err)
tt.is(err.code, 'ENOTINHISTORY')
tt.end()
})
})
t.end()
})
-79
View File
@@ -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()
})
})
})
+54 -1
View File
@@ -3,7 +3,7 @@ const test = require('tap').test
const plugins = require('../../dist/lib/plugins')
test('export plugins', (t) => {
t.plan(4)
t.plan(5)
const defaultPlugins = plugins({})
@@ -11,6 +11,59 @@ test('export plugins', (t) => {
t.is(typeof defaultPlugins.generateNotes, 'function')
t.is(typeof defaultPlugins.verifyConditions, 'function')
t.is(typeof defaultPlugins.verifyRelease, 'function')
t.is(typeof defaultPlugins.getLastRelease, 'function')
})
test('plugin pipelines', (t) => {
t.plan(3)
t.test('get all results', (tt) => {
const pipelinePlugins = plugins({
verifyRelease: [
'./dist/lib/plugin-noop',
'./.test/mocks/plugin-result-a',
'./.test/mocks/plugin-result-b'
]
})
pipelinePlugins.verifyRelease({}, (err, results) => {
tt.error(err)
tt.same(results, [undefined, 'a', 'b'])
tt.end()
})
})
t.test('get first error', (tt) => {
const pipelinePlugins = plugins({
verifyConditions: [
'./dist/lib/plugin-noop',
'./.test/mocks/plugin-error-a',
'./.test/mocks/plugin-error-b'
]
})
pipelinePlugins.verifyConditions({}, (err) => {
tt.is(err.message, 'a')
tt.end()
})
})
t.test('get error and only results before', (tt) => {
const pipelinePlugins = plugins({
verifyRelease: [
'./dist/lib/plugin-noop',
'./.test/mocks/plugin-result-a',
'./.test/mocks/plugin-error-b',
'./.test/mocks/plugin-result-b'
]
})
pipelinePlugins.verifyRelease({}, (err, results) => {
tt.is(err.message, 'b')
tt.same(results, [undefined, 'a', undefined])
tt.end()
})
})
})
test('normalize and load plugin', (t) => {
+13 -3
View File
@@ -3,18 +3,26 @@ const proxyquire = require('proxyquire')
require('../mocks/registry')
const pre = proxyquire('../../dist/pre', {
'child_process': require('../mocks/child-process')
'./lib/commits': proxyquire('../../dist/lib/commits', {
'child_process': require('../mocks/child-process')
})
})
const versions = {
available: '1.0.0'
}
const plugins = {
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 = {
registry: 'http://registry.npmjs.org/',
tag: 'latest'
}
test('full pre run', (t) => {
@@ -22,6 +30,7 @@ test('full pre run', (t) => {
tt.plan(3)
pre({
options: {branch: 'master'},
npm,
pkg: {name: 'available'},
plugins
@@ -36,6 +45,7 @@ test('full pre run', (t) => {
tt.plan(3)
pre({
options: {branch: 'master'},
npm,
pkg: {name: 'unavailable'},
plugins