Add a _Node Support Policy_ section to the project's `README.md` file to indicate what this project, and its core team, are promising in terms of Node runtime support. Establishing a support policy provides reassurance to the community that they can expect a level of functionality from `semantic-release`, while providing guidance to the core maintainers, and everyone else that contributes, the level of support they should espire to. Closes #485
📦🚀 semantic-release
fully automated package publishing
Trust us, this will change your workflow for the better.
Out of the box this is just about commit-messages, but you can do so much more.
- Detect breaking changes using the test suite of your last release: cracks
- Detect breaking changes using your dependents’ test suites: Help out! Implement the dont-break plugin
- Detect breaking changes diffing your JSDoc interface: Help out! Implement the india plugin
- Abort releases with insufficient test coverage: Help out! Implement the istanbul plugin
- Abort releases with vulnerable dependencies in the tree: Help out! Implement the nsp plugin
- Everything you can imagine: Build Plugins!
Commands | Comment | |
---|---|---|
manual/before |
|
You manually decide what the next version is. You have to remember what major, minor and patch means. You have to remember to push both commits and tags. You have to wait for the CI to pass. |
semantic-release/after |
|
You describe the changes you’ve made. A new version is automatically published with the correct version number. |
This removes the immediate connection between human emotions and version numbers, so strictly following the SemVer spec is not a problem anymore – and that’s ultimately semantic-release
’s goal.
How does it work?
Instead of writing meaningless commit messages, we can take our time to think about the changes in the codebase and write them down. Following formalized conventions it is then possible to generate a helpful changelog and to derive the next semantic version number from them.
When semantic-release
is set up it will do that after every successful continuous integration build of your master branch (or any other branch you specify) and publish the new version for you. This way no human is directly involved in the release process and your releases are guaranteed to be unromantic and unsentimental.
If you fear the loss of control over timing and marketing implications of software releases you should know that semantic-release
supports release channels using npm
’s dist-tags. This way you can keep control over what your users end up using by default, you can decide when to promote an automatically released version to the stable channel, and you can choose which versions to write blogposts and tweets about. You can use the same mechanism to support older versions of your software, for example with important security fixes.
When pushing new commits with git push
a CI build is triggered. After running the tests the command semantic-release
will execute the following tasks in series:
Step | Description |
---|---|
Verify Conditions | Run the verifyConditions plugin |
Get last release | Obtain last release with the getLastRelease plugin |
Analyze commits | Determine the type of release to do with the analyzeCommits plugin |
Verify release | Call the verifyRelease plugin |
Generate notes | Generate release notes with plugin generateNotes |
Publish | Call the publish plugin |
Default Commit Message Format
This module ships with the AngularJS Commit Message Conventions and changelog generator, but you can define your own style.
Each commit message consists of a header, a body and a footer. The header has a special format that includes a type, a scope and a subject (full explanation):
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
You can simplify using this convention for yourself and contributors by using commitizen and commitlint or semantic-git-commit-cli.
Patch Release
fix(pencil): stop graphite breaking when too much pressure applied
Minor Feature Release
feat(pencil): add 'graphiteWidth' option
Major Breaking Release
perf(pencil): remove graphiteWidth option
BREAKING CHANGE: The graphiteWidth option has been removed. The default graphite width of 10mm is always used for performance reasons.
Setup
npm install -g semantic-release-cli
cd your-module
semantic-release-cli setup
This is what happens under the hood.
Options
You can pass options either via command line (in kebab-case) or in the release
field of your package.json
(in camelCase). The following two examples are the same, but CLI arguments take precedence.
CLI
semantic-release --branch next
package.json
"release": {
"branch": "next"
}
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 inpackage.json
or git origin url. Any valid git url format is supported (See Git protocols). If the Github plugin is used the URL must be a valid Github URL that include theowner
, therepository
name and thehost
. The Github shorthand URL is not supported.dry-run
: Dry-run mode, skipping verifyConditions, publishing and release, printing next version and release notesdebug
: Output debugging information
A few notes on npm
config:
-
The
npm
token can only be defined in the environment asNPM_TOKEN
, because that’s wherenpm
itself is going to read it from. -
In order to publish to a different
npm
registry you can specify that inside thepackage.json
’spublishConfig
field. -
If you want to use another dist-tag for your publishes than
'latest'
you can specify that inside thepackage.json
’spublishConfig
field.
Plugins
There are numerous steps where you can customize semantic-release
’s behaviour using plugins. A plugin is a regular option, but passed inside the release
block of package.json
:
{
"release": {
"analyzeCommits": "npm-module-name",
"generateNotes": "./path/to/a/local/module",
"verifyConditions": {
"path": "./path/to/a/module",
"additional": "config"
}
}
}
semantic-release --analyze-commits="npm-module-name"
A plugin itself is an async function that always receives three arguments.
module.exports = function (pluginConfig, config, callback) {}
pluginConfig
: If the user of your plugin specifies additional plugin config in thepackage.json
(see theverifyConditions
example above) then it’s this object.config
: A config object containing a lot of information to act upon.options
:semantic-release
options likedebug
, orbranch
- For certain plugins the
config
object contains even more information. See below.
analyzeCommits
This plugin is responsible for determining the type of the next release. It additionally receives a commits
array inside config
. One commit is an object with a message
and hash
property. Call the callback with 'major'
, 'premajor'
, 'minor'
, 'preminor'
, 'patch'
, 'prepatch'
, 'prerelease'
, or null
if nothing changed.
While it may be tempting to use 'prepatch'
, 'preminor'
& 'prerelease'
as part of a release process, this is strongly discouraged. A better approach is to use dist-tags to create release channels (such as 'latest', 'next', 'stable') and to return only 'major'
, 'premajor'
and 'minor'
from the commit analyzer.
Have a look at the default implementation.
verifyConditions
This plugins is responsible for verifying that a release should happen in the first place. The default implementations are:
- travis: verifies that the publish is happening on Travis, that it’s the right branch, and that all other build jobs succeeded.
- github: verifies a Github authentication is set and valid.
- npm: verifies an npm authentication is set and valid.
Passing an array of plugins will run them in series.
verifyRelease
This plugin is responsible for verifying a release that was determined before and is about to be published. There is no default implementation. It additionally receives nextRelease
, lastRelease
and commits
inside config
. While commits
is the same as with analyzeCommits, nextRelease
contains a type
(e.g. 'major'
) and the new version (e.g. '1.0.0'
) and lastRelease
contains the old version
, the gitHead
at the time of the release and the npm dist-tag
(e.g. 'latest'
). Using this information you could detect breaking changes or hold back certain types of releases. Again: Be creative.
Passing an array of plugins will run them in series.
getLastRelease
This plugin is responsible for determining a package’s last release version. The default implementation uses the last published version on a npm registry.
generateNotes
This plugin is responsible for generating release notes. Call the callback with the notes as a string. Have a look at the default implementation.
It receives a commits
array, the lastRelease
and nextRelease
inside config
.
publish
This plugins is responsible for publishing the release. The default implementations publish on npm and github.
Passing an array of plugins will run them in series.
ITYMFAQLT
I think you might frequently ask questions like these
Why is the package.json
’s version not updated in my repository?
The npm
docs even state:
The most important things in your package.json are the name and version fields. Those are actually required, and your package won’t install without them. – npm docs
While this entirely true the version number doesn’t have to be checked into source control. semantic-release
takes care of the version field right before npm publish
uses it – and this is the only point where it really is required.
Is there a way to preview which version would currently get published?
If you run npm run semantic-release
locally a dry run gets performed, which logs the version that would currently get published.
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>
.
Can I manually trigger the release of a specific version?
You can trigger a release by pushing to your GitHub repository. You deliberately cannot trigger a specific version release, because this is the whole point of semantic-release
. Start your packages with 1.0.0
and semver on.
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 making every passing feature or fix on your master branch addressable via npm
you might not treat your master right. Have a look at branch workflows. If you still think you should have control over the exact point in time of your release, e.g. because you are following a release schedule, you can release only on the production
/deploy
/release
branch and push your code there in certain intervals, or better yet use dist-tags.
Why should I trust semantic-release
with my releases?
semantic-release
has a full unit- and integration-test-suite that tests actual npm
publishes against the npm-registry-couchapp. A new version won’t get published if it doesn’t pass on all these engines.
Why does semantic-release
require node version >= 8
Being able to write code for just the most recent node versions greatly simplifies development. More language features are available, no transpilation is required, less test builds are to be run, awaited and debugged.
For a special purpose tool like semantic-release
, that's only meant to be used in controlled CI environments, we think it's okay to have such a high version requirement. As semantic-release
handles package publishing we expect almost every project to have at least one build job running node 8 already – and that's all it takes. Even if that's not that case semantic-release
can still be executed with the help of npx (npx -p node@8 npm run semantic-release
).
Please see our Node Support Policy for our long-term promise for supporting Node.
Badge
Use this in one of your projects? Include one of these badges in your README.md to let people know that your package is published using semantic-release
.
[](https://github.com/semantic-release/semantic-release)
[](https://github.com/semantic-release/semantic-release)
[](https://github.com/semantic-release/semantic-release)
Node Support Policy
We only support Long-Term Support versions of Node starting with Node 8.9.0 (LTS).
We specifically limit our support to LTS versions of Node, not because this package won't work on other versions, but because we have a limited amount of time, and supporting LTS offers the greatest return on that investment.
It's possible this package will work correctly on newer versions of Node. It may even be possible to use this package on older versions of Node, though that's more unlikely as we'll make every effort to take advantage of features available in the oldest LTS version we support.
As each Node LTS version reaches its end-of-life we will remove that version from the node engines property of our package's package.json file. Removing a Node version is considered a breaking change and will entail the publishing of a new major version of this package. We will not accept any requests to support an end-of-life version of Node. Any merge requests or issues supporting an end-of-life version of Node will be closed.
We will accept code that allows this package to run on newer, non-LTS, versions of Node. Furthermore, we will attempt to ensure our own changes work on the latest version of Node. To help in that commitment, our continuous integration setup runs against all LTS versions of Node in addition the most recent Node release; called current.
JavaScript package managers should allow you to install this package with any version of Node, with, at most, a warning if your version of Node does not fall within the range specified by our node engines property. If you encounter issues installing this package, please report the issue to your package manager.
License
MIT License 2015 © Stephan Bönnemann and contributors