Compare commits

...
11 Commits
Author SHA1 Message Date
Christoph Witzko a5dabed534 fix(pre): use raw body instead of subject 2015-05-12 08:53:38 +02:00
Christoph Witzko be9bb40dd2 refactor(pre): inline if 2015-05-12 08:53:38 +02:00
Stephan Bönnemann 4821aff69e fix(npm-info): correctly encode scoped package names
This adds support for releasing scoped packages that are public and and that have an initial version in the registry available.
More fixes needed to support yet unpublished/private scoped modules.
2015-05-12 00:06:03 +02:00
Stephan Bönnemann 773ecf693f docs(readme): document expected error closes #18 2015-05-11 23:34:35 +02:00
Stephan Bönnemann f2dd66f614 chore(travis): test on iojs-v2 2015-05-08 00:49:11 +02:00
Lewis CowperandChristoph Witzko 3b921a63c5 docs(ci server): typo fix 2015-05-04 14:41:03 +02:00
Christoph Witzko 785e7f7b3b fix(setup): add newline at the end of package.json 2015-05-04 09:18:08 +02:00
Lewis CowperandChristoph Witzko b38f1e0687 docs(intro): grammar fix 2015-05-04 09:06:51 +02:00
Stephan Bönnemann 323b5d5bf8 feat(post): custom release note generation 2015-04-24 15:52:54 +02:00
Stephan Bönnemann 3369f31a8d test(post): custom release note generation 2015-04-24 15:52:25 +02:00
Stephan Bönnemann 63096c50c4 docs(readme): add link to release note generation 2015-04-24 15:34:57 +02:00
11 changed files with 96 additions and 27 deletions
+1
View File
@@ -1,5 +1,6 @@
language: node_js
node_js:
- iojs-v2
- iojs-v1
- '0.10'
- '0.12'
+11 -6
View File
@@ -11,7 +11,7 @@ It fully automates your package's releases. It will determine not only which ver
It is fully integrated into the `npm` lifecycle, so all you need to do is to configure your CI to regularly `npm publish` (i.e. for every commit).
Removing human descisions and emotions from version numbers and releases strictly following the [SemVer](http://semver.org/) spec suddenly isn't a problem anymore.
It removes human decisions and emotions from version numbers and releases suddenly, strictly following the [SemVer](http://semver.org/) spec isn't a problem anymore.
![https://twitter.com/trodrigues/status/509301317467373571](https://cloud.githubusercontent.com/assets/908178/6091690/cc86f58c-aeb8-11e4-94cb-15f15f486cde.png)
@@ -19,7 +19,7 @@ Removing human descisions and emotions from version numbers and releases str
Meaningful conventions. Instead of dumping [lols](http://whatthecommit.com/) into our commit messages, we can take some time to think about what we changed in the codebase and write it down. Following formalized conventions it this then possible to not only generate a helpful changelog, but to determine whether a new version should be released.
This module ships with the [AngularJS Commit Message Conventions](https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit), but you can [easily define your own](https://github.com/boennemann/semantic-release/wiki/commit-analysis).
This module ships with the [AngularJS Commit Message Conventions](https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit), but you can [define your own](https://github.com/boennemann/semantic-release/wiki/commit-analysis).
### The `prepublish` step
@@ -37,12 +37,14 @@ Before `npm` actually gets to publish a new version `semantic-release`'s `prepub
After `npm` published the new version the `postpublish` step does this:
- Generate a changelog
- Create a new [GitHub Release](https://help.github.com/articles/about-releases/) and tag with the changelog as body
- Generate release notes
- Create a new [GitHub Release](https://help.github.com/articles/about-releases/) (including a git tag) with the release notes
Note: The default release notes are a [changelog](https://github.com/ajoslin/conventional-changelog) that is generated from git metadata, using the AngularJS commit conventions. You can [specify your own release note generator](https://github.com/boennemann/semantic-release/wiki/release-note-generation).
Note: This is tied to GitHub, feel free to send PRs for other services.
Note: `semantic-release` works around a limitation in `npm`'s `prepublish` step. Once a version is published it prints an error that you can *safely ignore* [npm/npm#7118](https://github.com/npm/npm/issues/7118).
Note: `semantic-release` works around a limitation in `npm`'s `prepublish` step. Once a version is published it prints a "Could not pack" error that you can *safely ignore* [npm/npm#7118](https://github.com/npm/npm/issues/7118).
## How you can set it up
@@ -99,12 +101,15 @@ cache:
- node_modules
notifications:
email: false
# See https://github.com/boennemann/semantic-release/issues/18
before_deploy:
- npm config set spin false --global
env:
# Get your token here: https://github.com/settings/tokens/new
# Grant the token repo/public_repo scope (all others can be deselected)
# You should encrypt this:
# `travis encrypt GH_TOKEN=<token> --add`
global: GH_TOKEN=<github-access-token-with-acceess-to-your-repo>
global: GH_TOKEN=<github-access-token-with-access-to-your-repo>
deploy:
provider: npm
email: <your-npm-mail@example.com>
+1 -1
View File
@@ -68,7 +68,7 @@ if (~argv._.indexOf('pre')) {
}
if (~argv._.indexOf('post')) {
require('../src/post')(argv, efh(function () {
require('../src/post')(argv, plugins, efh(function () {
// see src/restart.js
if (npmArgv['semantic-release-rerun']) {
console.log('Everything is alright :) npm will now print an error message that you can safely ignore.')
+1 -1
View File
@@ -7,7 +7,7 @@ var efh = require('./error').efh
module.exports = function (from, cb) {
var range = (from ? from + '..' : '') + 'HEAD'
exec(
'git log -E --format=%H==SPLIT==%s==END== ' + range,
'git log -E --format=%H==SPLIT==%B==END== ' + range,
efh(cb)(function (stdout) {
cb(null, String(stdout).split('==END==\n')
+2 -1
View File
@@ -5,7 +5,8 @@ var request = require('request')
var efh = require('./error').efh
module.exports = function (pkgName, cb) {
request(process.env.npm_config_registry + pkgName, efh(cb)(function (response, body) {
var encodedPkgName = pkgName.replace(/\//g, '%2F')
request(process.env.npm_config_registry + encodedPkgName, efh(cb)(function (response, body) {
var res = {
version: null,
gitHead: null,
+17
View File
@@ -0,0 +1,17 @@
'use strict'
var readFile = require('fs').readFileSync
var changelog = require('conventional-changelog')
var parseUrl = require('github-url-from-git')
module.exports = function (cb) {
var pkg = JSON.parse(readFile('./package.json'))
var repository = pkg.repository ? parseUrl(pkg.repository.url) : null
changelog({
version: pkg.version,
repository: repository,
file: false
}, cb)
}
+4 -8
View File
@@ -3,20 +3,20 @@
var readFile = require('fs').readFileSync
var url = require('url')
var changelog = require('conventional-changelog')
var gitHead = require('git-head')
var GitHubApi = require('github')
var parseSlug = require('parse-github-repo-url')
var parseUrl = require('github-url-from-git')
var efh = require('../lib/error').efh
module.exports = function (options, cb) {
module.exports = function (options, plugins, cb) {
var pkg = JSON.parse(readFile('./package.json'))
var repository = pkg.repository ? pkg.repository.url : null
if (!repository) return cb(new Error('Package must have a repository'))
var notesGenerator = require(plugins.notes || '../lib/release-notes')
var config = options['github-url'] ? url.parse(options['github-url']) : {}
var github = new GitHubApi({
@@ -26,11 +26,7 @@ module.exports = function (options, cb) {
host: config.hostname
})
changelog({
version: pkg.version,
repository: parseUrl(repository),
file: false
}, efh(cb)(function (log) {
notesGenerator(efh(cb)(function (log) {
gitHead(efh(cb)(function (hash) {
var ghRepo = parseSlug(repository)
var release = {
+1 -1
View File
@@ -20,7 +20,7 @@ module.exports = function (options, plugins, cb) {
var type = analyzer(commits)
if (!type) return cb(null, null)
pkg.version = !res.version ? '1.0.0' : semver.inc(res.version, type)
pkg.version = res.version ? semver.inc(res.version, type) : '1.0.0'
if (!options.debug) fs.writeFileSync(path, JSON.stringify(pkg, null, 2))
cb(null, pkg.version)
+1 -1
View File
@@ -38,5 +38,5 @@ module.exports = function () {
pkg.devDependencies['semantic-release'] = '^' + require('../package.json').version
}
fs.writeFileSync('./package.json', JSON.stringify(pkg, null, 2))
fs.writeFileSync('./package.json', JSON.stringify(pkg, null, 2) + '\n')
}
+5
View File
@@ -0,0 +1,5 @@
'use strict'
module.exports = function (cb) {
cb(null, 'custom log')
}
+52 -8
View File
@@ -1,5 +1,7 @@
'use strict'
var path = require('path')
var efh = require('error-first-handler')
var GitHubApi = require('github')
var nixt = require('nixt')
@@ -25,19 +27,13 @@ module.exports = function (test, createModule) {
}
}, efh()(function (name, cwd) {
test('postpublish', function (t) {
var base = nixt()
.cwd(cwd)
.env('CI', true)
.env('GH_URL', 'http://127.0.0.1:4343/')
.env('GH_TOKEN', '***')
.exec('git commit --allow-empty -m "feat(cool): the next big thing"')
.code(0)
.stdout(/> semantic-release post\n\nGenerating changelog from.*\nParsed/m)
var base = getBase(cwd)
t.test('publish new version to github releases', function (t) {
t.plan(1)
base.clone()
.stdout(/> semantic-release post\n\nGenerating changelog from.*\nParsed/m)
.run('npm run postpublish')
.end(function (err) {
t.error(err, 'nixt')
@@ -48,6 +44,7 @@ module.exports = function (test, createModule) {
t.plan(1)
base.clone()
.stdout(/> semantic-release post\n\nGenerating changelog from.*\nParsed/m)
.exec('git checkout `git rev-parse HEAD`')
.run('npm run postpublish')
.end(function (err) {
@@ -68,4 +65,51 @@ module.exports = function (test, createModule) {
})
})
}))
createModule({
version: '2.0.0',
repository: {
type: 'git',
url: 'http://github.com/user/repo'
},
release: {
notes: path.join(__dirname, '../lib/custom-release-notes')
}
}, efh()(function (name, cwd) {
test('custom-release-notes', function (t) {
var base = getBase(cwd)
t.test('publish new version (with custom notes) to github releases', function (t) {
t.plan(1)
base.clone()
.run('npm run postpublish')
.end(function (err) {
t.error(err, 'nixt')
})
})
t.test('custom notes published', function (t) {
t.plan(4)
github.releases.getRelease({ owner: 'user', repo: 'repo', id: 3}, function (err, raw) {
var res = JSON.parse(raw)
t.error(err, 'github')
t.is(res.tag_name, 'v2.0.0', 'version')
t.is(res.author.login, 'user', 'user')
t.ok(/custom log/.test(res.body), 'body')
})
})
})
}))
}
function getBase (cwd) {
return nixt()
.cwd(cwd)
.env('CI', true)
.env('GH_URL', 'http://127.0.0.1:4343/')
.env('GH_TOKEN', '***')
.exec('git commit --allow-empty -m "feat(cool): the next big thing"')
.code(0)
}