Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd8ff5df43 | ||
|
|
a387c045a7 | ||
|
|
228451b7c9 | ||
|
|
3503407bf4 | ||
|
|
5025fcab55 | ||
|
|
6693080b51 | ||
|
|
a72d8f52af | ||
|
|
d7081fadb1 | ||
|
|
61d7d38ec2 |
@@ -68,9 +68,9 @@ Here is an example of the release type that will be done based on a commit messa
|
||||
|
||||
### Triggering a release
|
||||
|
||||
When pushing new commits to the release branch (i.e. `master`) with `git push` or by merging a pull request or merging from another branch, a CI build is triggered and runs the `semantic-release` command to make a release if there are relevant codebase changes since the last release.
|
||||
For each new commits added to the release branch (i.e. `master`) with `git push` or by merging a pull request or merging from another branch, a CI build is triggered and runs the `semantic-release` command to make a release if there are codebase changes since the last release that affect the package functionalities.
|
||||
|
||||
By default a release will be done for each push to the release branch that contains relevant code changes. If you need more control over the timing of releases you have a couple of options:
|
||||
If you need more control over the timing of releases you have a couple of options:
|
||||
- Publish releases on a distribution channel (for example 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, and you can decide when to make an automatically released version available to the stable channel, and promote it.
|
||||
- Develop on a `dev` branch and merge it to the release branch (i.e. `master`) once you are ready to publish. **semantic-release** will run only on pushes to the release branch.
|
||||
|
||||
@@ -83,11 +83,11 @@ After running the tests the command `semantic-release` will execute the followin
|
||||
| Verify Conditions | Verify all the conditions to proceed with the release with the [verify conditions plugins](docs/usage/plugins.md#verifyconditions-plugin). |
|
||||
| Get last release | Obtain the commit corresponding to the last release by analyzing [Git tags](https://git-scm.com/book/en/v2/Git-Basics-Tagging). |
|
||||
| Analyze commits | Determine the type of release with the [analyze commits plugin](docs/usage/plugins.md#analyzecommits-plugin) based on the commits added since the last release. |
|
||||
| Verify release | Verify the release conformity with the [verify release plugins](docs/usage/plugins.md#verifyrelease-plugin). |
|
||||
| Verify release | Verify the release conformity with the [verify release plugins](docs/usage/plugins.md#verifyrelease-plugin). |
|
||||
| Generate notes | Generate release notes with the [generate notes plugin](docs/usage/plugins.md#generatenotes-plugin) for the commits added since the last release. |
|
||||
| Create Git tag | Create a Git tag corresponding to the new release version |
|
||||
| Prepare | Prepare the release with the [prepare plugins](docs/usage/plugins.md#prepare-plugin). |
|
||||
| Publish | Publish the release with the [publish plugins](docs/usage/plugins.md#publish-plugin). |
|
||||
| Prepare | Prepare the release with the [prepare plugins](docs/usage/plugins.md#prepare-plugin). |
|
||||
| Publish | Publish the release with the [publish plugins](docs/usage/plugins.md#publish-plugin). |
|
||||
| Notify | Notify of new releases or errors with the [success](docs/usage/plugins.md#success-plugin) and [fail](docs/usage/plugins.md#fail-plugin) plugins. |
|
||||
|
||||
## Documentation
|
||||
|
||||
+18
-1
@@ -164,6 +164,21 @@ You can trigger a release by pushing to your Git repository. You deliberately ca
|
||||
|
||||
Yes, every commits that contains `[skip release]` or `[release skip]` in their message will be excluded from the commit analysis and won't participate in the release type determination.
|
||||
|
||||
## How can I change the type of commits that trigger a release?
|
||||
|
||||
By default **semantic-release** uses the [Angular Commit Message Conventions](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines) and triggers releases based on the following rules:
|
||||
|
||||
| Commit | Release type |
|
||||
|-----------------------------|----------------------------|
|
||||
| Commit with breaking change | ~~Major~~ Breaking release |
|
||||
| Commit with type `feat` | ~~Minor~~ Feature release |
|
||||
| Commit with type `fix` | Patch release |
|
||||
| Commit with type `perf` | Patch release |
|
||||
|
||||
See the [`@semantic-release/npm`](https://github.com/semantic-release/npm#npm-configuration) plugin documentation for more details.
|
||||
|
||||
This is fully customizable with the [`@semantic-release/commit-analyzer`](https://github.com/semantic-release/commit-analyzer) plugin's [`release-rules` option](https://github.com/semantic-release/commit-analyzer#release-rules).
|
||||
|
||||
## Is it *really* a good idea to release on every push?
|
||||
|
||||
It is indeed a great idea because it *forces* you to follow best practices. If you don’t feel comfortable releasing every feature or fix on your `master` you might not treat your `master` branch as intended.
|
||||
@@ -174,6 +189,8 @@ From [Understanding the GitHub Flow](https://guides.github.com/introduction/flow
|
||||
|
||||
If you need more control over the timing of releases, see [Triggering a release](../../README.md#triggering-a-release) for different options.
|
||||
|
||||
**Note**: Only the codebase changes altering the published package will trigger a release (for example new features, bug fixes or performance improvements would trigger a release while refactoring or changing code style would not). See [How can I change the type of commits that trigger a release?](#how-can-i-change-the-type-of-commits-that-trigger-a-release) for more details.
|
||||
|
||||
## Can I set the initial release version of my package to `0.0.1`?
|
||||
|
||||
This is not supported by **semantic-release** as it's not considered a good practice, mostly because [Semantic Versioning](https://semver.org) rules applies differently to major version zero.
|
||||
@@ -194,7 +211,7 @@ In addition the [verify conditions step](../../README.md#release-steps) verifies
|
||||
|
||||
See [Node version requirement](../support/node-version.md#node-version-requirement) for more details and solutions.
|
||||
|
||||
# What is npx?
|
||||
## What is npx?
|
||||
|
||||
[`npx`](https://www.npmjs.com/package/npx) – short for "npm exec" – is a CLI to find and execute npm binaries within the local `node_modules` folder or in the $PATH. If a binary can't be located npx will download the required package and execute it from its cache location.
|
||||
The tool is bundled with [npm](https://www.npmjs.com/package/npm) >= 5.2, or can be installed via `npm install -g npx`.
|
||||
|
||||
@@ -29,6 +29,15 @@ $ semantic-release
|
||||
|
||||
**Note**: Plugin options cannot be defined via CLI arguments and must be defined in the configuration file.
|
||||
|
||||
## Environment variables
|
||||
|
||||
| Variable | Description | Default |
|
||||
|-----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------|
|
||||
| `GIT_AUTHOR_NAME` | The author name associated with the [Git release tag](https://git-scm.com/book/en/v2/Git-Basics-Tagging). See [Git environment variables](https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables#_committing). | @semantic-release-bot. |
|
||||
| `GIT_AUTHOR_EMAIL` | The author email associated with the [Git release tag](https://git-scm.com/book/en/v2/Git-Basics-Tagging). See [Git environment variables](https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables#_committing). | @semantic-release-bot email address. |
|
||||
| `GIT_COMMITTER_NAME` | The committer name associated with the [Git release tag](https://git-scm.com/book/en/v2/Git-Basics-Tagging). See [Git environment variables](https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables#_committing). | @semantic-release-bot. |
|
||||
| `GIT_COMMITTER_EMAIL` | The committer email associated with the [Git release tag](https://git-scm.com/book/en/v2/Git-Basics-Tagging). See [Git environment variables](https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables#_committing). | @semantic-release-bot email address. |
|
||||
|
||||
## Options
|
||||
|
||||
### extends
|
||||
|
||||
@@ -15,6 +15,7 @@ const getGitAuthUrl = require('./lib/get-git-auth-url');
|
||||
const logger = require('./lib/logger');
|
||||
const {unshallow, verifyAuth, isBranchUpToDate, gitHead: getGitHead, tag, push} = require('./lib/git');
|
||||
const getError = require('./lib/get-error');
|
||||
const {COMMIT_NAME, COMMIT_EMAIL} = require('./lib/definitions/constants');
|
||||
|
||||
marked.setOptions({renderer: new TerminalRenderer()});
|
||||
|
||||
@@ -25,9 +26,16 @@ async function run(options, plugins) {
|
||||
logger.log('This run was not triggered in a known CI environment, running in dry-run mode.');
|
||||
options.dryRun = true;
|
||||
} else {
|
||||
// When running on CI, prevent the `git` CLI to prompt for username/password. See #703.
|
||||
process.env.GIT_ASKPASS = 'echo';
|
||||
process.env.GIT_TERMINAL_PROMPT = 0;
|
||||
// When running on CI, set the commits author and commiter info and prevent the `git` CLI to prompt for username/password. See #703.
|
||||
process.env = {
|
||||
GIT_AUTHOR_NAME: COMMIT_NAME,
|
||||
GIT_AUTHOR_EMAIL: COMMIT_EMAIL,
|
||||
GIT_COMMITTER_NAME: COMMIT_NAME,
|
||||
GIT_COMMITTER_EMAIL: COMMIT_EMAIL,
|
||||
...process.env,
|
||||
GIT_ASKPASS: 'echo',
|
||||
GIT_TERMINAL_PROMPT: 0,
|
||||
};
|
||||
}
|
||||
|
||||
if (isCi && isPr && !options.noCi) {
|
||||
@@ -46,6 +54,7 @@ async function run(options, plugins) {
|
||||
|
||||
await verify(options);
|
||||
|
||||
const {repositoryUrl} = options;
|
||||
options.repositoryUrl = await getGitAuthUrl(options);
|
||||
|
||||
if (!(await isBranchUpToDate(options.branch))) {
|
||||
@@ -60,7 +69,7 @@ async function run(options, plugins) {
|
||||
await verifyAuth(options.repositoryUrl, options.branch);
|
||||
} catch (err) {
|
||||
logger.error(`The command "${err.cmd}" failed with the error message %s.`, err.stderr);
|
||||
throw getError('EGITNOPERMISSION', {options});
|
||||
throw getError('EGITNOPERMISSION', {options, repositoryUrl});
|
||||
}
|
||||
|
||||
logger.log('Run automated release from branch %s', options.branch);
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
const RELEASE_TYPE = ['major', 'premajor', 'minor', 'preminor', 'patch', 'prepatch', 'prerelease'];
|
||||
|
||||
const FIRST_RELEASE = '1.0.0';
|
||||
|
||||
const COMMIT_NAME = 'semantic-release-bot';
|
||||
|
||||
const COMMIT_EMAIL = 'semantic-release-bot@martynus.net';
|
||||
|
||||
module.exports = {RELEASE_TYPE, FIRST_RELEASE, COMMIT_NAME, COMMIT_EMAIL};
|
||||
@@ -2,7 +2,7 @@ const url = require('url');
|
||||
const {inspect} = require('util');
|
||||
const {toLower, isString} = require('lodash');
|
||||
const pkg = require('../../package.json');
|
||||
const RELEASE_TYPE = require('./release-types');
|
||||
const {RELEASE_TYPE} = require('./constants');
|
||||
|
||||
const homepage = url.format({...url.parse(pkg.homepage), ...{hash: null}});
|
||||
const stringify = obj => (isString(obj) ? obj : inspect(obj, {breakLength: Infinity, depth: 2, maxArrayLength: 5}));
|
||||
@@ -27,15 +27,17 @@ Please make sure to add the \`repositoryUrl\` to the [semantic-release configura
|
||||
'docs/usage/configuration.md'
|
||||
)}).`,
|
||||
}),
|
||||
EGITNOPERMISSION: ({options}) => ({
|
||||
EGITNOPERMISSION: ({options, repositoryUrl}) => ({
|
||||
message: 'The push permission to the Git repository is required.',
|
||||
details: `**semantic-release** cannot push the version tag to the branch \`${
|
||||
options.branch
|
||||
}\` on remote Git repository.
|
||||
}\` on remote Git repository with URL \`${repositoryUrl}\`.
|
||||
|
||||
Please refer to the [authentication configuration documentation](${linkify(
|
||||
'docs/usage/ci-configuration.md#authentication'
|
||||
)}) to configure the Git credentials on your CI environment.`,
|
||||
)}) to configure the Git credentials on your CI environment and make sure the [repositoryUrl](${linkify(
|
||||
'docs/usage/configuration.md#repositoryurl'
|
||||
)}) is configured with a [valid Git URL](https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols).`,
|
||||
}),
|
||||
EINVALIDTAGFORMAT: ({tagFormat}) => ({
|
||||
message: 'Invalid `tagFormat` option.',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const {isString, isFunction, isArray, isPlainObject} = require('lodash');
|
||||
const RELEASE_TYPE = require('./release-types');
|
||||
const {RELEASE_TYPE} = require('./constants');
|
||||
|
||||
const validatePluginConfig = conf => isString(conf) || isString(conf.path) || isFunction(conf);
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
module.exports = ['major', 'premajor', 'minor', 'preminor', 'patch', 'prepatch', 'prerelease'];
|
||||
@@ -1,4 +1,5 @@
|
||||
const semver = require('semver');
|
||||
const {FIRST_RELEASE} = require('./definitions/constants');
|
||||
|
||||
module.exports = (type, lastRelease, logger) => {
|
||||
let version;
|
||||
@@ -6,7 +7,7 @@ module.exports = (type, lastRelease, logger) => {
|
||||
version = semver.inc(lastRelease.version, type);
|
||||
logger.log('The next release version is %s', version);
|
||||
} else {
|
||||
version = '1.0.0';
|
||||
version = FIRST_RELEASE;
|
||||
logger.log('There is no previous release, the next release version is %s', version);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -143,10 +143,10 @@ async function verifyTagName(tagName) {
|
||||
*
|
||||
* @param {String} branch The repository branch for which to verify status.
|
||||
*
|
||||
* @return {Boolean} `true` is the HEAD of the current local branch is the same as the HEAD of the remote branch, `false` otherwise.
|
||||
* @return {Boolean} `true` is the HEAD of the current local branch is the same as the HEAD of the remote branch, falsy otherwise.
|
||||
*/
|
||||
async function isBranchUpToDate(branch) {
|
||||
return isRefInHistory(await execa.stdout('git', ['rev-parse', `${branch}@{u}`]));
|
||||
return isRefInHistory(await execa.stdout('git', ['rev-parse', `origin/${branch}`]));
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
+2
-2
@@ -36,8 +36,8 @@
|
||||
"hook-std": "^0.4.0",
|
||||
"hosted-git-info": "^2.6.0",
|
||||
"lodash": "^4.17.4",
|
||||
"marked": "^0.3.9",
|
||||
"marked-terminal": "^2.0.0",
|
||||
"marked": "^0.4.0",
|
||||
"marked-terminal": "^3.0.0",
|
||||
"p-locate": "^2.0.0",
|
||||
"p-reduce": "^1.0.0",
|
||||
"read-pkg-up": "^3.0.0",
|
||||
|
||||
@@ -5,6 +5,7 @@ import clearModule from 'clear-module';
|
||||
import AggregateError from 'aggregate-error';
|
||||
import SemanticReleaseError from '@semantic-release/error';
|
||||
import DEFINITIONS from '../lib/definitions/plugins';
|
||||
import {COMMIT_NAME, COMMIT_EMAIL} from '../lib/definitions/constants';
|
||||
import {
|
||||
gitHead as getGitHead,
|
||||
gitTagHead,
|
||||
@@ -157,6 +158,12 @@ test.serial('Plugins are called with expected values', async t => {
|
||||
// Verify the tag has been created on the local and remote repo and reference the gitHead
|
||||
t.is(await gitTagHead(nextRelease.gitTag), nextRelease.gitHead);
|
||||
t.is(await gitRemoteTagHead(repositoryUrl, nextRelease.gitTag), nextRelease.gitHead);
|
||||
|
||||
// Verify the author/commiter name and email hve been set
|
||||
t.is(process.env.GIT_AUTHOR_NAME, COMMIT_NAME);
|
||||
t.is(process.env.GIT_AUTHOR_EMAIL, COMMIT_EMAIL);
|
||||
t.is(process.env.GIT_COMMITTER_NAME, COMMIT_NAME);
|
||||
t.is(process.env.GIT_COMMITTER_EMAIL, COMMIT_EMAIL);
|
||||
});
|
||||
|
||||
test.serial('Use custom tag format', async t => {
|
||||
|
||||
Reference in New Issue
Block a user