Skip to Content
DocsFrontend modulesReleasing modules

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:

  1. Open and merge a release PR that bumps local package versions. The merge to main triggers the CI pre_release job, or the equivalent branch of the shared release workflow, and publishes a pre-release build tagged next.
  2. Create a release using the GitHub Releases UI. The release event triggers CI to publish the package(s) to npm with the latest tag.

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 patch version would increment the version number to 1.0.1.
    • A minor version would increment the version number to 1.1.0.
    • A major version would increment the version number to 2.0.0.

Drafting a changelog

With that knowledge, you can draft a changelog. To do so:

  • Go to the releases page of your monorepo, and click Draft a new release.
  • Click the Choose a tag button in the releases page UI. Choose any tag, say v1.0.1 for a patch release if the most recent version is v1.0.0. We will likely change this shortly after reviewing the changelog. Set that value as the release title as well. Next, click the Generate release notes button.

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 major

This command:

  • Runs the version command against all the packages in the workspace and bumps them to a major version. For example, if the current version is 1.0.0, it would get bumped to 2.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 --exclude for 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 major

Libraries 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-version

Be 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.json file and the version in the package.json file in the projects/openmrs-esm-formentry directory. 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.json for release, ci:publish, ci:publish-next, or ci:prepublish scripts.
  • .github/workflows/open-release-pr.yml for 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 on push vs release.

Always follow the scripts defined in that repo, even if names differ from this guide.

Last updated on