A predictable versioning strategy for a monorepo using semver

release-managementsemantic-versioningversioning

To simplify deployment and project management tasks I maintain a monorepo containing several packages that each have a semver version. To be clear, I don't mean several repositories managed from one place, I mean a single Git repository that tracks several packages with a common toolchain. Note that this does NOT imply that this is the only repository maintained by my team. I just manage the one in question for a specific delivery pipeline.

The monorepo itself is hard to version with semver because a major version bump in a package might not justify a major version bump in the monorepo itself. Take a GUI moving from v2.9.3 to v3.0.0 on the grounds that it uses a new design system that other packages don't use yet. That's arguably not a breaking change in the monorepo, since:

  • The monorepo change would probably just amount to a dependency addition.
  • There's no reason to alarm the team with a major version bump for the monorepo that distracts from the more relevant change in the package.

The relationship between version changes in the monorepo and packages are, in general, difficult to automate unless highly-specific or brittle assumptions are taken as objective.

Note that I am assuming that two version bumps must happen simultaneously because if the monorepo does not have its own version and related tags, then that messes up the git describe output that we use company wide.

What strategy would you apply in my position?


Let me clarify some details given what I've read from other users. Assume that there are several tactics at play around the company to manage revisions. There's a monorepo with semver, but there's another repo using git submodules and yet another using cross-stack deployment tools. Given my position I have to assume that suggestions to normalize on one option are, unfortunately, non-actionable right now. The act of splitting up or combining repositories is a breaking change with a ripple effect. This should help you understand why I am restricting the question to use of semver on a repository; it's the least expensive change in context.

Best Answer

Perhaps a more manageable solution is a Changelog.

If your publishing components anyway, there should be a changelog. I'm not talking about checkin comments. I'm talking about a version controlled file describing important changes in the software.

Have the file as prepend only. Add major changes with some symbol say asterisk, and minor changes with say a plus sign. The list is terminated by a page break of hyphens eg: "-----"

Have a release job inspect the log up to the "----". Based on what it finds and the previous version number generate a new semver. Major bumps if a major change is in the log. Minor bumps if a minor version is in the log, otherwise bump the patch number. If the release is developmental, add some incremental build number on (commit number after that if desired). If the release is a complete release, then the job injects the final version number into the changelog and prepends a new empty section.

The release job can be run automatically (after tests) or manually depending on what works for the team.

Extra points if the release job fails due to an incorrectly edited changelog.

Related Topic