Merge branch 'caribou' into greenkeeper-tap-4.0.0

This commit is contained in:
Stephan Bönnemann 2015-12-31 15:16:38 +01:00
commit bb63f9de41
29 changed files with 474 additions and 461 deletions

7
.gitignore vendored
View File

@ -1,14 +1,9 @@
# common
coverage
node_modules
test/registry/couch
test/registry/data
test/tmp
*.log
*.dump
.DS_Store
.nyc_output
.test
.tmp
# build-artifacts
dist

View File

@ -1,18 +0,0 @@
# common
coverage
node_modules
test/registry/couch
test/registry/data
*.log
*.dump
.DS_Store
.nyc_output
.test
.tmp
# source/config
src
*.yml
.gitignore
.editorconfig
.npmrc

View File

@ -6,10 +6,9 @@ cache:
notifications:
email: false
node_js:
- v5
- v4
- iojs-v2
- iojs-v1
- 5
- 4
- iojs
- '0.12'
- '0.10'
before_install:
@ -19,3 +18,5 @@ before_script:
after_success:
- npm run coverage:upload
- npm run semantic-release
services:
- couchdb

View File

@ -257,9 +257,7 @@ 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?
`semantic-release` has a full unit- and integration-test-suite that tests _actual_ `npm` publishes against the [npm-registry-couchapp](https://github.com/npm/npm-registry-couchapp/) on node.js `^0.10`, `^0.12` and io.js `^1`, `^2`. A new version wont get published if it doesnt pass on all these engines.
Note: Currently integration-tests dont run on Travis CI. If you know stuff about npm/Travis/Couch: Please help!
`semantic-release` has a full unit- and integration-test-suite that tests _actual_ `npm` publishes against the [npm-registry-couchapp](https://github.com/npm/npm-registry-couchapp/) on all major node.js versions from `^0.10` on. A new version wont get published if it doesnt pass on all these engines.
## Badge

View File

@ -1,13 +1,163 @@
#!/usr/bin/env node
/* istanbul ignore next */
var fs = require('fs')
var path = require('path')
var url = require('url')
var _ = require('lodash')
var log = require('npmlog')
var nopt = require('nopt')
var npmconf = require('npmconf')
var normalizeData = require('normalize-package-data')
log.heading = 'semantic-release'
var env = process.env
var pkg = JSON.parse(fs.readFileSync('./package.json'))
normalizeData(pkg)
var knownOptions = {
branch: String,
debug: Boolean,
'github-token': String,
'github-url': String,
'analyze-commits': [path, String],
'generate-notes': [path, String],
'verify-conditions': [path, String],
'verify-release': [path, String]
}
var options = _.defaults(
_.mapKeys(nopt(knownOptions), function (value, key) {
return _.camelCase(key)
}),
pkg.release,
{
branch: 'master',
fallbackTags: {
next: 'latest'
},
debug: !env.CI,
githubToken: env.GH_TOKEN || env.GITHUB_TOKEN,
githubUrl: env.GH_URL
}
)
var plugins = require('../src/lib/plugins')(options)
npmconf.load({}, function (err, conf) {
if (err) {
log.error('init', 'Failed to load npm config.', err)
process.exit(1)
}
var npm = {
auth: {
token: env.NPM_TOKEN
},
loglevel: conf.get('loglevel'),
registry: require('../src/lib/get-registry')(pkg, conf),
tag: (pkg.publishConfig || {}).tag || conf.get('tag') || 'latest'
}
// normalize trailing slash
npm.registry = url.format(url.parse(npm.registry))
log.level = npm.loglevel
var config = {
env: env,
pkg: pkg,
options: options,
plugins: plugins,
npm: npm
}
var hide = {}
if (options.githubToken) hide.githubToken = '***'
log.verbose('init', 'options:', _.assign({}, options, hide))
log.verbose('init', 'Verifying config.')
var errors = require('../src/lib/verify')(config)
errors.forEach(function (err) {
log.error('init', err.message + ' ' + err.code)
})
if (errors.length) process.exit(1)
if (options.argv.remain[0] === 'pre') {
log.verbose('pre', 'Running pre-script.')
log.verbose('pre', 'Veriying conditions.')
plugins.verifyConditions(config, function (err) {
if (err) {
log[options.debug ? 'warn' : 'error']('pre', err.message)
if (!options.debug) process.exit(1)
}
var nerfDart = require('nerf-dart')(npm.registry)
var wroteNpmRc = false
if (env.NPM_OLD_TOKEN && env.NPM_EMAIL) {
// Using the old auth token format is not considered part of the public API
// This might go away anytime (i.e. once we have a better testing strategy)
conf.set('_auth', '${NPM_OLD_TOKEN}', 'project')
conf.set('email', '${NPM_EMAIL}', 'project')
wroteNpmRc = true
} else if (env.NPM_TOKEN) {
conf.set(nerfDart + ':_authToken', '${NPM_TOKEN}', 'project')
wroteNpmRc = true
}
conf.save('project', function (err) {
if (err) return log.error('pre', 'Failed to save npm config.', err)
if (wroteNpmRc) log.verbose('pre', 'Wrote authToken to .npmrc.')
require('../src/pre')(config, function (err, release) {
if (err) {
log.error('pre', 'Failed to determine new version.')
var args = ['pre', (err.code ? err.code + ' ' : '') + err.message]
if (err.stack) args.push(err.stack)
log.error.apply(log, args)
process.exit(1)
}
var message = 'Determined version ' + release.version + ' as "' + npm.tag + '".'
log.verbose('pre', message)
if (options.debug) {
log.error('pre', message + ' Not publishing in debug mode.', release)
process.exit(1)
}
try {
require('../dist')
} catch (err) {
if (err.code === 'MODULE_NOT_FOUND') {
require('babel/register')
require('../src')
var shrinkwrap = JSON.parse(fs.readFileSync('./npm-shrinkwrap.json'))
shrinkwrap.version = release.version
fs.writeFileSync('./npm-shrinkwrap.json', JSON.stringify(shrinkwrap, null, 2))
log.verbose('pre', 'Wrote version ' + release.version + 'to npm-shrinkwrap.json.')
} catch (e) {
log.silly('pre', 'Couldn\'t find npm-shrinkwrap.json.')
}
fs.writeFileSync('./package.json', JSON.stringify(_.assign(pkg, {
version: release.version
}), null, 2))
log.verbose('pre', 'Wrote version ' + release.version + ' to package.json.')
})
})
})
} else if (options.argv.remain[0] === 'post') {
log.verbose('post', 'Running post-script.')
require('../src/post')(config, function (err, published, release) {
if (err) {
log.error('post', 'Failed to publish release notes.', err)
process.exit(1)
}
log.verbose('post', (published ? 'Published' : 'Generated') + ' release notes.', release)
})
} else {
console.log(err)
}
log.error('post', 'Command "' + options.argv.remain[0] + '" not recognized. User either "pre" or "post"')
}
})

View File

@ -1,21 +1,14 @@
{
"name": "semantic-release",
"description": "automated semver compliant package publishing",
"version": "0.0.0-placeholder",
"author": "Stephan Bönnemann <stephan@boennemann.me> (http://boennemann.me)",
"bin": {
"semantic-release": "./bin/semantic-release.js"
"semantic-release": "bin/semantic-release.js"
},
"bugs": {
"url": "https://github.com/semantic-release/semantic-release/issues"
},
"config": {
"nyc": {
"exclude": [
".test",
"node_modules"
]
}
},
"czConfig": {
"path": "node_modules/cz-conventional-changelog/"
},
@ -40,7 +33,6 @@
"semver": "^5.0.3"
},
"devDependencies": {
"babel": "^5.8.21",
"coveralls": "^2.11.4",
"cz-conventional-changelog": "^1.1.4",
"mkdirp": "^0.5.1",
@ -49,7 +41,7 @@
"npm-registry-couchapp": "^2.6.11",
"nyc": "^5.0.0",
"proxyquire": "^1.7.3",
"rimraf": "^2.4.3",
"rimraf": "^2.5.0",
"standard": "^5.3.0",
"tap": "^4.0.0"
},
@ -70,7 +62,11 @@
"version"
],
"license": "MIT",
"main": "dist/index.js",
"main": "bin/semantic-release.js",
"files": [
"bin",
"src"
],
"publishConfig": {
"tag": "next"
},
@ -82,17 +78,12 @@
"url": "git+https://github.com/semantic-release/semantic-release.git"
},
"scripts": {
"build": "rimraf dist && mkdirp dist && babel src --out-dir dist",
"coverage": "nyc report",
"coverage:upload": "npm run coverage -- --reporter=lcovonly && coveralls < coverage/lcov.info",
"prepublish": "npm run build",
"pretest:integration": "npm run build && npm run test:build",
"pretest:unit": "npm run build && npm run test:build",
"semantic-release": "./bin/semantic-release.js pre && npm dedupe && npm publish && ./bin/semantic-release.js post",
"test": "npm run test:style && npm run test:unit",
"test:build": "rimraf .test && mkdirp .test && babel test --out-dir .test",
"test:integration": "tap --no-cov .test/scenarios/*.js",
"test:style": "standard",
"test:unit": "nyc tap --no-cov .test/specs/*.js"
"coverage:upload": "npm run coverage -s -- --reporter=text-lcov | coveralls",
"pretest": "standard",
"semantic-release": "./bin/semantic-release.js pre && npm publish && ./bin/semantic-release.js post",
"test": "npm run test:unit && npm run test:integration",
"test:integration": "tap --no-cov test/scenarios/*.js",
"test:unit": "nyc tap --no-cov test/specs/*.js"
}
}

View File

@ -1,150 +0,0 @@
const { readFileSync, writeFileSync } = require('fs')
const path = require('path')
const url = require('url')
const _ = require('lodash')
const log = require('npmlog')
const nopt = require('nopt')
const npmconf = require('npmconf')
const normalizeData = require('normalize-package-data')
log.heading = 'semantic-release'
const env = process.env
const pkg = normalizeData(readFileSync('./package.json'))
const knownOptions = {
branch: String,
debug: Boolean,
'github-token': String,
'github-url': String,
'analyze-commits': [path, String],
'generate-notes': [path, String],
'verify-conditions': [path, String],
'verify-release': [path, String]
}
const options = _.defaults(
_.mapKeys(nopt(knownOptions), (value, key) => _.camelCase(key)),
pkg.release,
{
branch: 'master',
fallbackTags: {
next: 'latest'
},
debug: !env.CI,
githubToken: env.GH_TOKEN || env.GITHUB_TOKEN,
githubUrl: env.GH_URL
}
)
const plugins = require('./lib/plugins')(options)
npmconf.load({}, (err, conf) => {
if (err) {
log.error('init', 'Failed to load npm config.', err)
process.exit(1)
}
let npm = {
auth: {
token: env.NPM_TOKEN
},
loglevel: conf.get('loglevel'),
registry: require('./lib/get-registry')(pkg, conf),
tag: (pkg.publishConfig || {}).tag || conf.get('tag') || 'latest'
}
// normalize trailing slash
npm.registry = url.format(url.parse(npm.registry))
log.level = npm.loglevel
const config = {env, pkg, options, plugins, npm}
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('init', `${err.message} ${err.code}`))
if (errors.length) process.exit(1)
if (options.argv.remain[0] === 'pre') {
log.verbose('pre', 'Running pre-script.')
log.verbose('pre', 'Veriying conditions.')
plugins.verifyConditions(config, (err) => {
if (err) {
log[options.debug ? 'warn' : 'error']('pre', err.message)
if (!options.debug) process.exit(1)
}
const nerfDart = require('nerf-dart')(npm.registry)
let wroteNpmRc = false
if (env.NPM_TOKEN) {
conf.set(`${nerfDart}:_authToken`, '${NPM_TOKEN}', 'project')
wroteNpmRc = true
} else if (env.NPM_OLD_TOKEN && env.NPM_EMAIL) {
// Using the old auth token format is not considered part of the public API
// This might go away anytime (i.e. once we have a better testing strategy)
conf.set('_auth', '${NPM_OLD_TOKEN}', 'project')
conf.set('email', '${NPM_EMAIL}', 'project')
wroteNpmRc = true
}
conf.save('project', (err) => {
if (err) return log.error('pre', 'Failed to save npm config.', err)
if (wroteNpmRc) log.verbose('pre', 'Wrote authToken to .npmrc.')
require('./pre')(config, (err, release) => {
if (err) {
log.error('pre', 'Failed to determine new version.')
const args = ['pre', (err.code ? `${err.code} ` : '') + err.message]
if (err.stack) args.push(err.stack)
log.error(...args)
process.exit(1)
}
const message = `Determined version ${release.version} as "${npm.tag}".`
log.verbose('pre', message)
if (options.debug) {
log.error('pre', `${message} Not publishing in debug mode.`, release)
process.exit(1)
}
try {
let shrinkwrap = JSON.parse(readFileSync('./npm-shrinkwrap.json'))
shrinkwrap.version = release.version
writeFileSync('./npm-shrinkwrap.json', JSON.stringify(shrinkwrap, null, 2))
log.verbose('pre', `Wrote version ${release.version} to npm-shrinkwrap.json.`)
} catch (e) {
log.silly('pre', `Couldn't find npm-shrinkwrap.json.`)
}
writeFileSync('./package.json', JSON.stringify(_.assign(pkg, {
version: release.version
}), null, 2))
log.verbose('pre', `Wrote version ${release.version} to package.json.`)
})
})
})
} else if (options.argv.remain[0] === 'post') {
log.verbose('post', 'Running post-script.')
require('./post')(config, (err, published, release) => {
if (err) {
log.error('post', 'Failed to publish release notes.', err)
process.exit(1)
}
log.verbose('post', `${published ? 'Published' : 'Generated'} release notes.`, release)
})
} else {
log.error('post', `Command "${options.argv.remain[0]}" not recognized. User either "pre" or "post"`)
}
})

View File

@ -1,39 +1,43 @@
const { exec } = require('child_process')
var exec = require('child_process').exec
const log = require('npmlog')
var log = require('npmlog')
const SemanticReleaseError = require('@semantic-release/error')
var SemanticReleaseError = require('@semantic-release/error')
module.exports = function ({lastRelease, options}, cb) {
const branch = options.branch
const from = lastRelease.gitHead
const range = (from ? from + '..' : '') + 'HEAD'
module.exports = function (config, cb) {
var lastRelease = config.lastRelease
var options = config.options
var branch = options.branch
var from = lastRelease.gitHead
var range = (from ? from + '..' : '') + 'HEAD'
if (!from) return extract()
exec(`git branch --contains ${from}`, (err, stdout) => {
let inHistory = false
let branches
exec('git branch --contains ' + from, function (err, stdout) {
var inHistory = false
var branches
if (!err && stdout) {
branches = stdout.split('\n')
.map((result) => {
.map(function (result) {
if (branch === result.replace('*', '').trim()) {
inHistory = true
return null
}
return result.trim()
})
.filter(branch => !!branch)
.filter(function (branch) {
return !!branch
})
}
if (!inHistory) {
log.error('commits',
`The commit the last release of this package was derived from is not 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, releasing from an unrelated branch, or using an already existing package name.
You can recover from this error by publishing manually or restoring the commit "${from}".` + (branches && branches.length
? `\nHere is a list of branches that still contain the commit in question: \n * ${branches.join('\n * ')}`
'The commit the last release of this package was derived from is not in the direct history of the "' + branch + '" branch.\n' +
'This means semantic-release can not extract the commits between now and then.\n' +
'This is usually caused by force pushing, releasing from an unrelated branch, or using an already existing package name.\n' +
'You can recover from this error by publishing manually or restoring the commit "' + from + '".' + (branches && 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'))
@ -44,16 +48,18 @@ You can recover from this error by publishing manually or restoring the commit "
function extract () {
exec(
`git log -E --format=%H==SPLIT==%B==END== ${range}`,
(err, stdout) => {
'git log -E --format=%H==SPLIT==%B==END== ' + range,
function (err, stdout) {
if (err) return cb(err)
cb(null, String(stdout).split('==END==\n')
.filter((raw) => !!raw.trim())
.filter(function (raw) {
return !!raw.trim()
})
.map((raw) => {
const data = raw.split('==SPLIT==')
.map(function (raw) {
var data = raw.split('==SPLIT==')
return {
hash: data[0],
message: data[1]

View File

@ -3,8 +3,8 @@ module.exports = function (pkg, conf) {
if (pkg.name[0] !== '@') return conf.get('registry') || 'https://registry.npmjs.org/'
const scope = pkg.name.split('/')[0]
const scopedRegistry = conf.get(`${scope}/registry`)
var scope = pkg.name.split('/')[0]
var scopedRegistry = conf.get(scope + '/registry')
if (scopedRegistry) return scopedRegistry

View File

@ -1,14 +1,14 @@
const relative = require('require-relative')
const series = require('run-series')
var relative = require('require-relative')
var series = require('run-series')
let exports = module.exports = function (options) {
var exports = module.exports = function (options) {
var plugins = {
analyzeCommits: exports.normalize(options.analyzeCommits, '@semantic-release/commit-analyzer'),
generateNotes: exports.normalize(options.generateNotes, '@semantic-release/release-notes-generator'),
getLastRelease: exports.normalize(options.getLastRelease, '@semantic-release/last-release-npm')
}
;['verifyConditions', 'verifyRelease'].forEach((plugin) => {
;['verifyConditions', 'verifyRelease'].forEach(function (plugin) {
if (!Array.isArray(options[plugin])) {
plugins[plugin] = exports.normalize(
options[plugin],
@ -20,7 +20,7 @@ let exports = module.exports = function (options) {
}
plugins[plugin] = function (pluginOptions, cb) {
var tasks = options[plugin].map((step) => {
var tasks = options[plugin].map(function (step) {
return exports.normalize(step, './plugin-noop').bind(null, pluginOptions)
})

View File

@ -1,9 +1,10 @@
const SemanticReleaseError = require('@semantic-release/error')
var SemanticReleaseError = require('@semantic-release/error')
module.exports = function (config, cb) {
const { plugins, lastRelease } = config
var plugins = config.plugins
var lastRelease = config.lastRelease
plugins.analyzeCommits(config, (err, type) => {
plugins.analyzeCommits(config, function (err, type) {
if (err) return cb(err)
if (!type) {

View File

@ -1,9 +1,12 @@
const parseSlug = require('parse-github-repo-url')
var parseSlug = require('parse-github-repo-url')
const SemanticReleaseError = require('@semantic-release/error')
var SemanticReleaseError = require('@semantic-release/error')
module.exports = function ({pkg, options, env}) {
let errors = []
module.exports = function (config) {
var pkg = config.pkg
var options = config.options
var env = config.env
var errors = []
if (!pkg.name) {
errors.push(new SemanticReleaseError(

View File

@ -1,32 +1,34 @@
const url = require('url')
var url = require('url')
const gitHead = require('git-head')
const GitHubApi = require('github')
const parseSlug = require('parse-github-repo-url')
var gitHead = require('git-head')
var GitHubApi = require('github')
var parseSlug = require('parse-github-repo-url')
module.exports = function (config, cb) {
const { pkg, options, plugins } = config
const ghConfig = options.githubUrl ? url.parse(options.githubUrl) : {}
var pkg = config.pkg
var options = config.options
var plugins = config.plugins
var ghConfig = options.githubUrl ? url.parse(options.githubUrl) : {}
const github = new GitHubApi({
var github = new GitHubApi({
version: '3.0.0',
port: ghConfig.port,
protocol: (ghConfig.protocol || '').split(':')[0] || null,
host: ghConfig.hostname
})
plugins.generateNotes(config, (err, log) => {
plugins.generateNotes(config, function (err, log) {
if (err) return cb(err)
gitHead((err, hash) => {
gitHead(function (err, hash) {
if (err) return cb(err)
const ghRepo = parseSlug(pkg.repository.url)
const release = {
var ghRepo = parseSlug(pkg.repository.url)
var release = {
owner: ghRepo[0],
repo: ghRepo[1],
name: `v${pkg.version}`,
tag_name: `v${pkg.version}`,
name: 'v' + pkg.version,
tag_name: 'v' + pkg.version,
target_commitish: hash,
draft: !!options.debug,
body: log
@ -41,7 +43,7 @@ module.exports = function (config, cb) {
token: options.githubToken
})
github.releases.createRelease(release, (err) => {
github.releases.createRelease(release, function (err) {
if (err) return cb(err)
cb(null, true, release)

View File

@ -1,32 +1,32 @@
const _ = require('lodash')
const auto = require('run-auto')
const semver = require('semver')
var _ = require('lodash')
var auto = require('run-auto')
var semver = require('semver')
const getCommits = require('./lib/commits')
const getType = require('./lib/type')
var getCommits = require('./lib/commits')
var getType = require('./lib/type')
module.exports = function (config, cb) {
const { plugins } = config
var plugins = config.plugins
auto({
lastRelease: plugins.getLastRelease.bind(null, config),
commits: ['lastRelease', (cb, results) => {
commits: ['lastRelease', function (cb, results) {
getCommits(_.assign({
lastRelease: results.lastRelease
}, config),
cb)
}],
type: ['commits', 'lastRelease', (cb, results) => {
type: ['commits', 'lastRelease', function (cb, results) {
getType(_.assign({
commits: results.commits,
lastRelease: results.lastRelease
}, config),
cb)
}]
}, (err, results) => {
}, function (err, results) {
if (err) return cb(err)
const nextRelease = {
var nextRelease = {
type: results.type,
version: results.type === 'initial'
? '1.0.0'
@ -36,8 +36,8 @@ module.exports = function (config, cb) {
plugins.verifyRelease(_.assign({
commits: results.commits,
lastRelease: results.lastRelease,
nextRelease
}, config), (err) => {
nextRelease: nextRelease
}, config), function (err) {
if (err) return cb(err)
cb(null, nextRelease)
})

View File

@ -1,4 +1,4 @@
const nixt = require('nixt')
var nixt = require('nixt')
module.exports = function (cwd, uri) {
return nixt()
@ -7,8 +7,6 @@ module.exports = function (cwd, uri) {
.env('NPM_EMAIL', 'integration@test.com')
.env('GH_TOKEN', 'ghtoken')
.env('CI', 'true')
.env('TRAVIS', 'true')
.env('TRAVIS_BRANCH', 'master')
.env('npm_config_registry', uri)
.clone()
}

View File

@ -1,40 +1,31 @@
const { exec } = require('child_process')
const { join } = require('path')
const { writeFileSync } = require('fs')
var exec = require('child_process').exec
var join = require('path').join
var writeFileSync = require('fs').writeFileSync
const mkdirp = require('mkdirp')
var mkdirp = require('mkdirp')
module.exports = function (name, cb) {
const cwd = join(__dirname, '../tmp', name)
module.exports = function (name, registry, cb) {
var cwd = join(__dirname, '../tmp', name)
mkdirp.sync(cwd)
writeFileSync(join(cwd, '.npmrc'), `
//localhost:1337/registry/_design/app/_rewrite/:username=integration
//localhost:1337/registry/_design/app/_rewrite/:email=integration@test.com`, null, 2)
writeFileSync(join(cwd, 'package.json'), JSON.stringify({
name,
name: name,
repository: {
url: 'git+https://github.com/semantic-release/test'
},
_npmUser: {
name: 'integration',
email: 'integration@test.com'
},
maintainers: [{
name: 'integration',
email: 'integration@test.com'
}]
release: {
verifyConditions: '../../../src/lib/plugin-noop'
}
}, null, 2))
exec(`
git init &&
git config user.email "integration@test" &&
git config user.name "Integration Test" &&
git add . &&
git commit -m "chore: root"`
, {cwd}, (err, stdout, stderr) => {
exec(
'git init && ' +
'git config user.email "integration@test" && ' +
'git config user.name "Integration Test" && ' +
'git add . && ' +
'git commit -m "chore: root"'
, {cwd: cwd}, function (err, stdout, stderr) {
if (err) {
console.log(stdout, stderr)
return cb(err)

View File

@ -4,10 +4,10 @@ const rawCommits = [
]
module.exports = {
exec: (command, cb) => {
exec: function (command, cb) {
if (/contains/.test(command)) {
if (/notinhistory/.test(command)) return cb(new Error())
return cb(null, `whatever\nmaster\n`)
return cb(null, 'whatever\nmaster\n')
}
cb(

View File

@ -1,6 +1,12 @@
module.exports = () => ({
authenticate: () => true,
module.exports = function () {
return {
authenticate: function () {
return true
},
releases: {
createRelease: (release, cb) => cb(null)
createRelease: function (release, cb) {
cb(null)
}
}
}
}
})

View File

@ -1,12 +1,11 @@
const { exec } = require('child_process')
const { join } = require('path')
var exec = require('child_process').exec
const opts = {
cwd: join(__dirname, '../../test/registry')
var opts = {
cwd: __dirname
}
module.exports = {
start: exec.bind(null, './start.sh', opts),
stop: exec.bind(null, './stop.sh', opts),
uri: 'http://localhost:15986/registry/_design/app/_rewrite/'
uri: 'http://localhost:' + (process.env.TRAVIS === 'true' ? 5984 : 15986) + '/registry/_design/app/_rewrite/'
}

View File

@ -7,19 +7,23 @@ cd $(dirname $0)
mkdir -p couch
# start couchdb as a background process, load local config, specify writable logfiles
if [[ $TRAVIS = true ]]
then
echo 'starting couch with sudo'
sudo couchdb -b -a local.ini -p couch/pid -o couch/stdout.log -e couch/stderr.log
COUCH=http://admin:password@127.0.0.1:5984
curl -X PUT http://127.0.0.1:5984/_config/admins/admin -d '"password"'
curl -X PUT $COUCH/_config/couchdb/delayed_commits -d '"false"'
curl -X PUT $COUCH/_config/couch_httpd_auth/users_db_public -d '"true"'
curl -X PUT $COUCH/_config/couch_httpd_auth/public_fields -d '"appdotnet, avatar, avatarMedium, avatarLarge, date, email, fields, freenode, fullname, github, homepage, name, roles, twitter, type, _id, _rev"'
curl -X PUT $COUCH/_config/httpd/secure_rewrites -d '"false"'
else
couchdb -b -a local.ini -p couch/pid -o couch/stdout.log -e couch/stderr.log
fi
# wait for couch to start
sleep 5
COUCH=http://admin:password@127.0.0.1:15986
couchdb -b -a local.ini -p couch/pid -o couch/stdout.log -e couch/stderr.log
# wait for couch to start
sleep 1
fi
# create "registry" database
curl -X PUT $COUCH/registry

View File

@ -8,5 +8,6 @@ cd $(dirname $0)
cat couch/{couch,stdout,stderr}.log
cat couch/pid | xargs kill
rm -rf couch
rm -rf data

View File

@ -1,30 +1,27 @@
const { join } = require('path')
var join = require('path').join
const { test, tearDown } = require('tap')
const rimraf = require('rimraf')
var tap = require('tap')
var rimraf = require('rimraf')
const registry = require('../registry')
const testModule = require('../lib/test-module')
const baseScenario = require('../lib/base-scenario')
var registry = require('../registry')
var testModule = require('../lib/test-module')
var baseScenario = require('../lib/base-scenario')
test('change version', (t) => {
var tearDown = tap.tearDown
var test = tap.test
test('change version', {bail: process.env.TRAVIS === 'true'}, function (t) {
t.plan(7)
registry.start((err) => {
registry.start(function (err, stdout, stderr) {
t.error(err, 'registry started')
if (err) {
t.end()
t.bailout('registry not started')
}
if (err) return t.end()
testModule('change-version', (err, cwd) => {
testModule('change-version', registry.uri, function (err, cwd) {
t.error(err, 'test-module created')
if (err) {
t.end()
t.bailout('test-module not created')
}
if (err) return t.end()
t.test('no version', (tt) => {
t.test('no version', function (tt) {
tt.plan(1)
baseScenario(cwd, registry.uri)
@ -35,7 +32,7 @@ test('change version', (t) => {
.end(tt.error)
})
t.test('initial version', (tt) => {
t.test('initial version', function (tt) {
tt.plan(1)
baseScenario(cwd, registry.uri)
@ -47,7 +44,7 @@ test('change version', (t) => {
.end(tt.error)
})
t.test('patch version', (tt) => {
t.test('patch version', function (tt) {
tt.plan(1)
baseScenario(cwd, registry.uri)
@ -59,7 +56,7 @@ test('change version', (t) => {
.end(tt.error)
})
t.test('feature version', (tt) => {
t.test('feature version', function (tt) {
tt.plan(1)
baseScenario(cwd, registry.uri)
@ -71,7 +68,7 @@ test('change version', (t) => {
.end(tt.error)
})
t.test('breaking version', (tt) => {
t.test('breaking version', function (tt) {
tt.plan(1)
baseScenario(cwd, registry.uri)
@ -86,10 +83,11 @@ test('change version', (t) => {
})
})
tearDown(() => {
tearDown(function () {
if (process.env.TRAVIS === 'true') return
function cb (err, stdout, stderr) {
if (err) console.log(err)
if (stdout) console.log(stdout)
if (stderr) console.log(stderr)
}

View File

@ -1,13 +1,16 @@
const test = require('tap').test
const proxyquire = require('proxyquire')
var test = require('tap').test
var proxyquire = require('proxyquire')
const commits = proxyquire('../../dist/lib/commits', {
var commits = proxyquire('../../src/lib/commits', {
'npmlog': {
error: function () {}
},
'child_process': require('../mocks/child-process')
})
test('commits since last release', (t) => {
t.test('get all commits', (tt) => {
commits({lastRelease: {}, options: {branch: 'master'}}, (err, commits) => {
test('commits since last release', function (t) {
t.test('get all commits', function (tt) {
commits({lastRelease: {}, options: {branch: 'master'}}, function (err, commits) {
tt.error(err)
tt.is(commits.length, 2, 'all commits')
tt.is(commits[0].hash, 'hash-one', 'parsed hash')
@ -17,8 +20,8 @@ test('commits since last release', (t) => {
})
})
t.test('get commits since hash', (tt) => {
commits({lastRelease: {gitHead: 'hash'}, options: {branch: 'master'}}, (err, commits) => {
t.test('get commits since hash', function (tt) {
commits({lastRelease: {gitHead: 'hash'}, options: {branch: 'master'}}, function (err, commits) {
tt.error(err)
tt.is(commits.length, 1, 'specified commits')
tt.is(commits[0].hash, 'hash-one', 'parsed hash')
@ -28,8 +31,8 @@ test('commits since last release', (t) => {
})
})
t.test('get commits since hash', (tt) => {
commits({lastRelease: {gitHead: 'notinhistory'}, options: {branch: 'notmaster'}}, (err, commits) => {
t.test('get commits since hash', function (tt) {
commits({lastRelease: {gitHead: 'notinhistory'}, options: {branch: 'notmaster'}}, function (err, commits) {
tt.ok(err)
tt.is(err.code, 'ENOTINHISTORY')
tt.end()

View File

@ -1,8 +1,8 @@
const test = require('tap').test
const getRegistry = require('../../dist/lib/get-registry')
const getRegistry = require('../../src/lib/get-registry')
test('get correct registry', (t) => {
test('get correct registry', function (t) {
t.is(getRegistry({
name: 'publish-config',
publishConfig: {
@ -10,20 +10,34 @@ test('get correct registry', (t) => {
}},
{}), 'a')
t.is(getRegistry({name: 'normal'}, {get: () => 'b'}), 'b')
t.is(getRegistry({name: 'normal'}, {
get: function () {
return 'b'
}
}), 'b')
t.is(getRegistry({name: 'normal'}, {get: () => null}), 'https://registry.npmjs.org/')
t.is(getRegistry({name: 'normal'}, {
get: function () {
return null
}
}), 'https://registry.npmjs.org/')
t.is(getRegistry({name: '@scoped/foo'}, {
get: (input) => input === '@scoped/registry' ? 'c' : 'd'
get: function (input) {
return input === '@scoped/registry' ? 'c' : 'd'
}
}), 'c')
t.is(getRegistry({name: '@scoped/bar'}, {
get: () => 'e'
get: function () {
return 'e'
}
}), 'e')
t.is(getRegistry({name: '@scoped/baz'}, {
get: () => null
get: function () {
return null
}
}), 'https://registry.npmjs.org/')
t.end()

View File

@ -1,11 +1,11 @@
const test = require('tap').test
var test = require('tap').test
const plugins = require('../../dist/lib/plugins')
var plugins = require('../../src/lib/plugins')
test('export plugins', (t) => {
test('export plugins', function (t) {
t.plan(5)
const defaultPlugins = plugins({})
var defaultPlugins = plugins({})
t.is(typeof defaultPlugins.analyzeCommits, 'function')
t.is(typeof defaultPlugins.generateNotes, 'function')
@ -14,51 +14,51 @@ test('export plugins', (t) => {
t.is(typeof defaultPlugins.getLastRelease, 'function')
})
test('plugin pipelines', (t) => {
test('plugin pipelines', function (t) {
t.plan(3)
t.test('get all results', (tt) => {
const pipelinePlugins = plugins({
t.test('get all results', function (tt) {
var pipelinePlugins = plugins({
verifyRelease: [
'./dist/lib/plugin-noop',
'./.test/mocks/plugin-result-a',
'./.test/mocks/plugin-result-b'
'./src/lib/plugin-noop',
'./test/mocks/plugin-result-a',
'./test/mocks/plugin-result-b'
]
})
pipelinePlugins.verifyRelease({}, (err, results) => {
pipelinePlugins.verifyRelease({}, function (err, results) {
tt.error(err)
tt.same(results, [undefined, 'a', 'b'])
tt.end()
})
})
t.test('get first error', (tt) => {
const pipelinePlugins = plugins({
t.test('get first error', function (tt) {
var pipelinePlugins = plugins({
verifyConditions: [
'./dist/lib/plugin-noop',
'./.test/mocks/plugin-error-a',
'./.test/mocks/plugin-error-b'
'./src/lib/plugin-noop',
'./test/mocks/plugin-error-a',
'./test/mocks/plugin-error-b'
]
})
pipelinePlugins.verifyConditions({}, (err) => {
pipelinePlugins.verifyConditions({}, function (err) {
tt.is(err.message, 'a')
tt.end()
})
})
t.test('get error and only results before', (tt) => {
const pipelinePlugins = plugins({
t.test('get error and only results before', function (tt) {
var pipelinePlugins = plugins({
verifyRelease: [
'./dist/lib/plugin-noop',
'./.test/mocks/plugin-result-a',
'./.test/mocks/plugin-error-b',
'./.test/mocks/plugin-result-b'
'./src/lib/plugin-noop',
'./test/mocks/plugin-result-a',
'./test/mocks/plugin-error-b',
'./test/mocks/plugin-result-b'
]
})
pipelinePlugins.verifyRelease({}, (err, results) => {
pipelinePlugins.verifyRelease({}, function (err, results) {
tt.is(err.message, 'b')
tt.same(results, [undefined, 'a', undefined])
tt.end()
@ -66,18 +66,18 @@ test('plugin pipelines', (t) => {
})
})
test('normalize and load plugin', (t) => {
t.test('load from string', (tt) => {
const plugin = plugins.normalize('./dist/lib/plugin-noop')
test('normalize and load plugin', function (t) {
t.test('load from string', function (tt) {
var plugin = plugins.normalize('./src/lib/plugin-noop')
tt.is(typeof plugin, 'function')
tt.end()
})
t.test('load from object', (tt) => {
const plugin = plugins.normalize({
path: './dist/lib/plugin-noop'
t.test('load from object', function (tt) {
var plugin = plugins.normalize({
path: './src/lib/plugin-noop'
})
tt.is(typeof plugin, 'function')
@ -85,8 +85,8 @@ test('normalize and load plugin', (t) => {
tt.end()
})
t.test('load from object', (tt) => {
const plugin = plugins.normalize(null, '../../dist/lib/plugin-noop')
t.test('load from fallback', function (tt) {
var plugin = plugins.normalize(null, '../../src/lib/plugin-noop')
tt.is(typeof plugin, 'function')

View File

@ -1,20 +1,24 @@
const { defaults } = require('lodash')
const test = require('tap').test
const proxyquire = require('proxyquire')
var defaults = require('lodash').defaults
var test = require('tap').test
var proxyquire = require('proxyquire')
const post = proxyquire('../../dist/post', {
var post = proxyquire('../../src/post', {
'git-head': require('../mocks/git-head'),
github: require('../mocks/github')
})
const pkg = {
var pkg = {
version: '1.0.0',
repository: {url: 'http://github.com/whats/up.git'}
}
const plugins = {generateNotes: (pkg, cb) => cb(null, 'the log')}
var plugins = {
generateNotes: function (pkg, cb) {
cb(null, 'the log')
}
}
const defaultRelease = {
var defaultRelease = {
owner: 'whats',
repo: 'up',
name: 'v1.0.0',
@ -23,13 +27,13 @@ const defaultRelease = {
body: 'the log'
}
test('full post run', (t) => {
t.test('in debug mode w/o token', (tt) => {
test('full post run', function (t) {
t.test('in debug mode w/o token', function (tt) {
post({
options: {debug: true},
pkg,
plugins
}, (err, published, release) => {
pkg: pkg,
plugins: plugins
}, function (err, published, release) {
tt.error(err)
tt.is(published, false)
tt.match(release, defaults({draft: true}, defaultRelease))
@ -38,12 +42,12 @@ test('full post run', (t) => {
})
})
t.test('in debug mode w/token', (tt) => {
t.test('in debug mode w/token', function (tt) {
post({
options: {debug: true, githubToken: 'yo'},
pkg,
plugins
}, (err, published, release) => {
pkg: pkg,
plugins: plugins
}, function (err, published, release) {
tt.error(err)
tt.is(published, true)
tt.match(release, defaults({draft: true}, defaultRelease))
@ -52,12 +56,12 @@ test('full post run', (t) => {
})
})
t.test('production', (tt) => {
t.test('production', function (tt) {
post({
options: {githubToken: 'yo'},
pkg,
plugins
}, (err, published, release) => {
pkg: pkg,
plugins: plugins
}, function (err, published, release) {
tt.error(err)
tt.is(published, true)
tt.match(release, defaultRelease)

View File

@ -1,55 +1,59 @@
const test = require('tap').test
const proxyquire = require('proxyquire')
var test = require('tap').test
var proxyquire = require('proxyquire')
require('../mocks/registry')
const pre = proxyquire('../../dist/pre', {
'./lib/commits': proxyquire('../../dist/lib/commits', {
var pre = proxyquire('../../src/pre', {
'./lib/commits': proxyquire('../../src/lib/commits', {
'child_process': require('../mocks/child-process')
})
})
const versions = {
var versions = {
available: '1.0.0'
}
const plugins = {
verifyRelease: (release, cb) => cb(null, release),
analyzeCommits: (commits, cb) => cb(null, 'major'),
getLastRelease: ({ pkg }, cb) => {
cb(null, {version: versions[pkg.name] || null, gitHead: 'HEAD'})
var plugins = {
verifyRelease: function (release, cb) {
cb(null, release)
},
analyzeCommits: function (commits, cb) {
cb(null, 'major')
},
getLastRelease: function (config, cb) {
cb(null, {version: versions[config.pkg.name] || null, gitHead: 'HEAD'})
}
}
const npm = {
var npm = {
registry: 'http://registry.npmjs.org/',
tag: 'latest'
}
test('full pre run', (t) => {
t.test('increase version', (tt) => {
test('full pre run', function (t) {
t.test('increase version', function (tt) {
tt.plan(3)
pre({
options: {branch: 'master'},
npm,
npm: npm,
pkg: {name: 'available'},
plugins
}, (err, release) => {
plugins: plugins
}, function (err, release) {
tt.error(err)
tt.is(release.type, 'major')
tt.is(release.version, '2.0.0')
})
})
t.test('increase version', (tt) => {
t.test('increase version', function (tt) {
tt.plan(3)
pre({
options: {branch: 'master'},
npm,
npm: npm,
pkg: {name: 'unavailable'},
plugins
}, (err, release) => {
plugins: plugins
}, function (err, release) {
tt.error(err)
tt.is(release.type, 'initial')
tt.is(release.version, '1.0.0')

View File

@ -1,9 +1,9 @@
const test = require('tap').test
var test = require('tap').test
const type = require('../../dist/lib/type')
var type = require('../../src/lib/type')
test('get type from commits', (t) => {
t.test('get type from plugin', (tt) => {
test('get type from commits', function (t) {
t.test('get type from plugin', function (tt) {
tt.plan(2)
type({
@ -12,33 +12,45 @@ test('get type from commits', (t) => {
message: 'a'
}],
lastRelease: {version: '1.0.0'},
plugins: {analyzeCommits: (config, cb) => cb(null, 'major')}
}, (err, type) => {
plugins: {
analyzeCommits: function (config, cb) {
cb(null, 'major')
}
}
}, function (err, type) {
tt.error(err)
tt.is(type, 'major')
})
})
t.test('error when no changes', (tt) => {
t.test('error when no changes', function (tt) {
tt.plan(1)
type({
commits: [],
lastRelease: {},
plugins: {analyzeCommits: (config, cb) => cb(null, null)}
}, (err) => {
plugins: {
analyzeCommits: function (config, cb) {
cb(null, null)
}
}
}, function (err) {
tt.is(err.code, 'ENOCHANGE')
})
})
t.test('initial version', (tt) => {
t.test('initial version', function (tt) {
tt.plan(2)
type({
commits: [],
lastRelease: {},
plugins: {analyzeCommits: (config, cb) => cb(null, 'major')}
}, (err, type) => {
plugins: {
analyzeCommits: function (config, cb) {
cb(null, 'major')
}
}
}, function (err, type) {
tt.error(err)
tt.is(type, 'initial')
})

View File

@ -1,10 +1,10 @@
const test = require('tap').test
var test = require('tap').test
const verify = require('../../dist/lib/verify')
var verify = require('../../src/lib/verify')
test('verify pkg, options and env', (t) => {
t.test('dry run verification', (tt) => {
const noErrors = verify({
test('verify pkg, options and env', function (t) {
t.test('dry run verification', function (tt) {
var noErrors = verify({
options: {debug: true},
pkg: {
name: 'package',
@ -16,7 +16,7 @@ test('verify pkg, options and env', (t) => {
tt.is(noErrors.length, 0)
const errors = verify({
var errors = verify({
options: {debug: true},
pkg: {}
})
@ -25,7 +25,7 @@ test('verify pkg, options and env', (t) => {
tt.is(errors[0].code, 'ENOPKGNAME')
tt.is(errors[1].code, 'ENOPKGREPO')
const errors2 = verify({
var errors2 = verify({
options: {debug: true},
pkg: {
name: 'package',
@ -41,8 +41,8 @@ test('verify pkg, options and env', (t) => {
tt.end()
})
t.test('publish verification', (tt) => {
const noErrors = verify({
t.test('publish verification', function (tt) {
var noErrors = verify({
env: {NPM_TOKEN: 'yo'},
options: {githubToken: 'sup'},
pkg: {
@ -55,7 +55,7 @@ test('verify pkg, options and env', (t) => {
tt.is(noErrors.length, 0)
const errors = verify({env: {}, options: {}, pkg: {}})
var errors = verify({env: {}, options: {}, pkg: {}})
tt.is(errors.length, 4)
tt.is(errors[0].code, 'ENOPKGNAME')