Release practices

Updating release notes

We use towncrier to maintain the release history. This is where we keep users up to date with new features and breaking changes.

It makes the release manager’s job much easier if most release notes are written by the developers who make the corresponding changes, since they normally know best how to describe them. Therefore, where relevant, merge requests should include a “news fragment” with a brief user-focused description of the change. This is a requirement for backward-incompatible changes, and encouraged for features and bug-fixes. Refactoring, test-only changes, and other things that are not directly visible to users do not generally need news fragments.

File names

News fragments are stored in newsfragments/<section>/<issue>.<type>.rst; a link to the issue will automatically be included in the release notes.

For changes that do not have an associated issue, use newsfragments/<section>/+mr<merge-request>.<type>.rst; this requires creating the merge request first in order to get its ID. (In fact, any first segment starting with + is fine, but the +mr<merge-request> convention helps us to avoid collisions and makes tracking easier.)

News fragment sections

We have the following sections for news fragments, each of which corresponds to a section in the assembled release notes:

  • Server (newsfragments/server/): Backend code on the Debusine server, especially changes to debusine/db/ and debusine/server/. This includes Server, Internal, and Wait tasks.

  • Web UI (newsfragments/web/): The Debusine web user interface, especially changes to debusine/web/.

  • Client (newsfragments/client/): The debusine client, especially changes to debusine/client/.

  • Workflows (newsfragments/workflows/): Workflows, especially changes to debusine/server/workflows/.

  • Tasks (newsfragments/tasks/): Tasks, especially changes to debusine/tasks/, debusine/server/tasks/, and debusine/signing/tasks.

  • Worker (newsfragments/worker/): The Debusine worker, especially changes to debusine/worker/.

  • Signing (newsfragments/signing/): The Debusine signing worker, especially changes to debusine/signing/.

  • General (newsfragments/): Anything that does not fit into the above categories, including significant codebase-wide changes.

News fragment types

We use the following types to categorize news fragments:

  • incompatible: An incompatible change.

  • feature: A new feature.

  • bugfix: A bug fix.

  • doc: A documentation improvement.

  • misc: An issue has been closed, but it is not of interest to users. (This also includes issues about problems with other changes that were introduced since the last release; it doesn’t normally make sense to document these separately.)

Writing style

News fragments should be in the imperative mood (i.e. “Fix something”, not “Fixes something” or “Fixed something”).

They should be complete sentences, ending with a full stop.

They may use reStructuredText features, such as :ref: for cross-references.

Each news fragment should generally be on a single line. towncrier will wrap them as necessary when assembling the release notes. If a single issue needs more than one entry with the same section and type, then put each one on a separate line.

If an issue is relevant to multiple sections or types, it may have multiple news fragments to cover them all.

Examples

If you made a breaking change to a workflow in response to issue #42, then you would put a news fragment in newsfragments/workflows/42.incompatible.rst.

If you made an important bug fix to a server database model in merge request !999 with no associated issue, then you would put a news fragment in newsfragments/server/+mr999.bugfix.rst.

If you added a new feature to the web UI in response to issue #123, then you would put a news fragment in newsfragments/web/123.feature.rst.

Making a release

The release manager follows this procedure to make a new Debusine release.

Select a branch

For simplicity, most releases are made from the devel git branch. However, it may occasionally make sense to release from other branches, such as when Debian is in a freeze period and we need to make targeted fixes. Following DEP-14, such branches should be named <vendor>/<suite> for development releases (e.g. debian/unstable) or <vendor>/<codename> for stable releases (e.g. debian/trixie); they should be created by branching from an appropriate tag.

The work needed to prepare a release will be merged into this branch, and the release tag will end up in that branch’s history.

Finalize release notes

Look through the changes since the last release (e.g. using tig --first-parent <previous-tag>..), checking for changes that should have been documented but were not. Add news fragments for these.

Run towncrier build --version <new-version> to assemble a first draft of the new release notes, then run make -C docs clean html and check the results in a web browser. Edit the result as needed to improve readability: for example, it may make sense to consolidate items that relate to the same overall topic, or to make minor formatting adjustments.

Add a debian/changelog entry for the new release, briefly highlighting the most significant changes.

File a merge request with all these changes, targeted to the branch selected above, and ask for review.

Release to Debian

Once your merge request with updated release notes has been approved, merge it into the appropriate branch. (Be careful to check for other changes that have been merged since you filed the merge request, since you may need to add release notes for them; it’s best to merge release notes branches as promptly as possible to avoid this extra work.)

In most cases, you can now run git debpush (you will need the git-debpush package). This will push a signed tag causing the tag2upload service to make an upload to Debian.

If the upload will require going through the NEW queue (either due to a new binary package, or because this is the first upload to the -backports suite for a new Debian release), you will instead need to make an upload including binaries. To do this, run dgit sbuild to build the package, dgit push-built to upload it, and push the resulting git branch and tag.

git debpush or dgit push-built will create a signed debian/<version> tag. For convenience (such as making it easy to browse changes interactively, or to make it a little easier for people to install the Debusine client directly from git), we also create a <version> tag without the debian/ prefix. Do this manually using git tag after making the release to Debian, and push it.

If you did not make the release from devel or from a backports branch, then you should normally merge it into devel now so that version numbers of automatically-built packages from devel remain higher than those in Debian unstable.

Follow up

Over the next few days, check the tracker to make sure that your release has built and passed tests everywhere and (if relevant) that it will migrate to testing. If this is not the case, you may need to make follow-up releases to fix any problems. It is a good idea to subscribe to the debusine package via the tracker so that you are notified of build failures, testing migration, and bug reports.

For releases to unstable, once they have migrated to testing, we normally also prepare a stable backport. These are maintained in the debian/<codename>-backports git branch, but they do not have independent release notes, other than a brief “Rebuild for <codename>-backports” note in debian/changelog. To prepare these, use git merge locally to merge the release tag into the backports branch, run dch --bpo or similar to update the changelog, and upload the result using git debpush or dgit as above.