Releasing frontend modules
Releasing frontend modules is a critical part of the development process. After meeting a reasonable threshold of commits, or after a set amount of time, you will likely want to publish your software to the npm registry so that consumers can install it. This guide will walk you through the process of releasing frontend modules in the O3 ecosystem.
O3 currently follows a release cadence of monthly or every other month. This means we aim to publish new versions of our frontend to our QA environment on a roughly monthly or bi-monthly cycle. QA review and feedback typically takes a week, after which we promote the release to our demo Production environment . This cadence is subject to change as we get more experience with the process.
Cutting a release
Please read through the Important notes section at the end of this page for guidance on some oft-overlooked steps in the release process.
Cutting an O3 release normally has two publishing stages:
- Open and merge a release PR that bumps local package versions. The merge to
maintriggers the CIpre_releasejob, or the equivalent branch of the shared release workflow, and publishes a pre-release build taggednext. - Create a release using the GitHub Releases UI. The
releaseevent triggers CI to publish the package(s) to npm with thelatesttag.
If you want to publish a release version of your module, you need to think about a few things first, including:
-
The release
type- the semantic versioning release type your changes conform to. Our release versions use the SemVer spec, meaning we have three release types:patch- when you make backwards-compatible bug fixes.minor- when you add functionality in a backwards-compatible manner.major- when you make incompatible API changes.
For example, if the most recently released version number for a frontend module is
v1.0.0:- A
patchversion would increment the version number to1.0.1. - A
minorversion would increment the version number to1.1.0. - A
majorversion would increment the version number to2.0.0.
Drafting a changelog
With that knowledge, you can draft a changelog. To do so:
- Go to the
releasespage of your monorepo, and clickDraft a new release. - Click the
Choose a tagbutton in the releases page UI. Choose any tag, sayv1.0.1for apatchrelease if the most recent version isv1.0.0. We will likely change this shortly after reviewing the changelog. Set that value as the release title as well. Next, click theGenerate release notesbutton.
We have established a convention within O3 where PR titles use one of these canonical formats:
(type) TICKET: Sentence case summary(type) Sentence case summary(BREAKING) TICKET: Sentence case summary(BREAKING) Sentence case summary
Allowed parenthesized type values are (feat), (fix), (chore), (docs), (test), and (BREAKING). Keep avoiding (refactor), and allow ticketless PR titles when a Jira ticket does not exist yet. Bot-authored PRs are exempt from this check.
Reviewing the generated changelog with these title rules in mind should give you a good idea of the semantic version bump your release should create. For the full PR title policy and examples of valid and invalid titles, refer to the contributing guide.
Bumping versions
At this point, check whether the repo has a .github/workflows/open-release-pr.yml workflow. Many current frontend module repos provide an Open release PR GitHub Action with a release_type input (patch, minor, or major). Prefer that workflow when it exists: it runs the repo’s release command, verifies the release diff, and opens a PR with the release bump. If the repo does not have that workflow, or if you are doing the bump manually, use the repo’s yarn release scripts as described below.
Monorepos
For monorepos, we use the workspaces command to bump versions across all packages in the monorepo. You’ll typically find a release script in the root-level package.json file of the monorepo that looks like this:
"release": "yarn workspaces foreach --all --topological version"This script runs the version command against all the packages in the workspace. You’ll need to append the release type to this command to trigger a version bump. So, for a major release, you would run:
yarn release majorThis command:
- Runs the
versioncommand against all the packages in the workspace and bumps them to a major version. For example, if the current version is1.0.0, it would get bumped to2.0.0. - Tells yarn to sort the packages before running the commands so that they run on the packages in topological order (i.e., packages that depend on other packages get run later).
- If you need to avoid versioning the root
package.json, add an explicit--excludefor the root package name.
Non-monorepos
For non-monorepos, you can use the version command directly. For example, to bump the package version to a major release, run:
yarn version majorLibraries using legacy versions of yarn
Some of our projects use legacy versions of yarn (yarn v1). The Angular form engine is an example of such a project. To release the Angular form engine, you would run the following command:
yarn version --new-version <major|minor|patch> --no-git-tag-versionBe sure to follow the instructions listed in the Cutting a release docs to avoid getting caught out.
Post-bump steps
Once you’re done versioning, you should see a diff in your editor that includes a version bump for all the packages in your repository. Run yarn or yarn install to update your yarn.lock file.
If the repo’s Open release PR workflow created the branch and commit for you, review that PR and continue from there. If you are doing the bump manually, create a release branch using the repo’s convention, commonly release/vX.X.X or chore/release-vX.X.X, where X.X.X is the version number you are releasing. Commit the bump with a title such as (chore) Release vX.X.X. See an example of this commit that bumps Patient Chart to v5.0.0.
Once your release commit is merged into main, CI publishes a pre-release version tagged next on npm. This is useful for early testing before you publish latest. The exact script name is repo-specific: openmrs-esm-core uses ci:publish-next, many frontend module repos use ci:prepublish, and some repos pass the command into the shared release-frontend-module workflow.
Releasing on GitHub
You can then switch to your browser and head back to the releases page of the repo you are working with. Review the release notes generated by GitHub and then update the version number and tags appropriately.
Release notes should match the format of the O3 changelog. This format includes a title, a
description, and a list of changes. The main categories of changes are Features, Bug Fixes, Breaking Changes,
Chores, Docs, and Tests. Each category should have a list of changes under it. You might need to do a bit more
work to get the changelog to match this format. It’s worth the effort, as it makes it easier for the Release Manager
to review the changes and prepare release notes for the community.
Once you are satisfied that everything looks OK, click the Publish release button. This step should trigger the CI workflow and, notably, the release job.
For many monorepos, that job runs a publish script similar to this:
"ci:publish": "yarn workspaces foreach --all --topological --exclude @openmrs/esm-patient-management npm publish --access public --tag latest"Single-package repos may instead call yarn npm publish --access public directly, and monorepos often exclude the root workspace from publishing. The important invariant is the npm dist-tag: pre-release automation publishes next, while a GitHub release publishes latest.
The latest tag is the version consumers get by default when they install your frontend module.
To see what version the latest tag corresponds to for a frontend module, go to its npm registry page and click on the version tag. Look out for the most recent version tagged latest.
Important notes
- When versioning the Angular form engine , ensure you bump both the version in the root-level
package.jsonfile and the version in thepackage.jsonfile in theprojects/openmrs-esm-formentrydirectory. The actual library is published from that directory, so it’s important to bump the version there as well. More information can be found in this section of the README. - When versioning the Patient Chart , ensure you bump the Common Lib peer dependency in each of the packages that depend on it. Here’s an example of a release commit that bumps both the package version and the peer dependency version: chore: Release v7.0.0 .
Repo-specific differences
Not every repo wires releases the same way. Before releasing, check:
package.jsonforrelease,ci:publish,ci:publish-next, orci:prepublishscripts..github/workflows/open-release-pr.ymlfor an automated release-bump PR workflow..github/workflows/ci.yml,.github/workflows/node.js.yml, or a shared workflow reference to see which tags are published onpushvsrelease.
Always follow the scripts defined in that repo, even if names differ from this guide.