Skip to content
Select theme

Versioning and releases

Every component in the monorepo is versioned and released independently. What gets released, and at what level, is decided by two things: which paths changed, and what your commit messages say.

Understanding this page is the difference between shipping the release you intended and shipping a surprise.

flowchart TB
    START(["Branch merged to main"])
    Q1{"Did files change<br/>under the component's<br/>path?"}
    NONE(["No release.<br/>Markers are ignored."])
    Q2{"Bump marker in any<br/>commit message?"}
    PATCH(["Patch release<br/><i>the default</i>"])
    MARKED(["Release at the<br/>highest marked level"])

    START --> Q1
    Q1 -->|"no"| NONE
    Q1 -->|"yes"| Q2
    Q2 -->|"no"| PATCH
    Q2 -->|"yes"| MARKED

Rule one: no path change, no release. A new tag is created for a component only when files under that component’s path actually changed.

One exception: FEGA-Norway itself is in the release matrix unconditionally, so it gets a release on every merged pull request regardless of which paths changed. The path rule covers the other eight components.

Rule two: patch by default. When a component changes, its patch version increments unless a commit message explicitly asks for something else.

Add a marker to a commit subject line:

#major_componentName
#minor_componentName
#patch_componentName

For example:

implement getVisa() #minor_clearinghouse

This bumps the minor version of clearinghouse. Any other component that changed in the same branch still gets its default patch bump unless separately marked.

A marker naming something that is not a real component fails CI. The recognised names are:

lega-commander · clearinghouse · crypt4gh · tsd-file-api-client · cega-mock · localega-tsd-proxy · mq-interceptor · tsd-api-mock · FEGA-Norway

The check-commit-message workflow validates every marker against this list on pull requests targeting main, and fails on a typo.

Across several commits in one branch:

update encryption #minor_crypt4gh
add new API endpoint #major_clearinghouse

Or within a single commit:

upgrade to Java 25 #major_clearinghouse #major_crypt4gh

Both work. Markers are collected across the whole branch.

If the same component is marked at different levels anywhere in the branch, the highest level wins. This precedence comes from the pinned third-party tagging action rather than from anything in this repository, so it is the action’s documented behaviour rather than a rule the repo enforces itself:

major > minor > patch

So both of these produce a major bump for clearinghouse:

refactor X #minor_clearinghouse #major_clearinghouse
refactor X #minor_clearinghouse
upgrade X #major_clearinghouse

You have two options before merging.

Terminal window
git commit --amend

Edit the message to include the marker, then push:

Terminal window
git push --force-with-lease

Add a commit, if you would rather not rewrite history

Section titled “Add a commit, if you would rather not rewrite history”
add missing marker #minor_clearinghouse

The marker is picked up from any commit in the branch, so a commit that exists only to carry one works fine.

The publish-and-release workflow runs after a pull request is merged into main. For every changed component it publishes the new version, creates a GitHub Release, tags it, and generates a changelog from the Conventional Commit subjects.

Publishing targets differ per artifact, which is easy to get wrong:

Component Published to
crypt4gh, clearinghouse Maven Central, plus the GitHub registry
tsd-file-api-client GitHub Packages only, not Maven Central
Docker images GitHub Container Registry
lega-commander Go binaries on the GitHub Release

Before merge, pre-release-check runs on pull requests to catch a release that would break.

Built from f91944d