Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
23221cc044 | ||
|
|
7a4c89f131 | ||
|
|
2405453f2d | ||
|
|
a16c36ed4d | ||
|
|
5cc7da6035 |
@@ -1,16 +1,15 @@
|
||||
# semantic-release
|
||||
|
||||
|
||||
[](https://github.com/semantic-release/semantic-release)
|
||||
[](https://github.com/feross/standard)
|
||||
[](https://gitter.im/semantic-release/semantic-release?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
[](https://travis-ci.org/semantic-release/semantic-release)
|
||||
[](https://coveralls.io/github/semantic-release/semantic-release?branch=next)
|
||||
|
||||
[](https://david-dm.org/semantic-release/semantic-release/next)
|
||||
[](https://david-dm.org/semantic-release/semantic-release/next#info=devDependencies)
|
||||
|
||||
[](https://gitter.im/semantic-release/semantic-release?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://github.com/semantic-release/semantic-release)
|
||||
[](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_.
|
||||
|
||||
| Commands | Comment
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
"@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.1.1",
|
||||
"@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",
|
||||
|
||||
@@ -24,6 +24,9 @@ const options = _.defaults(
|
||||
pkg.release,
|
||||
{
|
||||
branch: 'master',
|
||||
fallbackTags: {
|
||||
next: 'latest'
|
||||
},
|
||||
debug: !env.CI,
|
||||
githubToken: env.GH_TOKEN || env.GITHUB_TOKEN,
|
||||
githubUrl: env.GH_URL
|
||||
|
||||
+55
-15
@@ -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]
|
||||
}
|
||||
}))
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) ?
|
||||
|
||||
+10
-2
@@ -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()
|
||||
})
|
||||
|
||||
+6
-3
@@ -3,7 +3,9 @@ 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 = {
|
||||
@@ -14,14 +16,13 @@ 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' })
|
||||
cb(null, {version: versions[pkg.name] || null, gitHead: 'HEAD'})
|
||||
}
|
||||
}
|
||||
|
||||
const npm = {
|
||||
registry: 'http://registry.npmjs.org/',
|
||||
tag: 'latest'
|
||||
|
||||
}
|
||||
|
||||
test('full pre run', (t) => {
|
||||
@@ -29,6 +30,7 @@ test('full pre run', (t) => {
|
||||
tt.plan(3)
|
||||
|
||||
pre({
|
||||
options: {branch: 'master'},
|
||||
npm,
|
||||
pkg: {name: 'available'},
|
||||
plugins
|
||||
@@ -43,6 +45,7 @@ test('full pre run', (t) => {
|
||||
tt.plan(3)
|
||||
|
||||
pre({
|
||||
options: {branch: 'master'},
|
||||
npm,
|
||||
pkg: {name: 'unavailable'},
|
||||
plugins
|
||||
|
||||
Reference in New Issue
Block a user