Security News
vlt Debuts New JavaScript Package Manager and Serverless Registry at NodeConf EU
vlt introduced its new package manager and a serverless registry this week, innovating in a space where npm has stagnated.
semantic-release
Advanced tools
The semantic-release npm package automates the versioning and package publishing process based on semantic versioning (SemVer) principles. It analyzes commits since the last release to determine the type of version change (major, minor, or patch) and generates a changelog. It then publishes the new version to npm and can also update GitHub/GitLab releases.
Automated Version Management
Automatically analyzes commits, determines the next semantic version, generates a changelog, and publishes the package. The code snippet shows a basic configuration in a package.json file.
"release": {
"branches": ["main"],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/npm",
"@semantic-release/github"
]
}
Customizable Plugins
semantic-release's behavior can be customized with plugins. This example configures the commit analyzer and release notes generator to use the Angular preset.
"plugins": [
["@semantic-release/commit-analyzer", {
"preset": "angular"
}],
["@semantic-release/release-notes-generator", {
"preset": "angular"
}],
"@semantic-release/npm",
"@semantic-release/github"
]
Continuous Integration (CI) Configuration
Integrates with CI tools like GitHub Actions to automate the release process. This example shows a GitHub Actions workflow that sets up a job for semantic-release.
{
"name": "semantic-release",
"on": {
"push": {
"branches": ["main"]
}
},
"jobs": {
"release": {
"runs-on": "ubuntu-latest",
"steps": [
{
"name": "Checkout repository",
"uses": "actions/checkout@v2"
},
{
"name": "Setup Node.js",
"uses": "actions/setup-node@v1",
"with": {
"node-version": "12"
}
},
{
"name": "semantic-release",
"uses": "semantic-release-plus/docker@v1",
"env": {
"GITHUB_TOKEN": "${{ secrets.GITHUB_TOKEN }}",
"NPM_TOKEN": "${{ secrets.NPM_TOKEN }}"
}
}
]
}
}
}
Similar to semantic-release, standard-version automates versioning and CHANGELOG generation based on commit messages, following the Conventional Commits specification. Unlike semantic-release, it does not automatically publish to npm or create GitHub/GitLab releases, focusing instead on versioning and changelog generation.
release-it is a CLI tool for automating versioning and package publishing, similar to semantic-release. It supports plugins for extending functionality but requires more manual configuration for things like generating changelogs and determining version bumps based on commit messages.
While primarily a tool for managing monorepos, Lerna also offers features for automated package publishing similar to semantic-release. It can increment package versions and publish to npm, but it's more focused on managing dependencies and versions across multiple packages in a monorepo.
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 | |
---|---|---|
manual |
| 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 |
| You think about and 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.
“We fail to follow SemVer – and why it needn’t matter”
JSConf Budapest 2015
This talk gives you a complete introduction to the underlying concepts of this module
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 this then possible to generate a helpful changelog and to derive the next semantic version number from them.
Note: This module ships with the AngularJS Commit Message Conventions and changelog generator, but you can define your own style.
Commit Message Format
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:
():
```When semantic-release
got setup 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. That 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.
This is what happens in series:
1. git push | 2. semantic-release pre | 3. npm publish | 4. semantic-release post |
---|---|---|---|
New code is pushed and triggers a CI build. | Based on all commits that happened since the last release, the new version number gets written to the package.json . | The new version gets published to npm . | A changelog gets generated and a release (including a git tag) on GitHub gets created. |
Note: The current release/tag implementation is tied to GitHub, but could be opened up to Bitbucket, GitLab, et al. Feel free to send PRs for these services.
npm install -g semantic-release-cli
cd your-module
semantic-release-cli setup
This is what happens under the hood.
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 | package.json |
---|---|
|
|
These options are currently available:
branch
: The branch on which releases should happen. Default: 'master'
debug
: If true doesn't actually publish to npm or write things to file. Default: !process.env.CI
githubToken
: The token used to authenticate with GitHub. Default: process.env.GH_TOKEN
githubUrl
: Optional. Pass your GitHub Enterprise endpoint.A few notes on npm
config:
The npm
token can only be defined in the environment as NPM_TOKEN
, because that's where npm
itself is going to read it from.
In order to publish to a different npm
registry you can just configure that how you would usually do it and semantic-release
will respect that setting.
If you want to use another dist-tag for your publishes than 'latest'
you can specify that inside the package.json
's publishConfig
field.
semantic-release
generally tries to orientate itself towards npm
– it inherits the loglevel for example.
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 pre --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 the package.json
(see the verifyConditions
example above) then it's this object.config
: A config object containing a lot of information to act upon.
env
: All environment variablesnpm
: Select npm configuration bits like registry
, tag
and auth
options
: semantic-release
options like debug
, or branch
pkg
: Parsed package.json
config
object contains even more information. See below.callback
: If an error occurs pass it as first argument. Otherwise pass your result as second argument.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. Have a look at the default implementation.
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.
verifyConditions
This plugins is responsible for verifying that a release should happen in the first place. For example, the default implementation verifies that the publish is happening on Travis, that it's the right branch, and that all other build jobs succeeded. There are more use cases for this, e.g. verifying that test coverage is above a certain threshold or that there are no vulnerabilities in your dependencies. Be creative.
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.
I think you might frequently ask questions like these
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.
If you run npm run semantic-release
locally a dry run gets performed, which logs the version that would currently get published.
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>
.
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.
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.
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 on node.js ^0.10
, ^0.12
and io.js ^1
, ^2
. A new version won't get published if it doesn't pass on all these engines.
Note: Currently integration-tests don't run on Travis CI. If you know stuff about npm/Travis/Couch: Please help!
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
.
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=plastic)](https://github.com/semantic-release/semantic-release)
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=flat-square)](https://github.com/semantic-release/semantic-release)
MIT License 2015 © Stephan Bönnemann and contributors
FAQs
Automated semver compliant package publishing
We found that semantic-release demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 4 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
vlt introduced its new package manager and a serverless registry this week, innovating in a space where npm has stagnated.
Security News
Research
The Socket Research Team uncovered a malicious Python package typosquatting the popular 'fabric' SSH library, silently exfiltrating AWS credentials from unsuspecting developers.
Security News
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.