@semantic-release/npm
takes care of updating the package.json
’s version before publishing to npm based on the previous version that was tracked as a git tag.
By default, only the published package will contain the version, which is the only place where it is really required, but the updated package.json
will not be pushed to the Git repository.
A git tag is added to track the new version, so committing the version is not necessary for semantic-release to pick up from there for the next release.
Some teams find value in being able to reference the repository to determine the current latest version available for the published package. Unfortunately, there are some failure scenarios where semantic-release might leave the committed version in the repository out of sync with the version that exists in the registry. The best way to determine available versions is to consult the registry that your package is published to, since it is the actual source of truth. The npm CLI can be used to consult the registry with the following command:
npm dist-tags ls <package-name>
When not committing updates to the version, a value that follows the semver guidelines is still required for the version
property within the package.json
.
To make it clear to contributors that the version is not kept up to date, we recommend using a value like 0.0.0-development
or 0.0.0-semantically-released
.
While the @semantic-release/git
enables committing such changes and pushing them back to the repository as part of a release, we strongly recommend against this practice.
Making commits and pushing them back to the repository adds significant additional complexity to your release process that can be avoided:
- Branch protection configuration must account for allowing the release user account to bypass restrictions enforced for human contributors, which might require elevating the access level of the release user beyond what would otherwise be desired/considered secure.
- Pre-commit hooks configured for a project, which is a popular practice when enabling commitlint through husky, for example, must be accounted for in the release process. (We recommend disabling tools like this for automated commits, but you need to decide what is appropriate for your project)
If you make your npm package available directly via a GitHub repository rather than publishing to a registry, for example, making a commit and pushing to the repository is a necessary step.
In such a case you will want to use @semantic-release/git
to coordinate the commit and push.
You can set the project to "private": true,
within your package.json
to prevent publishing to the registry.
However, if you are choosing to follow this path because you can't use the official npm registry and don't want to manage your own registry, consider publishing to GitHub packages instead.
@semantic-release/changelog
can be used to add release notes to a CHANGELOG.md
file within your repository as part of each release.
Committing changes to a CHANGELOG.md
or similar file introduces the same complexities as committing an updated version within a package.json
file.
In addition, the release notes that would be added to a changelog file are likely redundant with the release notes added as GitHub releases, if that is also configured for your project (enabled by default).
Before deciding that a changelog file is necessary for your project, please consider whether the added complexity is worth it when GitHub releases (or similar for your host, if not GitHub) might accomplish the same goal.
It could also be worth considering whether having a CHANGELOG.md
in your repository that only contains a link to the project's GitHub releases could be an acceptable middle ground.
The package.json
’s version will be updated by the semantic-release
command just before publishing to npm, therefore it won't be available for scripts ran before the semantic-release
command.
As the @semantic-release/npm
plugin uses the npm CLI to update the package.json
version and publish the package, all npm hook scripts will be executed.
You can run your build script in:
- the
prepublishOnly
orprepack
hook so it will be executed during thepublish
step of@semantic-release/npm
- the
postversion
hook so it will be executed during theprepare
step of@semantic-release/npm
, which allow for example to update files before committing them with the@semantic-release/git
plugin
If using npm hook scripts is not possible, and alternative solution is to @semantic-release/exec
plugin to run your script in the prepare
step:
{
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/npm",
[
"@semantic-release/exec",
{
"prepareCmd": "./my-build-script.sh ${nextRelease.version}"
}
]
]
}
Yes with the dry-run options which prints to the console the next version to be published and the release notes.
Yes, semantic-release is a Node CLI application, but it can be used to publish any type of packages.
To publish a non-Node package (without a package.json
) you would need to:
- Use a global semantic-release installation
- Set semantic-release options via CLI arguments or
.rc
file - Make sure your CI job executing the
semantic-release
command has access to a version of Node that meets our version requirement to execute thesemantic-release
command
See the CI configuration recipes for more details on specific CI environments.
In addition, you will need to configure the semantic-release plugins to disable the @semantic-release/npm
plugin which is used by default and use a plugin for your project type.
If there is no specific plugin for your project type you can use the @semantic-release/exec
plugin to publish the release with a shell command.
Here is a basic example to create GitHub releases and use a shell command to publish:
{
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/github",
[
"@semantic-release/exec",
{
"prepareCmd": "set-version ${nextRelease.version}",
"publishCmd": "publish-package"
}
]
]
}
Note: This is a theoretical example where the command set-version
update the project version with the value passed as its first argument and publish-package
publishes the package to a registry.
See the package managers and languages recipes for more details on specific project types and the available plugins list to see if there are community-supported plugins already available for the stack you are interested in.
Yes, semantic-release can be used with any CI service, as long as it provides:
- A way to set authentication via environment variables
- A way to guarantee that the
semantic-release
command is executed only after all the tests of all the jobs in the CI build pass
See the CI configuration recipes for more details on specific CI environments.
Yes, you can by explicitly setting the --no-ci
CLI option option. You will also have to set the required authentication via environment variables on your local machine, for example:
$ NPM_TOKEN=<your_npm_token> GH_TOKEN=<your_github_token> npx semantic-release --no-ci
However this is not the recommended approach, as running unit and integration tests on an independent machine before publishing software is a crucial part of the release workflow.
Yes, with the @semantic-release/gitlab-config
shareable configuration.
See the GitLab CI recipes for the CI configuration.
By default semantic-release uses the @semantic-release/github
plugin to publish a GitHub release. For other Git hosted environment the @semantic-release/git
and @semantic-release/changelog
plugins can be used via plugins configuration.
See the @semantic-release/git
@semantic-release/changelog
plugins documentation for more details.
Yes, the publishing to the npm registry can be disabled with the npmPublish
option of the @semantic-release/npm
plugin. In addition the tarballDir
option allow to generate the package tarball in order to publish it to your repository with the @semantic-release/git
or to a GitHub release with the @semantic-release/github
plugin.
See the @semantic-release/npm
plugin documentation for more details.
If you have introduced a breaking bug in a release you have 2 options:
- If you have a fix immediately ready, commit and push it (or merge it via a pull request) to the release branch
- Otherwise, revert the commit that introduced the bug and push the revert commit (or merge it via a pull request) to the release branch
In both cases semantic-release will publish a new release, so your package users will get the fixed/reverted version.
Depending on the package manager you are using, you might be able to un-publish or deprecate a release, in order to prevent users from downloading it by accident. For example, npm allows you to un-publish within 72 hours after release. You may also deprecate a release if you would rather avoid un-publishing.
In any case do not remove the Git tag associated with the buggy version, otherwise semantic-release will later try to republish that version. Publishing a version after un-publishing is not supported by most package managers.
Note: If you are using the default Angular Commit Message Conventions be aware that it uses a different revert commit format than the standard one created by git revert, contrary to what is claimed in the convention. Therefore, if you revert a commit with git revert
, use the --edit
option to format the message according to the Angular revert commit message format. See conventional-changelog/conventional-changelog#348 for more details.
Yes, all the npm configuration options are supported via the .npmrc
file at the root of your repository.
See the @semantic-release/npm
plugin documentation for more details.
The npm access
option can be set in the .npmrc
file at the root of your repository:
access=public
Or with the publishConfig.access
key in your project's package.json
:
{
"publishConfig": {
"access": "public"
}
}
You can trigger a release by pushing to your Git repository. You deliberately cannot trigger a specific version release, because this is the whole point of semantic-release.
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.
By default semantic-release uses the Angular Commit Message Conventions and triggers releases based on the following rules:
Commit | Release type |
---|---|
Commit with breaking change | |
Commit with type feat |
|
Commit with type fix |
Patch release |
Commit with type perf |
Patch release |
See the @semantic-release/npm
plugin documentation for more details.
This is fully customizable with the @semantic-release/commit-analyzer
plugin's release-rules
option.
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
/main
you might not treat your master
/main
branch as intended.
From Understanding the GitHub Flow:
Branching is a core concept in Git, and the entire GitHub Flow is based upon it. There's only one rule: anything in the master/main branch is always deployable.
If you need more control over the timing of releases, see 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? for more details.
This is not supported by semantic-release. Semantic Versioning rules apply differently to major version zero and supporting those differences is out of scope and not one of the goals of the semantic-release project.
If your project is under heavy development, with frequent breaking changes, and is not production ready yet we recommend publishing pre-releases.
See “Introduction to SemVer” - Irina Gebauer for more details on Semantic Versioning and the recommendation to start at version 1.0.0
.
semantic-release has a full unit and integration test suite that tests npm
publishes against the verdaccio.
In addition, the verify conditions step verifies that all necessary conditions for proceeding with a release are met, and a new release will be performed only if all your tests pass.
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 >= 5.2, or can be installed via npm install -g npx
.
For more details and motivation read the introductory blog post by @zkat.