Lerna monorepos with fewer tags

Getting the perks of monorepo publishing while curating our git tags and release notes.
For the Visual Framework, a front-end component library, we're developing its 112 npm packages as a monorepo using the tool Lerna.
Lerna works out of the box quite well, allowing us to manage all of our components in a single project and easily publishing them to npm. However, the default did two things we didn't like:
- Each release created a new tag per updated component and we were on our way to 1,000s of tags in our project.
- Release notes were not easy to curate and using Conventional Commits didn't suit our workflow.
What we want#
- make one tag for each overall
lerna publish
release - use git to harvest the changes in each
CHANGELOG.md
to generate release notes as an "update" on the website
How we get it#
Generate the release notes#
We run the aliased command yarn run releasenotes
that invokes a git dump:
git show -U0 --raw $(git describe --abbrev=0 --tags $(git rev-list --tags --skip=1 --max-count=1))..$(git describe --abbrev=0 --tags $(git rev-list --tags --max-count=1)) --pretty=format:'commit: %H %n abbreviated_commit: %h %n subject: %s %n sanitized_subject_line: %f %n date : %aD %n commiter : %cN %n' --output=tools/vf-component-library/src/site/updates/$(date +%F)-component-updates.md -- **/CHANGELOG.md
I'll walk through that chunk of code:
- Show the raw git history:
git show -U0 --raw
- Since the most recent tag:
$(git describe --abbrev=0 --tags $(git rev-list --tags --skip=1 --max-count=1))..$(git describe --abbrev=0 --tags $(git rev-list --tags --max-count=1))
- In this format:
--pretty=format:'commit: %H %n abbreviated_commit: %h %n subject: %s %n sanitized_subject_line: %f %n date : %aD %n commiter : %cN %n'
- Add a new post file to the
updates
directory:
--output=tools/vf-component-library/src/site/updates/$(date +%F)-component-updates.md
- Add the diff from any
CHANGELOG.md
changes:
-- **/CHANGELOG.md
That still leaves us to add on the frontmatter and massage the content, but with the help of a macro it's a pretty quick task:
{% macro notes(component='vf-xxx', componentVersion='9.9.9', commitId='0123456789') %}
### [{{component}}](https://visual-framework.github.io/vf-core/components/{{component}}/)
- <span class="kh-badge">{{ componentVersion }}</span>
- <a href="https://www.npmjs.com/package/@visual-framework/{{component}}/v/{{componentVersion}}" class="kh-badge">npm</a>
- <a href="https://github.com/visual-framework/vf-core/commit/{{commitId}}" class="kh-badge">git diff</a>
{% endmacro %}
Here's an example release notes update and its 11ty source code.
Make a reference git tag for Lerna#
- Run Lerna publish and skip git tags:
lerna publish --no-git-tag-version --no-push
- Lerna publishes to npm and does cross-dependency updates to each component's
package.json
. - Commit the
package.json
updates to our main git branch - Create a manual tag
git tag -a v2.3.whatever -m 'Combined snapshot of packages'
- Push our new tag
git push origin --tags
Now running lerna changed
shows the expected "No changed packages".
It works well for us#
To be clear, we don't think there is anything "wrong" with Lerna's default publishing flow, however it didn't suit our needs. This is an alternative approach.