Compare commits

..
6 Commits
11 changed files with 142 additions and 59 deletions
+1
View File
@@ -0,0 +1 @@
base: app0ZOxG0FnHmOiuU
+2 -2
View File
@@ -87,8 +87,8 @@ When pushing new commits with `git push` a CI build is triggered. After running
| Step | Description |
| ------------------ | ------------------------------------------------------------------------------------------- |
| Verify Conditions` | Run the [verifyConditions](#verifyConditions) plugin) |
| Get last release` | Obtain last release with the [getLastRelease](#getLastRelease) plugin |
| Verify Conditions | Run the [verifyConditions](#verifyConditions) plugin) |
| Get last release | Obtain last release with the [getLastRelease](#getLastRelease) plugin |
| Analyze commits | Determine the type of release to do with the [analyzeCommits](#analyzeCommits) plugin |
| Verify release | Call the [verifyRelease](#verifyRelease) plugin |
| npm publish | Update the version in `package.json` and call `npm publish` |
+4 -3
View File
@@ -15,7 +15,7 @@
}
},
"dependencies": {
"@semantic-release/commit-analyzer": "^3.0.1",
"@semantic-release/commit-analyzer": "^4.0.0",
"@semantic-release/condition-travis": "^6.0.0",
"@semantic-release/error": "^2.1.0",
"@semantic-release/last-release-npm": "^2.0.0",
@@ -25,7 +25,9 @@
"debug": "^3.1.0",
"execa": "^0.8.0",
"fs-extra": "^4.0.2",
"get-stream": "^3.0.0",
"git-head": "^1.2.1",
"git-log-parser": "^1.2.0",
"github": "^12.0.0",
"lodash": "^4.0.0",
"marked": "^0.3.6",
@@ -52,13 +54,12 @@
"eslint-plugin-prettier": "^2.3.0",
"eslint-plugin-promise": "^3.5.0",
"eslint-plugin-standard": "^3.0.1",
"get-stream": "^3.0.0",
"mockserver-client": "^1.0.16",
"nock": "^9.0.2",
"npm-registry-couchapp": "^2.6.12",
"nyc": "^11.2.1",
"p-map-series": "^1.0.0",
"prettier": "^1.7.0",
"prettier": "~1.8.0",
"proxyquire": "^1.8.0",
"rimraf": "^2.5.0",
"sinon": "^4.0.0",
+22 -25
View File
@@ -1,4 +1,6 @@
const execa = require('execa');
const gitLogParser = require('git-log-parser');
const getStream = require('get-stream');
const debug = require('debug')('semantic-release:get-commits');
const getVersionHead = require('./get-version-head');
const {debugShell} = require('./debug');
@@ -65,28 +67,17 @@ module.exports = async ({version, gitHead}, branch) => {
debugShell('Unshallow repo', shell, debug);
}
try {
const shell = await execa('git', [
'log',
'--format=format:%H==SPLIT==%B==END==',
`${gitHead ? gitHead + '..' : ''}HEAD`,
]);
debugShell('Get commits', shell, debug);
const commits = shell.stdout
.split('==END==')
.filter(raw => !!raw.trim())
.map(raw => {
const [hash, message] = raw.trim().split('==SPLIT==');
return {hash, message};
});
logger.log('Found %s commits since last release', commits.length);
debug('Parsed commits: %o', commits);
return {commits, lastRelease: {version, gitHead}};
} catch (err) {
debug(err);
logger.log('Found no commit since last release');
return {commits: [], lastRelease: {version, gitHead}};
}
Object.assign(gitLogParser.fields, {hash: 'H', message: 'B', gitTags: 'd', committerDate: {key: 'ci', type: Date}});
const commits = (await getStream.array(gitLogParser.parse({_: `${gitHead ? gitHead + '..' : ''}HEAD`}))).map(
commit => {
commit.message = commit.message.trim();
commit.gitTags = commit.gitTags.trim();
return commit;
}
);
logger.log('Found %s commits since last release', commits.length);
debug('Parsed commits: %o', commits);
return {commits, lastRelease: {version, gitHead}};
};
function noGitHeadMessage(branch, version) {
@@ -94,18 +85,24 @@ function noGitHeadMessage(branch, version) {
This means semantic-release can not extract the commits between now and then.
This is usually caused by releasing from outside the repository directory or with innaccessible git metadata.
You can recover from this error by creating a tag for the version "${version}" on the commit corresponding to this release:
You can recover from this error by creating a tag for the version "${
version
}" on the commit corresponding to this release:
$ git tag -f v${version} <commit sha1 corresponding to last release>
$ git push -f --tags origin ${branch}
`;
}
function notInHistoryMessage(gitHead, branch, version) {
return `The commit the last release of this package was derived from is not in the direct history of the "${branch}" branch.
return `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 restoring the commit "${gitHead}" or by creating a tag for the version "${version}" on the commit corresponding to this release:
You can recover from this error by restoring the commit "${gitHead}" or by creating a tag for the version "${
version
}" on the commit corresponding to this release:
$ git tag -f v${version || '<version>'} <commit sha1 corresponding to last release>
$ git push -f --tags origin ${branch}
`;
+3 -3
View File
@@ -7,9 +7,9 @@ module.exports = {
log(...args) {
const [format, ...rest] = args;
console.log(
`${chalk.grey('[Semantic release]:')}${typeof format === 'string'
? ` ${format.replace(/%[^%]/g, seq => chalk.magenta(seq))}`
: ''}`,
`${chalk.grey('[Semantic release]:')}${
typeof format === 'string' ? ` ${format.replace(/%[^%]/g, seq => chalk.magenta(seq))}` : ''
}`,
...(typeof format === 'string' ? [] : [format]).concat(rest)
);
},
+82
View File
@@ -42,14 +42,48 @@ test.serial('Get all commits when there is no last release', async t => {
t.is(result.commits.length, 2);
t.is(result.commits[0].hash.substring(0, 7), commits[0].hash);
t.is(result.commits[0].message, commits[0].message);
t.truthy(result.commits[0].committerDate);
t.truthy(result.commits[0].author.name);
t.truthy(result.commits[0].committer.name);
t.is(result.commits[1].hash.substring(0, 7), commits[1].hash);
t.is(result.commits[1].message, commits[1].message);
t.truthy(result.commits[1].committerDate);
t.truthy(result.commits[1].author.name);
t.truthy(result.commits[1].committer.name);
// Verify the last release is returned and updated
t.truthy(result.lastRelease);
t.falsy(result.lastRelease.gitHead);
t.falsy(result.lastRelease.version);
});
test.serial('Get all commits with gitTags', async t => {
// Create a git repository, set the current working directory at the root of the repo
await gitRepo();
// Add commits to the master branch
let commits = await gitCommits(['First']);
// Create the tag corresponding to version 1.0.0
await gitTagVersion('v1.0.0');
// Add new commits to the master branch
commits = (await gitCommits(['Second'])).concat(commits);
// Retrieve the commits with the commits module
const result = await t.context.getCommits({}, 'master');
// Verify the commits created and retrieved by the module are identical
t.is(result.commits.length, 2);
t.is(result.commits[0].hash.substring(0, 7), commits[0].hash);
t.is(result.commits[0].message, commits[0].message);
t.truthy(result.commits[0].committerDate);
t.truthy(result.commits[0].author.name);
t.truthy(result.commits[0].committer.name);
t.is(result.commits[0].gitTags, '(HEAD -> master)');
t.is(result.commits[1].hash.substring(0, 7), commits[1].hash);
t.is(result.commits[1].message, commits[1].message);
t.truthy(result.commits[1].committerDate);
t.truthy(result.commits[1].author.name);
t.truthy(result.commits[1].committer.name);
t.is(result.commits[1].gitTags, '(tag: v1.0.0)');
});
test.serial('Get all commits when there is no last release, including the ones not in the shallow clone', async t => {
// Create a git repository, set the current working directory at the root of the repo
const repo = await gitRepo();
@@ -68,8 +102,14 @@ test.serial('Get all commits when there is no last release, including the ones n
t.is(result.commits.length, 2);
t.is(result.commits[0].hash.substring(0, 7), commits[0].hash);
t.is(result.commits[0].message, commits[0].message);
t.truthy(result.commits[0].committerDate);
t.truthy(result.commits[0].author.name);
t.truthy(result.commits[0].committer.name);
t.is(result.commits[1].hash.substring(0, 7), commits[1].hash);
t.is(result.commits[1].message, commits[1].message);
t.truthy(result.commits[1].committerDate);
t.truthy(result.commits[1].author.name);
t.truthy(result.commits[1].committer.name);
// Verify the last release is returned and updated
t.truthy(result.lastRelease);
t.falsy(result.lastRelease.gitHead);
@@ -89,8 +129,14 @@ test.serial('Get all commits since gitHead (from lastRelease)', async t => {
t.is(result.commits.length, 2);
t.is(result.commits[0].hash.substring(0, 7), commits[0].hash);
t.is(result.commits[0].message, commits[0].message);
t.truthy(result.commits[0].committerDate);
t.truthy(result.commits[0].author.name);
t.truthy(result.commits[0].committer.name);
t.is(result.commits[1].hash.substring(0, 7), commits[1].hash);
t.is(result.commits[1].message, commits[1].message);
t.truthy(result.commits[1].committerDate);
t.truthy(result.commits[1].author.name);
t.truthy(result.commits[1].committer.name);
// Verify the last release is returned and updated
t.truthy(result.lastRelease);
t.is(result.lastRelease.gitHead, commits[commits.length - 1].hash);
@@ -112,6 +158,9 @@ test.serial('Get all commits since gitHead (from lastRelease) on a detached head
t.is(result.commits.length, 1);
t.is(result.commits[0].hash.substring(0, 7), commits[1].hash);
t.is(result.commits[0].message, commits[1].message);
t.truthy(result.commits[0].committerDate);
t.truthy(result.commits[0].author.name);
t.truthy(result.commits[0].committer.name);
// Verify the last release is returned and updated
t.truthy(result.lastRelease);
t.is(result.lastRelease.gitHead, commits[commits.length - 1].hash);
@@ -135,8 +184,14 @@ test.serial('Get all commits since gitHead (from tag) ', async t => {
t.is(result.commits.length, 2);
t.is(result.commits[0].hash.substring(0, 7), commits[0].hash);
t.is(result.commits[0].message, commits[0].message);
t.truthy(result.commits[0].committerDate);
t.truthy(result.commits[0].author.name);
t.truthy(result.commits[0].committer.name);
t.is(result.commits[1].hash.substring(0, 7), commits[1].hash);
t.is(result.commits[1].message, commits[1].message);
t.truthy(result.commits[1].committerDate);
t.truthy(result.commits[1].author.name);
t.truthy(result.commits[1].committer.name);
// Verify the last release is returned and updated
t.truthy(result.lastRelease);
t.is(result.lastRelease.gitHead.substring(0, 7), commits[commits.length - 1].hash);
@@ -162,6 +217,9 @@ test.serial('Get all commits since gitHead (from tag) on a detached head repo',
t.is(result.commits.length, 1);
t.is(result.commits[0].hash.substring(0, 7), commits[1].hash);
t.is(result.commits[0].message, commits[1].message);
t.truthy(result.commits[0].committerDate);
t.truthy(result.commits[0].author.name);
t.truthy(result.commits[0].committer.name);
// Verify the last release is returned and updated
t.truthy(result.lastRelease);
t.is(result.lastRelease.gitHead.substring(0, 7), commits[commits.length - 1].hash);
@@ -185,8 +243,14 @@ test.serial('Get all commits since gitHead (from tag formatted like v<version>)
t.is(result.commits.length, 2);
t.is(result.commits[0].hash.substring(0, 7), commits[0].hash);
t.is(result.commits[0].message, commits[0].message);
t.truthy(result.commits[0].committerDate);
t.truthy(result.commits[0].author.name);
t.truthy(result.commits[0].committer.name);
t.is(result.commits[1].hash.substring(0, 7), commits[1].hash);
t.is(result.commits[1].message, commits[1].message);
t.truthy(result.commits[1].committerDate);
t.truthy(result.commits[1].author.name);
t.truthy(result.commits[1].committer.name);
// Verify the last release is returned and updated
t.truthy(result.lastRelease);
t.is(result.lastRelease.gitHead.substring(0, 7), commits[commits.length - 1].hash);
@@ -210,8 +274,14 @@ test.serial('Get commits when last release gitHead is missing but a tag match th
t.is(result.commits.length, 2);
t.is(result.commits[0].hash.substring(0, 7), commits[0].hash);
t.is(result.commits[0].message, commits[0].message);
t.truthy(result.commits[0].committerDate);
t.truthy(result.commits[0].author.name);
t.truthy(result.commits[0].committer.name);
t.is(result.commits[1].hash.substring(0, 7), commits[1].hash);
t.is(result.commits[1].message, commits[1].message);
t.truthy(result.commits[1].committerDate);
t.truthy(result.commits[1].author.name);
t.truthy(result.commits[1].committer.name);
// Verify the last release is returned and updated
t.truthy(result.lastRelease);
t.is(result.lastRelease.gitHead.substring(0, 7), commits[commits.length - 1].hash);
@@ -233,8 +303,14 @@ test.serial('Get all commits since gitHead, when gitHead are mising from the sha
t.is(result.commits.length, 2);
t.is(result.commits[0].hash.substring(0, 7), commits[0].hash);
t.is(result.commits[0].message, commits[0].message);
t.truthy(result.commits[0].committerDate);
t.truthy(result.commits[0].author.name);
t.truthy(result.commits[0].committer.name);
t.is(result.commits[1].hash.substring(0, 7), commits[1].hash);
t.is(result.commits[1].message, commits[1].message);
t.truthy(result.commits[1].committerDate);
t.truthy(result.commits[1].author.name);
t.truthy(result.commits[1].committer.name);
// Verify the last release is returned and updated
t.truthy(result.lastRelease);
t.is(result.lastRelease.gitHead.substring(0, 7), commits[commits.length - 1].hash);
@@ -263,8 +339,14 @@ test.serial('Get all commits since gitHead from tag, when tags are mising from t
t.is(result.commits.length, 2);
t.is(result.commits[0].hash.substring(0, 7), commits[0].hash);
t.is(result.commits[0].message, commits[0].message);
t.truthy(result.commits[0].committerDate);
t.truthy(result.commits[0].author.name);
t.truthy(result.commits[0].committer.name);
t.is(result.commits[1].hash.substring(0, 7), commits[1].hash);
t.is(result.commits[1].message, commits[1].message);
t.truthy(result.commits[1].committerDate);
t.truthy(result.commits[1].author.name);
t.truthy(result.commits[1].committer.name);
// Verify the last release is returned and updated
t.truthy(result.lastRelease);
t.is(result.lastRelease.gitHead.substring(0, 7), commits[commits.length - 1].hash);
+7 -7
View File
@@ -13,13 +13,13 @@ import pMapSeries from 'p-map-series';
*/
/**
* Create a temporary git repository and change the current working directory to the repository root.
*
* @method gitCommits
* @param {Array<Commit>} commits the created commits.
*
* @return {string} The path of the repository.
*/
* Create a temporary git repository and change the current working directory to the repository root.
*
* @method gitCommits
* @param {Array<Commit>} commits the created commits.
*
* @return {string} The path of the repository.
*/
export async function gitRepo() {
const dir = tempy.directory();
+3 -1
View File
@@ -408,7 +408,9 @@ test.serial('Create a tag as a recovery solution for "ENOTINHISTORY" error', asy
t.regex(
stderr,
new RegExp(
`You can recover from this error by restoring the commit "${head}" or by creating a tag for the version "${version}" on the commit corresponding to this release`
`You can recover from this error by restoring the commit "${head}" or by creating a tag for the version "${
version
}" on the commit corresponding to this release`
)
);