Skip to main content
Version: 0.1 (next)

Cut a release

A Product ships through deployments and is announced through releases. This page is about the second: what a release is, what cutting one does, and how to cut one from the UI or with ir.

A release and a deployment​

A deployment (the Release resource) is one build of a Product moving through its zones: built, tagged, promoted zone by zone through a pull request each, checked, held under the release guard, rolled back if it fails. A merged Change starts one on its own, and New deployment starts one by hand. Deployments are how code reaches production, and there can be many of them in a day.

A release is what people read. It gathers every deployment that reached production since the last release under one version, tags the commit and the image running in production with that version, and publishes two write-ups: release notes for engineers and a post for everyone else. The ReleaseCut resource; its phase is Pending, Tagging, Publishing, Released or Failed. An org-admin cuts one when the Product has something worth telling.

DeploymentRelease
What it isOne build moving through the zonesThe deployments in production since the last release, under one version
Started byA merged Change, or a personA person who cuts it
VersionThe next patch: v1.6.1, v1.6.2The next minor or major: v1.7.0, v2.0.0
TagsA git tag on the commitA git tag on the commit, and the image's digest tagged with the version
On the forgeNothingA GitHub release on the tag, with the notes, marked latest
release.cutNot sentSent once, so the release AgentWorkflow runs once per release
PhasesPending, Building, Tagged, Promoting, AwaitingApproval, Released, FailedPending, Tagging, Publishing, Released, Failed

Version numbers​

A deployment bumps only the patch, counting from the newer of the last deployment's version and the last release's. After release v1.6.0, the next deployment is v1.6.1, then v1.6.2. The first deployment of a Product with no tag at all is v0.1.0. Pre-release tracks (-rc.N) are unchanged.

A release takes the next minor or major of the version running in production. The draft suggests major when a deployment since the last release holds a breaking change and the Product is at 1.0 or later, and minor otherwise. The choice is yours when you cut. A release is never a patch.

What cutting does​

Cutting a release of zippy at v1.7.0, with zippy-7kq2m running in production:

  1. Tags the commit. The git tag v1.7.0 lands on the commit the production deployment shipped. Nothing is built: the release is exactly what runs.
  2. Tags the image. The image digest running in production gets the tag v1.7.0 in the Product's registry, beside the tag its deployment gave it.
  3. Creates the GitHub release. On the tag, with the release notes as its body, marked latest. Deployments make no GitHub release, so a Product's GitHub releases are its releases and nothing else.
  4. Sends release.cut once. Every enabled AgentWorkflow with a release.cut trigger starts one run, with the release's version and notes. The release AgentWorkflow, which announces, runs once per release, not once per deployment.

Each step is done once: a cut that fails partway, for instance because the forge did not answer, resumes from the step that failed, and never repeats a tag it made.

A cut covers the deployments that reached production Healthy after the last release, in the order they got there; the one in production now is the newest of them. With no release yet, it covers every deployment in production since the Product's last GitHub release, or all of them when it has none. A cut with nothing new is refused, and so is a second cut while one is still Tagging or Publishing.

Who may cut​

An org-admin, or a platform admin. Members see the Releases tab, the draft and every release, and can read the notes and the post, but Cut a release is not theirs. A cut records who made it, as Infrared names people, never by an email address.

The nudge​

A Product's Releases tab says when there is enough in production to be worth a release: at least one feature, or one breaking change, or ten fixes since the last release. It counts the commits the deployments shipped by their conventional commit subjects: feat is a feature, fix a fix, a ! or a BREAKING CHANGE footer a breaking change, and anything else is other. The nudge is a suggestion; you can cut a release with one fix in it, or let twenty features wait.

Cut a release in the UI​

Open the Product and its Releases tab.

  1. In production, not in a release yet lists the deployments a cut would cover, oldest first, each with its version, when it reached production, who asked for it, how its release guard ended, and the commits it shipped by kind. Above it, the nudge and its counts.
  2. Cut a release opens the drawer. It proposes the version, minor or major, and says why in a sentence ("12 changes since v1.6.0, none breaking"). Switch to the other if you disagree.
  3. The title is <product> <version> unless you change it.
  4. The notes are drafted for engineers, in Markdown: Breaking changes, Features, Fixes and Other, a section only when it has items, each item its title, pull request, issue and who asked for it, and which deployment shipped it. A footer names the covered deployments. Edit them as you like.
  5. The post is drafted for everyone else: a few plain lines, a breaking change first, then each feature in a short paragraph, then "and N fixes". Edit it too. Nothing in either draft is written by an agent.
  6. Cut release v1.7.0 cuts it. The drawer closes and the release appears on the tab, Tagging, then Publishing, then Released, with a message at each step and the reason if it fails.

The tab lists the releases so far, newest first: version, title, who cut it and when, how many deployments and commits it covers, and the GitHub release once it exists.

The release's page and its post​

A release has a page, /releases/<product>/<version>, and the org's releases are listed at Releases in the rail. The page shows the version, the title, who cut it and when, the commit and the image it tagged, the GitHub release, the notes as published, every change by kind, and the deployments it covers with their changes. The post has a page of its own, /releases/<product>/<version>/post, which reads as it was written, without the engineering detail, for anyone in the org to read or to pass on.

The deployments it covers keep their own pages under Deployments. An old link to /releases/<deployment> opens the deployment.

With ir​

ir release cut --product zippy
ir release cut --product zippy --major --title "zippy v2.0.0" --notes-file notes.md --post-file post.md
ir release cuts --product zippy
ir release cut get zippy-1-7-0
CommandWhat it does
ir release cut --product <p> [--major] [--title <t>] [--notes-file <f>] [--post-file <f>]Cut a release of the Product at the next minor, or the next major with --major. The title, notes and post are the draft's unless you pass your own
ir release cuts [--product <p>]The org's releases, newest first, or one Product's
ir release cut get <name>One release: its tags, the GitHub release, the notes and the post, and the deployments it covers

ir release new and ir release promote start and promote a deployment, as before. They are not a release.

With the API​

OperationWhat it does
GET /v1/orgs/{org}/products/{product}/releasecut-draft?bump=minor|majorThe draft: what is in production and not in a release yet, the versions to choose from, the nudge, the title, the notes and the post. Members and up
POST /v1/orgs/{org}/releasecutsCut a release: product, bump (minor or major), and optionally title, notes and post, the draft's where empty. 201 with the release; 403 below org-admin; 409 when there is nothing new or a cut is in progress; 422 on a bad bump
GET /v1/orgs/{org}/releasecuts?product=<p>The org's releases, newest first
GET /v1/orgs/{org}/releasecuts/{name}One release, with its notes, its post, every change by kind and the deployments it covers

A release is named <product>-<major>-<minor>-<patch>: zippy-1-7-0.