This recipe will walk you through a simple example that uses distribution channels to make releases available only to a subset of users, in order to collect feedback before distributing the release to all users.
This example uses the semantic-release default configuration:
- branches:
['+([0-9])?(.{+([0-9]),x}).x', 'master', 'next', 'next-major', {name: 'beta', prerelease: true}, {name: 'alpha', prerelease: true}]
- plugins:
['@semantic-release/commit-analyzer', '@semantic-release/release-notes-generator', '@semantic-release/npm', '@semantic-release/github']
We'll start by making the first commit of the project, with the code for the initial release and the message feat: initial commit
to master
. When pushing that commit, semantic-release will release the version 1.0.0
and make it available on the default distribution channel which is the dist-tag @latest
for npm.
The Git history of the repository is:
* feat: initial commit # => v1.0.0 on @latest
We can now continue to commit changes and release updates to our users. For example we can commit a bug fix with the message fix: a fix
to master
. When pushing that commit, semantic-release will release the version 1.0.1
on the dist-tag @latest
.
The Git history of the repository is now:
* feat: initial commit # => v1.0.0 on @latest
* fix: a fix # => v1.0.1 on @latest
We now want to develop an important feature, which is a breaking change. Considering the scope of this feature we want to make it available, at first, only to our most dedicated users in order to get feedback. Once we get that feedback we can make improvements and ultimately make the new feature available to all users.
To implement that workflow we can create the branch next
and commit our feature to this branch. When pushing that commit, semantic-release will release the version 2.0.0
on the dist-tag @next
. That means only the users installing our module with npm install example-module@next
will receive the version 2.0.0
. Other users installing with npm install example-module
will still receive the version 1.0.1
.
The Git history of the repository is now:
* feat: initial commit # => v1.0.0 on @latest
* fix: a fix # => v1.0.1 on @latest
| \
| * feat: a big feature \n\n BREAKING CHANGE: it breaks something # => v2.0.0 on @next
One of our users starts to use the new 2.0.0
release and reports a bug. We develop a bug fix and commit it to the next
branch with the message fix: fix something on the big feature
. When pushing that commit, semantic-release will release the version 2.0.1
on the dist-tag @next
.
The Git history of the repository is now:
* feat: initial commit # => v1.0.0 on @latest
* fix: a fix # => v1.0.1 on @latest
| \
| * feat: a big feature \n\n BREAKING CHANGE: it breaks something # => v2.0.0 on @next
| * fix: fix something on the big feature # => v2.0.1 on @next
We now want to develop a smaller, non-breaking feature. Its scope is small enough that we don't need to have a phase of feedback and we can release it to all users right away.
If we were to commit that feature on next
only a subset of users would get it, and we would need to wait for the end of our feedback period in order to make both the big and the small feature available to all users.
Instead, we develop that small feature commit it to master
with the message feat: a small feature
. When pushing that commit, semantic-release will release the version 1.1.0
on the dist-tag @latest
so all users can benefit from it right away.
The Git history of the repository is now:
* feat: initial commit # => v1.0.0 on @latest
* fix: a fix # => v1.0.1 on @latest
| \
| * feat: a big feature \n\n BREAKING CHANGE: it breaks something # => v2.0.0 on @next
| * fix: fix something on the big feature # => v2.0.1 on @next
* | feat: a small feature # => v1.1.0 on @latest
Most of our users now have access to the small feature, but we still need to make it available to our users using the @next
dist-tag. To do so we need to merge our changes made on master
(the commit feat: a small feature
) into next
. As master
and next
branches have diverged, this merge might require to resolve conflicts.
Once the conflicts are resolved and the merge commit is pushed to next
, semantic-release will release the version 2.1.0
on the dist-tag @next
which contains both our small and big feature.
The Git history of the repository is now:
* feat: initial commit # => v1.0.0 on @latest
* fix: a fix # => v1.0.1 on @latest
| \
| * feat: a big feature \n\n BREAKING CHANGE: it breaks something # => v2.0.0 on @next
| * fix: fix something on the big feature # => v2.0.1 on @next
* | feat: a small feature # => v1.1.0 on @latest
| * Merge branch master into next # => v2.1.0 on @next
After a period of feedback from our users using the @next
dist-tag we feel confident to make our big feature available to all users. To do so we merge the next
branch into master
. There should be no conflict as next
is strictly ahead of master
.
Once the merge commit is pushed to master
, semantic-release will add the version 2.1.0
to the dist-tag @latest
so all users will receive it when installing out module with npm install example-module
.
The Git history of the repository is now:
* feat: initial commit # => v1.0.0 on @latest
* fix: a fix # => v1.0.1 on @latest
| \
| * feat: a big feature \n\n BREAKING CHANGE: it breaks something # => v2.0.0 on @next
| * fix: fix something on the big feature # => v2.0.1 on @next
* | feat: a small feature # => v1.1.0 on @latest
| * Merge branch master into next # => v2.1.0 on @next
| /|
* | Merge branch next into master # => v2.1.0 on @latest
We can now continue to push new fixes and features on master
, or a new breaking change on next
as we did before.