feat: allow to release from local machine
This commit is contained in:
parent
5cc62e49ee
commit
5bc46a08cf
@ -168,6 +168,7 @@ semantic-release
|
||||
These options are currently available:
|
||||
- `branch`: The branch on which releases should happen. Default: `'master'`
|
||||
- `repositoryUrl`: The git repository URL. Default: `repository` property in `package.json` or git origin url. Any valid git url format is supported (See [Git protocols](https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols)). If the [Github plugin](https://github.com/semantic-release/github) is used the URL must be a valid Github URL that include the `owner`, the `repository` name and the `host`. The Github shorthand URL is not supported.
|
||||
- `no-ci`: Skip Continuous Integration environment verifications, allowing to make releases from a local machine
|
||||
- `dry-run`: Dry-run mode, skip publishing, print next version and release notes
|
||||
- `extends`: Array of module or files path containing a shareable configuration. Options defined via CLI or in the `release` property will take precedence over the one defined in a shareable configuration.
|
||||
- `debug`: Output debugging information
|
||||
@ -269,7 +270,8 @@ If you run `npm run semantic-release` locally a dry run gets performed, which lo
|
||||
|
||||
### Can I run this on my own machine rather than on a CI server?
|
||||
|
||||
Of course you can, but this doesn’t necessarily mean you should. Running your tests on an independent machine before releasing software is a crucial part of this workflow. Also it is a pain to set this up locally, with tokens lying around and everything. That said, you can run the scripts with `--debug=false` explicitly. You have to export `GH_TOKEN=<your_token>` and `NPM_TOKEN=<your_other_token>`.
|
||||
Yes, you can by explicitly setting the [`--no-ci` CLI option](#options), but this doesn’t necessarily mean you should. Running your tests on an independent machine before releasing software is a crucial part of this workflow.
|
||||
You will need to set all necessary authentication token (like `GH_TOKEN` and `NPM_TOKEN`) on your local machine.
|
||||
|
||||
### Can I manually trigger the release of a specific version?
|
||||
|
||||
|
4
cli.js
4
cli.js
@ -27,6 +27,10 @@ module.exports = async () => {
|
||||
)
|
||||
.option('--generate-notes <path>', 'Path or package name for the generateNotes plugin')
|
||||
.option('--publish <paths>', 'Comma separated list of paths or packages name for the publish plugin(s)', list)
|
||||
.option(
|
||||
'--no-ci',
|
||||
'Skip Continuous Integration environment verifications, allowing to make releases from a local machine'
|
||||
)
|
||||
.option('--debug', 'Output debugging information')
|
||||
.option(
|
||||
'-d, --dry-run',
|
||||
|
6
index.js
6
index.js
@ -10,13 +10,13 @@ const {gitHead: getGitHead, isGitRepo} = require('./lib/git');
|
||||
module.exports = async opts => {
|
||||
const {isCi, branch, isPr} = envCi();
|
||||
|
||||
if (!isCi && !opts.dryRun) {
|
||||
if (!isCi && !opts.dryRun && !opts.noCi) {
|
||||
logger.log('This run was not triggered in a known CI environment, running in dry-run mode.');
|
||||
opts.dryRun = true;
|
||||
}
|
||||
|
||||
if (isCi && isPr) {
|
||||
logger.log('This run was triggered by a pull request and therefore a new version won’t be published.');
|
||||
if (isCi && isPr && !opts.noCi) {
|
||||
logger.log("This run was triggered by a pull request and therefore a new version won't be published.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -209,7 +209,7 @@ test.serial('Dry-run skips publish', async t => {
|
||||
t.is(publish.callCount, 0);
|
||||
});
|
||||
|
||||
test.serial('Force a dry-run if not on a CI', async t => {
|
||||
test.serial('Force a dry-run if not on a CI and ignore "noCi" is not explicitly set', 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
|
||||
@ -257,6 +257,58 @@ test.serial('Force a dry-run if not on a CI', async t => {
|
||||
t.is(publish.callCount, 0);
|
||||
});
|
||||
|
||||
test.serial('Allow local releases with "noCi" option', 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);
|
||||
|
||||
const lastRelease = {version: '1.0.0', gitHead: commits[commits.length - 1].hash, gitTag: 'v1.0.0'};
|
||||
const nextRelease = {type: 'major', version: '2.0.0', gitHead: await getGitHead(), gitTag: 'v2.0.0'};
|
||||
const notes = 'Release notes';
|
||||
|
||||
const verifyConditions = stub().resolves();
|
||||
const getLastRelease = stub().resolves(lastRelease);
|
||||
const analyzeCommits = stub().resolves(nextRelease.type);
|
||||
const verifyRelease = stub().resolves();
|
||||
const generateNotes = stub().resolves(notes);
|
||||
const publish = stub().resolves();
|
||||
|
||||
const options = {
|
||||
noCi: true,
|
||||
branch: 'master',
|
||||
repositoryUrl: 'git@hostname.com:owner/module.git',
|
||||
verifyConditions,
|
||||
getLastRelease,
|
||||
analyzeCommits,
|
||||
verifyRelease,
|
||||
generateNotes,
|
||||
publish,
|
||||
};
|
||||
|
||||
const semanticRelease = proxyquire('..', {
|
||||
'./lib/logger': t.context.logger,
|
||||
'env-ci': () => ({isCi: false, branch: 'master', isPr: true}),
|
||||
});
|
||||
t.truthy(await semanticRelease(options));
|
||||
|
||||
t.not(t.context.log.args[0][0], 'This run was not triggered in a known CI environment, running in dry-run mode.');
|
||||
t.not(
|
||||
t.context.log.args[0][0],
|
||||
"This run was triggered by a pull request and therefore a new version won't be published."
|
||||
);
|
||||
t.is(verifyConditions.callCount, 1);
|
||||
t.is(getLastRelease.callCount, 1);
|
||||
t.is(analyzeCommits.callCount, 1);
|
||||
t.is(verifyRelease.callCount, 1);
|
||||
t.is(generateNotes.callCount, 1);
|
||||
t.is(publish.callCount, 1);
|
||||
});
|
||||
|
||||
test.serial('Accept "undefined" values for the "getLastRelease" and "generateNotes" plugins', async t => {
|
||||
// Create a git repository, set the current working directory at the root of the repo
|
||||
await gitRepo();
|
||||
@ -333,7 +385,7 @@ test.serial('Returns falsy value if triggered by a PR', async t => {
|
||||
t.falsy(await semanticRelease({repositoryUrl: 'git@hostname.com:owner/module.git'}));
|
||||
t.is(
|
||||
t.context.log.args[0][0],
|
||||
'This run was triggered by a pull request and therefore a new version won’t be published.'
|
||||
"This run was triggered by a pull request and therefore a new version won't be published."
|
||||
);
|
||||
});
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user