Compare commits
+6
-11
@@ -1,22 +1,17 @@
|
||||
sudo: false
|
||||
dist: trusty
|
||||
language: node_js
|
||||
cache:
|
||||
directories:
|
||||
- node_modules
|
||||
- $HOME/.npm
|
||||
notifications:
|
||||
email: false
|
||||
node_js:
|
||||
- 5
|
||||
- 4
|
||||
- iojs
|
||||
- '0.12'
|
||||
- '0.10'
|
||||
before_install:
|
||||
- npm i -g npm@^2.0.0
|
||||
before_script:
|
||||
- npm prune
|
||||
- 8
|
||||
after_success:
|
||||
- npm run coverage:upload
|
||||
- npm run semantic-release
|
||||
services:
|
||||
- couchdb
|
||||
branches:
|
||||
except:
|
||||
- /^v\d+\.\d+\.\d+$/
|
||||
|
||||
@@ -79,7 +79,7 @@ This removes the immediate connection between human emotions and version numbers
|
||||
|
||||
Instead of writing [meaningless commit messages](http://whatthecommit.com/), we can take our time to think about the changes in the codebase and write them down. Following formalized conventions it is then possible to generate a helpful changelog and to derive the next semantic version number from them.
|
||||
|
||||
When `semantic-release` is setup it will do that after every successful continuous integration build of your master branch (or any other branch you specify) and publish the new version for you. This way no human is directly involved in the release process and your releases are guaranteed to be [unromantic and unsentimental](http://sentimentalversioning.org/).
|
||||
When `semantic-release` is set up it will do that after every successful continuous integration build of your master branch (or any other branch you specify) and publish the new version for you. This way no human is directly involved in the release process and your releases are guaranteed to be [unromantic and unsentimental](http://sentimentalversioning.org/).
|
||||
|
||||
If you fear the loss of control over timing and marketing implications of software releases you should know that `semantic-release` supports [release channels](https://github.com/npm/npm/issues/2718) using `npm`’s [dist-tags](https://docs.npmjs.com/cli/dist-tag). This way you can keep control over what your users end up using by default, you can decide when to promote an automatically released version to the stable channel, and you can choose which versions to write blogposts and tweets about. You can use the same mechanism to [support older versions of your software](https://gist.github.com/boennemann/54042374e49c7ade8910), for example with important security fixes.
|
||||
|
||||
@@ -106,7 +106,7 @@ format that includes a **type**, a **scope** and a **subject** ([full explanatio
|
||||
<footer>
|
||||
```
|
||||
|
||||
You can simplify using this convention for yourself and contributors by using [commitizen](https://github.com/commitizen/cz-cli) and [validate-commit-msg](https://github.com/kentcdodds/validate-commit-msg).
|
||||
You can simplify using this convention for yourself and contributors by using [commitizen](https://github.com/commitizen/cz-cli) and [validate-commit-msg](https://github.com/kentcdodds/validate-commit-msg) or [semantic-git-commit-cli](https://github.com/JPeer264/node-semantic-git-commit-cli).
|
||||
|
||||
### Patch Release
|
||||
|
||||
@@ -141,7 +141,7 @@ semantic-release-cli setup
|
||||
|
||||

|
||||
|
||||
_[This is what happens under the hood.](https://github.com/semantic-release/cli#manual-setup)_
|
||||
_[This is what happens under the hood.](https://github.com/semantic-release/cli#what-it-does)_
|
||||
|
||||
## Options
|
||||
|
||||
@@ -206,7 +206,11 @@ module.exports = function (pluginConfig, config, callback) {}
|
||||
|
||||
### `analyzeCommits`
|
||||
|
||||
This plugin is responsible for determining the type of the next release. It additionally receives a `commits` array inside `config`. One commit is an object with a `message` and `hash` property. Call the callback with `'major'`, `'premajor'`, `'minor'`, `'preminor'`, `'patch'`, `'prepatch'`, `'prerelease'`, or `null` if nothing changed. Have a look at the [default implementation](https://github.com/semantic-release/commit-analyzer/).
|
||||
This plugin is responsible for determining the type of the next release. It additionally receives a `commits` array inside `config`. One commit is an object with a `message` and `hash` property. Call the callback with `'major'`, `'premajor'`, `'minor'`, `'preminor'`, `'patch'`, `'prepatch'`, `'prerelease'`, or `null` if nothing changed.
|
||||
|
||||
While it may be tempting to use `'prepatch'`, `'preminor'` & `'prerelease'` as part of a release process, this is strongly discouraged. A better approach is to use [dist-tags](https://docs.npmjs.com/cli/dist-tag) to create release channels (such as 'latest', 'next', 'stable') and to return only `'major'`, `'premajor'` and `'minor'` from the commit analyzer.
|
||||
|
||||
Have a look at the [default implementation](https://github.com/semantic-release/commit-analyzer/).
|
||||
|
||||
### `generateNotes`
|
||||
|
||||
@@ -258,7 +262,13 @@ 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 all major node.js versions from `^0.10` on. A new version won’t get published if it doesn’t pass on all these engines.
|
||||
`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/). A new version won’t get published if it doesn’t pass on all these engines.
|
||||
|
||||
### Why does `semantic-release` require node version >= 8
|
||||
|
||||
Being able to write code for just the most recent node versions greatly simplifies development. More language features are available, no transpilation is required, less test builds are to be run, awaited and debugged.
|
||||
|
||||
For a special purpose tool like `semantic-release`, that's only meant to be used in controlled CI environments, we think it's okay to have such a high version requirement. As `semantic-release` handles package publishing we expect almost every project to have at least one build job running node 8 already – and that's all it takes. Even if that's not that case `semantic-release` can still be executed with the help of [npx](https://www.npmjs.com/package/npx) (`npx -p node@8 npm run semantic-release`).
|
||||
|
||||
## Badge
|
||||
|
||||
|
||||
+19
-159
@@ -1,165 +1,25 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var fs = require('fs')
|
||||
var path = require('path')
|
||||
var url = require('url')
|
||||
// Bad news: We have to write plain ES5 in this file
|
||||
// Good news: It's the only file of the entire project
|
||||
|
||||
var _ = require('lodash')
|
||||
var log = require('npmlog')
|
||||
var nopt = require('nopt')
|
||||
var npmconf = require('npmconf')
|
||||
var normalizeData = require('normalize-package-data')
|
||||
var semver = require('semver')
|
||||
|
||||
log.heading = 'semantic-release'
|
||||
var env = process.env
|
||||
var pkg = JSON.parse(fs.readFileSync('./package.json'))
|
||||
var originalPkg = _.cloneDeep(pkg)
|
||||
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]
|
||||
if (semver.lt(process.version, '8.0.0')) {
|
||||
console.error(
|
||||
`semantic-release: node version >= 8 is required. Found ${process.version}.
|
||||
|
||||
If there is another job running on node version >= 8, it will be picked as
|
||||
the build leader and you can safely ignore this message.
|
||||
|
||||
If you don't have node 8 in your build matrix you can use "npx" to restore
|
||||
compatibility with minimal overhead:
|
||||
|
||||
$ npx -p node@8 npm run semantic-release
|
||||
|
||||
npx is bundled with npm >= 5.4, or available via npm. More info: npm.im/npx`)
|
||||
process.exit(1)
|
||||
}
|
||||
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
|
||||
},
|
||||
cafile: conf.get('cafile'),
|
||||
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 {
|
||||
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(originalPkg, {
|
||||
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 {
|
||||
log.error('post', 'Command "' + options.argv.remain[0] + '" not recognized. Use either "pre" or "post"')
|
||||
}
|
||||
})
|
||||
// node 8+ from this point on
|
||||
require('../src')
|
||||
|
||||
Generated
+7490
File diff suppressed because it is too large
Load Diff
+18
-17
@@ -13,43 +13,48 @@
|
||||
"path": "node_modules/cz-conventional-changelog/"
|
||||
},
|
||||
"dependencies": {
|
||||
"@bahmutov/parse-github-repo-url": "^0.1.0",
|
||||
"@semantic-release/commit-analyzer": "^2.0.0",
|
||||
"@semantic-release/condition-travis": "^5.0.2",
|
||||
"@semantic-release/condition-travis": "^6.0.0",
|
||||
"@semantic-release/error": "^1.0.0",
|
||||
"@semantic-release/last-release-npm": "^1.2.1",
|
||||
"@semantic-release/release-notes-generator": "^2.0.0",
|
||||
"@semantic-release/release-notes-generator": "^3.0.1",
|
||||
"git-head": "^1.2.1",
|
||||
"github": "^0.2.4",
|
||||
"github": "^8.0.0",
|
||||
"lodash": "^4.0.0",
|
||||
"nerf-dart": "^1.0.0",
|
||||
"nopt": "^3.0.3",
|
||||
"nopt": "^4.0.0",
|
||||
"normalize-package-data": "^2.3.4",
|
||||
"npmconf": "^2.1.2",
|
||||
"npmlog": "^4.0.0",
|
||||
"parse-github-repo-url": "^1.3.0",
|
||||
"require-relative": "^0.8.7",
|
||||
"run-auto": "^2.0.0",
|
||||
"run-series": "^1.1.3",
|
||||
"semver": "^5.0.3"
|
||||
"semver": "^5.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"coveralls": "^2.11.4",
|
||||
"cz-conventional-changelog": "^1.1.4",
|
||||
"mkdirp": "^0.5.1",
|
||||
"mock-spawn": "^0.2.6",
|
||||
"nixt": "^0.5.0",
|
||||
"nock": "^8.0.0",
|
||||
"npm-registry-couchapp": "^2.6.11",
|
||||
"nyc": "^7.0.0",
|
||||
"nock": "^9.0.2",
|
||||
"npm-registry-couchapp": "^2.6.12",
|
||||
"nyc": "^10.0.0",
|
||||
"proxyquire": "^1.7.3",
|
||||
"rimraf": "^2.5.0",
|
||||
"standard": "^7.0.1",
|
||||
"tap": "^6.2.0"
|
||||
"standard": "^9.0.0",
|
||||
"tap": "^10.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10",
|
||||
"node": ">=8",
|
||||
"npm": ">=2"
|
||||
},
|
||||
"homepage": "https://github.com/semantic-release/semantic-release/tree/next#readme",
|
||||
"files": [
|
||||
"bin",
|
||||
"src"
|
||||
],
|
||||
"homepage": "https://github.com/semantic-release/semantic-release#readme",
|
||||
"keywords": [
|
||||
"author",
|
||||
"automation",
|
||||
@@ -63,10 +68,6 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "bin/semantic-release.js",
|
||||
"files": [
|
||||
"bin",
|
||||
"src"
|
||||
],
|
||||
"publishConfig": {
|
||||
"tag": "next"
|
||||
},
|
||||
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
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'))
|
||||
var originalPkg = _.cloneDeep(pkg)
|
||||
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
|
||||
},
|
||||
cafile: conf.get('cafile'),
|
||||
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') // eslint-disable-line no-template-curly-in-string
|
||||
conf.set('email', '${NPM_EMAIL}', 'project') // eslint-disable-line no-template-curly-in-string
|
||||
wroteNpmRc = true
|
||||
} else if (env.NPM_TOKEN) {
|
||||
conf.set(nerfDart + ':_authToken', '${NPM_TOKEN}', 'project') // eslint-disable-line no-template-curly-in-string
|
||||
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 {
|
||||
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(originalPkg, {
|
||||
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 {
|
||||
log.error('post', 'Command "' + options.argv.remain[0] + '" not recognized. Use either "pre" or "post"')
|
||||
}
|
||||
})
|
||||
+19
-14
@@ -1,4 +1,4 @@
|
||||
var exec = require('child_process').exec
|
||||
var childProcess = require('child_process')
|
||||
|
||||
var log = require('npmlog')
|
||||
|
||||
@@ -13,7 +13,7 @@ module.exports = function (config, cb) {
|
||||
|
||||
if (!from) return extract()
|
||||
|
||||
exec('git branch --contains ' + from, function (err, stdout) {
|
||||
childProcess.exec('git branch --no-color --contains ' + from, function (err, stdout) {
|
||||
var inHistory = false
|
||||
var branches
|
||||
|
||||
@@ -47,28 +47,33 @@ module.exports = function (config, cb) {
|
||||
})
|
||||
|
||||
function extract () {
|
||||
exec(
|
||||
'git log -E --format=%H==SPLIT==%B==END== ' + range,
|
||||
{
|
||||
maxBuffer: 1024 * 1024 // 1MB instead of 220KB (issue #286)
|
||||
},
|
||||
function (err, stdout) {
|
||||
if (err) return cb(err)
|
||||
var child = childProcess.spawn('git', ['log', '-E', '--format=%H==SPLIT==%B==END==', range])
|
||||
var stdout = ''
|
||||
var err = ''
|
||||
|
||||
cb(null, String(stdout).split('==END==\n')
|
||||
child.stdout.on('data', function (data) {
|
||||
stdout += data
|
||||
})
|
||||
|
||||
child.stderr.on('data', function (data) {
|
||||
err += data
|
||||
})
|
||||
|
||||
child.on('close', function (code) {
|
||||
if (err || code) return cb(err)
|
||||
|
||||
cb(null, String(stdout).split('==END==\n')
|
||||
.filter(function (raw) {
|
||||
return !!raw.trim()
|
||||
})
|
||||
|
||||
.map(function (raw) {
|
||||
var data = raw.split('==SPLIT==')
|
||||
return {
|
||||
hash: data[0],
|
||||
message: data[1]
|
||||
}
|
||||
}))
|
||||
}
|
||||
)
|
||||
})
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
+24
-7
@@ -2,7 +2,7 @@ var url = require('url')
|
||||
|
||||
var gitHead = require('git-head')
|
||||
var GitHubApi = require('github')
|
||||
var parseSlug = require('@bahmutov/parse-github-repo-url')
|
||||
var parseSlug = require('parse-github-repo-url')
|
||||
|
||||
module.exports = function (config, cb) {
|
||||
var pkg = config.pkg
|
||||
@@ -11,7 +11,6 @@ module.exports = function (config, cb) {
|
||||
var ghConfig = options.githubUrl ? url.parse(options.githubUrl) : {}
|
||||
|
||||
var github = new GitHubApi({
|
||||
version: '3.0.0',
|
||||
port: ghConfig.port,
|
||||
protocol: (ghConfig.protocol || '').split(':')[0] || null,
|
||||
host: ghConfig.hostname,
|
||||
@@ -25,12 +24,18 @@ module.exports = function (config, cb) {
|
||||
if (err) return cb(err)
|
||||
|
||||
var ghRepo = parseSlug(pkg.repository.url)
|
||||
var tag = {
|
||||
owner: ghRepo[0],
|
||||
repo: ghRepo[1],
|
||||
ref: 'refs/tags/v' + pkg.version,
|
||||
sha: hash
|
||||
}
|
||||
var release = {
|
||||
owner: ghRepo[0],
|
||||
repo: ghRepo[1],
|
||||
name: 'v' + pkg.version,
|
||||
tag_name: 'v' + pkg.version,
|
||||
target_commitish: hash,
|
||||
name: 'v' + pkg.version,
|
||||
target_commitish: options.branch,
|
||||
draft: !!options.debug,
|
||||
body: log
|
||||
}
|
||||
@@ -40,14 +45,26 @@ module.exports = function (config, cb) {
|
||||
}
|
||||
|
||||
github.authenticate({
|
||||
type: 'oauth',
|
||||
type: 'token',
|
||||
token: options.githubToken
|
||||
})
|
||||
|
||||
github.releases.createRelease(release, function (err) {
|
||||
if (options.debug) {
|
||||
return github.repos.createRelease(release, function (err) {
|
||||
if (err) return cb(err)
|
||||
|
||||
cb(null, true, release)
|
||||
})
|
||||
}
|
||||
|
||||
github.gitdata.createReference(tag, function (err) {
|
||||
if (err) return cb(err)
|
||||
|
||||
cb(null, true, release)
|
||||
github.repos.createRelease(release, function (err) {
|
||||
if (err) return cb(err)
|
||||
|
||||
cb(null, true, release)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -4,7 +4,7 @@ module.exports = function (cwd, uri) {
|
||||
return nixt()
|
||||
.cwd(cwd)
|
||||
.env('NPM_OLD_TOKEN', 'aW50ZWdyYXRpb246c3VjaHNlY3VyZQ==')
|
||||
.env('NPM_EMAIL', 'integration@test.com')
|
||||
.env('NPM_EMAIL', 'integration@test.com')
|
||||
.env('GH_TOKEN', 'ghtoken')
|
||||
.env('CI', 'true')
|
||||
.env('npm_config_registry', uri)
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
var mockSpawn = require('mock-spawn')()
|
||||
mockSpawn.setStrategy(function (command, args, opts) {
|
||||
return function (cb) {
|
||||
this.stdout.write(
|
||||
/\.\.HEAD/.test(args.join(' '))
|
||||
? rawCommits[0]
|
||||
: rawCommits.join()
|
||||
)
|
||||
cb(0)
|
||||
}
|
||||
})
|
||||
|
||||
const rawCommits = [
|
||||
'hash-one==SPLIT==commit-one==END==\n',
|
||||
'hash-two==SPLIT==commit-two==END==\n'
|
||||
@@ -12,13 +24,7 @@ module.exports = {
|
||||
if (/notinhistory/.test(command)) return cb(new Error())
|
||||
return cb(null, 'whatever\nmaster\n')
|
||||
}
|
||||
|
||||
cb(
|
||||
null,
|
||||
/\.\.HEAD/.test(command)
|
||||
? rawCommits[0]
|
||||
: rawCommits.join()
|
||||
)
|
||||
},
|
||||
spawn: mockSpawn,
|
||||
'@noCallThru': true
|
||||
}
|
||||
|
||||
@@ -3,7 +3,12 @@ module.exports = function () {
|
||||
authenticate: function () {
|
||||
return true
|
||||
},
|
||||
releases: {
|
||||
gitdata: {
|
||||
createReference: function (release, cb) {
|
||||
cb(null)
|
||||
}
|
||||
},
|
||||
repos: {
|
||||
createRelease: function (release, cb) {
|
||||
cb(null)
|
||||
}
|
||||
|
||||
@@ -37,4 +37,5 @@ export DEPLOY_VERSION=nope
|
||||
# setup npm-registry-couchapp
|
||||
npm explore npm-registry-couchapp -- npm start --npm-registry-couchapp:couch=$COUCH/registry
|
||||
npm explore npm-registry-couchapp -- npm run load --npm-registry-couchapp:couch=$COUCH/registry
|
||||
npm explore npm-registry-couchapp -- NO_PROMPT=yes npm run copy --npm-registry-couchapp:couch=$COUCH/registry
|
||||
export NO_PROMPT=yes
|
||||
npm explore npm-registry-couchapp -- npm run copy --npm-registry-couchapp:couch=$COUCH/registry
|
||||
|
||||
+4
-4
@@ -23,14 +23,14 @@ var defaultRelease = {
|
||||
repo: 'up',
|
||||
name: 'v1.0.0',
|
||||
tag_name: 'v1.0.0',
|
||||
target_commitish: 'bar',
|
||||
target_commitish: 'master',
|
||||
body: 'the log'
|
||||
}
|
||||
|
||||
test('full post run', function (t) {
|
||||
t.test('in debug mode w/o token', function (tt) {
|
||||
post({
|
||||
options: {debug: true},
|
||||
options: {debug: true, branch: 'master'},
|
||||
pkg: pkg,
|
||||
plugins: plugins
|
||||
}, function (err, published, release) {
|
||||
@@ -44,7 +44,7 @@ test('full post run', function (t) {
|
||||
|
||||
t.test('in debug mode w/token', function (tt) {
|
||||
post({
|
||||
options: {debug: true, githubToken: 'yo'},
|
||||
options: {debug: true, githubToken: 'yo', branch: 'master'},
|
||||
pkg: pkg,
|
||||
plugins: plugins
|
||||
}, function (err, published, release) {
|
||||
@@ -58,7 +58,7 @@ test('full post run', function (t) {
|
||||
|
||||
t.test('production', function (tt) {
|
||||
post({
|
||||
options: {githubToken: 'yo'},
|
||||
options: {githubToken: 'yo', branch: 'master'},
|
||||
pkg: pkg,
|
||||
plugins: plugins
|
||||
}, function (err, published, release) {
|
||||
|
||||
@@ -39,7 +39,6 @@ test('verify pkg, options and env', function (t) {
|
||||
}
|
||||
})
|
||||
|
||||
console.log(noErrors)
|
||||
tt.is(noErrors.length, 0)
|
||||
tt.end()
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user