Guide to releasing software at Q-CTRL

Every software release at Q-CTRL requires three important pieces of information:

  1. Version
  2. Title
  3. Description

The information is mandatory and follows specific standards that MUST be followed in order to ensure consistency, quality and usefulness for both internal and external customers.


The version MUST follow the Semantic Versioning standard.


Python package

The title MUST be the project name followed by the version. For example, Q-CTRL Open Controls 2.3.4.

Node package

The title MUST be the JavaScript install name found in package.json followed by the version and joined by an @. For example, @qctrl/react-commons@2.3.4.


The description MUST consist of at least one of the following sections:

  1. Major changes
  2. Minor changes
  3. Patch changes

Please refer to the Semantic Versioning standard for details on the above sections. If there are changes that don’t fit under any section, the “Patch changes” section should describe the changes that call for the release.

NOTE: For the sections, there can be an exception for automated tools that do not follow the capitalization rules in the Q-CTRL Content guidelines, this can be permitted as long as the entire repository uses the same automated tool. For example, tools like changesets capitalize “Changes”.

The sections MUST appear in the above order. If one section is empty, it can be omitted from the description. The contents of each section MUST be an unordered (bulleted) list and MUST adhere to the Q-CTRL Content guidelines. No additional sections are allowed.

Use the template below when describing a release.

Major changes

- Things
- We
- Broke

Minor changes

- Things
- We
- Made

Patch changes

- Things
- We
- Fixed

Methods for generating release notes

The Q-CTRL Release Noter is an actively maintained Python tool which generates release notes according to our current standards. It can be installed using pip with the command pip install qctrl-release-noter.

To use the Q-CTRL Release Noter, use your terminal to navigate to the desired repository and run the command release_noter --github. You can also specify the path of the repository by running release_noter --github /path/to/repository. This will sync changes from remote, generate the release notes, automatically open a browser, and prefill the information on the GitHub release page.


Changesets is an automated versioning and generator tool that follows our standards and is primarily implemented for Node packages. It has a focus on monorepo but supports single package repositories too.

Get started with changesets by following this introduction.

GitHub automatically generated release notes

An alternative method is to use GitHub automatically generated release notes.

Warning: In general, release notes automatically generated by GitHub do not follow our standards above. Specific care must be taken to modify these release notes according to our standards.


Git tags

All release commits MUST be tagged with the matching version.

If more than one package with different new versions has been released from a release commit in a monorepo, the commit MUST have separate tags for each of the package release titles. For example, a Python monorepo has released White Opal Mango 0.1.2 and White Opal Papaya 0.2.1, the commit that released those two packages should have tags with both those release titles.

Monorepo releasing

Each package MUST contain an individual file that contains the latest and historical releases. The MUST be sectioned with the semantic version and each section MUST contain a description in the release description format.

Broken releases through failed CI

On occasion, a release may fail during the on-release CI step. If this occurs, and a package has not been published, delete the failed release and publish a new one with the same release notes and an appropriate PATCH update in the version number according to our Releases standard.

If a package has been published to npm or PyPI as a part of a failed release, the failed package must be deleted manually on the relevant package registry before publishing a new release.


Sometimes a release is necessary because of an updated dependency. For example, the Q-CTRL Python package being released because of an updated version of the Q-CTRL Commons Python package. Although the changes may only occur in the dependency project, the changes affecting the upstream project MUST be captured in the release description of that project.