Releasing frontend modules
Releasing a frontend module means publishing a new version to the npm registry so consumers can install it. O3 frontend modules are released with a one-click GitHub Actions workflow that bumps the version, tags it, publishes to npm, and creates a GitHub Release with release notes.
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.
How releases are published
There are two kinds of builds on npm:
- Pre-releases (
nexttag). Every merge tomainpublishes a pre-release automatically, with a version like12.3.5-pre.1234. Use these for early testing. You don’t need to do anything to get them. - Releases (
latesttag). These are cut on demand with the Release workflow described below.latestis the version consumers get by default when they install a module.
Creating a release through the GitHub Releases UI no longer publishes anything to npm. Always use the Release workflow in the Actions tab. It creates the GitHub Release for you.
Cutting a release
1. Choose the release type
Our versions follow semantic versioning , so pick the type that matches the changes since the last release:
patchfor backwards-compatible bug fixes (1.0.0→1.0.1)minorfor new backwards-compatible functionality (1.0.0→1.1.0)majorfor incompatible API changes (1.0.0→2.0.0)
PR titles tell you which one to pick. O3 PR titles use one of these formats:
(type) TICKET: Sentence case summary(type) Sentence case summary(BREAKING) TICKET: Sentence case summary(BREAKING) Sentence case summary
Allowed type values are (feat), (fix), (chore), (docs), (test), and (BREAKING). Avoid (refactor). Ticketless titles are fine when no Jira ticket exists yet, and bot-authored PRs are exempt. Any (BREAKING) PR since the last release means a major release; any (feat) means at least minor. For the full policy and examples, see the contributing guide.
To see what has merged since the last release, compare the latest release tag with main on GitHub, or check the commit history on main.
2. Run the Release workflow
- Go to the repo’s Actions tab and select the OpenMRS CI workflow.
- Click Run workflow and keep Use workflow from set to
main. - Choose the Version bump (
patch,minor, ormajor). - Leave Custom version empty unless you need a specific version, such as
13.0.0. When set, it overrides the version bump. - Leave Publish only unchecked. It is only for recovering a failed release (see If a release fails).
- Click Run workflow.
You need write access to the repo to run the workflow.

3. What the workflow does
The workflow:
- Bumps the version of every package in the repo (all workspaces in a monorepo).
- Commits the bump to
mainas(chore) Release vX.Y.Zand tags itvX.Y.Z. - Builds the packages from the release commit.
- Pushes the commit and tag.
- Publishes the packages to npm with the
latesttag. - Creates a GitHub Release for
vX.Y.Zwith release notes generated from the PRs merged since the previous release.
It also refuses to run when something looks wrong:
- Releases can only be cut from
main. - It won’t release a version that is already tagged, or one that isn’t higher than the current version.
- The commit and tag are pushed before anything goes to npm, so a failed run can never leave a published version without a matching tag.
The run summary shows the version change and, if anything fails, exactly what was and wasn’t done.
4. Review the release
Once the run finishes, check the new release on the repo’s Releases page and the package’s npm page. To confirm what latest points to, open the package on npm and look at the Versions tab.
The generated notes come from PR titles, which is another reason to keep titles in the format above. You can edit the GitHub Release afterwards if the notes need cleaning up. They should read like the O3 changelog, grouped into Features, Bug Fixes, Breaking Changes, Chores, Docs, and Tests, which makes it easier for the Release Manager to prepare release notes for the community.
If a release fails
Open the failed run and read its summary. It tells you whether the tag was pushed and which packages, if any, reached npm, along with what to do next. The common cases:
- Failed before the push. Nothing left the runner, so the version is still free. Fix the problem and run the workflow again normally.
- Tag pushed, nothing on npm. This usually means an expired npm token or a registry outage. Fix the cause, then run the workflow again with Publish only checked and Custom version set to the version that was tagged (for example
12.4.0). It builds and publishes the existing tag without bumping or tagging again. - Some packages published, others not. npm versions can’t be republished or reused, so don’t delete the tag and don’t release the same version again. Follow the recovery steps in the run summary.
Repo-specific notes
- Most repos need no configuration: the workflow infers the build and publish commands from
package.json. If a repo definesci:publish, that script is used to publish. - For the Angular form engine repos (openmrs-ngx-formentry, openmrs-ngx-file-uploader, and esm-form-entry-app in openmrs-esm-patient-chart), confirm before releasing that the Angular line they ship is still in support per the Angular version support policy.