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.
The two rules
Section titled “The two rules”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.
Marker syntax
Section titled “Marker syntax”Add a marker to a commit subject line:
#major_componentName#minor_componentName#patch_componentNameFor example:
implement getVisa() #minor_clearinghouseThis bumps the minor version of clearinghouse. Any other component that changed in the
same branch still gets its default patch bump unless separately marked.
Valid component names
Section titled “Valid component names”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.
Multiple components
Section titled “Multiple components”Across several commits in one branch:
update encryption #minor_crypt4ghadd new API endpoint #major_clearinghouseOr within a single commit:
upgrade to Java 25 #major_clearinghouse #major_crypt4ghBoth work. Markers are collected across the whole branch.
Conflicting markers
Section titled “Conflicting markers”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_clearinghouserefactor X #minor_clearinghouseupgrade X #major_clearinghouseForgot a marker?
Section titled “Forgot a marker?”You have two options before merging.
Amend, if it was your most recent commit
Section titled “Amend, if it was your most recent commit”git commit --amendEdit the message to include the marker, then push:
git push --force-with-leaseAdd 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_clearinghouseThe marker is picked up from any commit in the branch, so a commit that exists only to carry one works fine.
What actually happens on merge
Section titled “What actually happens on merge”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