- Trigger the Version workflow specifying the
version-bump
. This will create a new pull request with the changes done by Lernaversion
. - Merge the previous pull request. It will generate a new draft release.
- Publish the draft release (press the edit icon of the newly created draft release in here)
- See your packages get published to NPM 😌
This repository uses Lerna as a tool to handle monorepos. Lerna provides the commands version
and publish
, which under normal circumstances should be sufficient for versioning and publishing packages in a monorepo. In brief, the version
command increments the versions of the monorepo packages, generates a git tag, and pushes the modified files (lerna.json
, package.json
of the packages, changelog files, etc.) and the git tag. The publish
command publishes the packages to the corresponding registry.
As mentioned in Lerna's documentation for the allow-branch
option, it is advisable not to run the version
command on a branch other than main
. We agree that allowing versioning on branches can be error-prone. However, in this repository, pushes to main
are restricted. We also wanted to avoid using personal access tokens. This first limitation has led us to opt for an alternative and secure way to increment the version of the packages.
Furthermore, even though Lerna can generate versions based on commit messages following the conventional commits specification, we have chosen a somewhat more manual but safer approach, at least in our opinion.
Continuing in this line, another limitation of Lerna (at least with our current knowledge of the tool) is that, even though it can generate git tags, it does not allow generating releases on GitHub automatically and synchronized with the package publishing in the corresponding registry.
Due to the reasons mentioned earlier, we have decided to structure the release process in three separate workflows:
- Version: This workflow is triggered with a
workflow_dispatch
trigger, where you need to specify theversion-bump
using a choice input. The options correspond to the positional argumentbump
of Lerna'sversion
command. Key steps in this workflow include:- Increasing the version of packages using Lerna's
version
. The--no-push
option prevents Lerna from pushing the changes, and--no-git-tag-version
prevents Lerna generating a git tag. Both actions are delegated to subsequent steps and/or workflows. - Creating a pull request using the create-pull-request action. The generated branch follows the format
releases/bump-version-v*.*.*
, where*.*.*
is the version generated by Lerna according to theversion-bump
input.
- Increasing the version of packages using Lerna's
- Release: This workflow is triggered when a pull request on a branch whose name follows the format
'releases/'
is merged. Effectively, this means that this workflow is triggered when the pull request generated during theVersion
workflow is merged. Using the release-drafter action, a draft release (and a tag) is generated on GitHub with the version determined during theVersion
workflow. - Publish: This workflow is triggered when a tag with the format
v*.*.*
is pushed. Effectively, this workflow is activated when the release generated in the previous step is published. This workflow uses Lerna'spublish
command with thefrom-package
option. We have experienced some undesired behaviour using thefrom-git
option, resulting in no new versions detected during the publication step.
A significant portion of this workflow has been inspired by the lerna-ci-cd-example repository by Austin Fahls (@fashlaj) and the very informative (though a bit long 🙏) video Using Github Actions to Publish your Packages by Austin and Zachary DeRose (@ZackDeRose). Huge thanks to both.
We recommend you to visit these links. And if their work has also been helpful to you, don't forget to acknowledge their efforts. 😉