TurboPanel Docs
Development

How to ship

Shipping TurboPanel is two merges. Each repository does it on its own: a merge on trunk becomes a canary, merging one pull request publishes a release candidate, and merging a second one publishes the release. Nothing is rebuilt along the way — the release candidate and the release are the canary's exact bytes, re-named and re-signed.

This page is for maintainers. The channels themselves are described under Canary environment.

The whole path

StepWhoResult
Squash-merge a change into trunkAnyone with a green ci-okA canary x.y.z-canary.N is built and published
Merge "Release Candidate x.y.z-rc.N" (trunk → staging)A maintainervx.y.z-rc.N is published from that commit's canary; staging moves; "Release x.y.z" opens
Merge "Release x.y.z" (staging → live) and approve the release environmentA maintainervx.y.z becomes the latest release; live moves; the next canary is x.y.z+1 by itself

The pull requests are opened and refreshed by a bot (the TurboPanel Release App), so their checks run. You never run a workflow by hand for a normal release.

1. Publish a release candidate

  1. Open the pull request titled Release Candidate x.y.z-rc.N. The number after rc. is the next one for that version: one more than the highest candidate that already exists.
  2. Wait for ci-ok, then merge it with a merge commit. staging takes merge commits only.
  3. A workflow takes the canary that was built from the merged commit and publishes it as vx.y.z-rc.N — no approval click. The Release x.y.z pull request opens (or refreshes).

If something is wrong with a candidate, fix it on trunk. The next candidate pull request appears after the next green build, and merging it publishes rc.N+1. The version number is never burned: a candidate is replaced, not abandoned.

2. Ship the release

  1. Open Release x.y.z. The list is everything since the last release.
  2. Wait for ci-ok, then merge it with a merge commit. live takes merge commits only.
  3. A workflow takes the newest candidate of that version and publishes it as vx.y.z, marks it the latest release and moves live. It pauses for your approval on the release environment; approve it on the run page. That approval stays until the first release has gone through this exact path end to end; the plan is to drop it afterwards, so that merging Release x.y.z is the only act.

Nothing else opens: the next canary is the next patch by itself.

The installer and the update system follow GitHub's latest release, so the release is what a plain install gets from that moment.

3. The next number

Version numbers come from git tags, not from a file, so no pull request moves them. Once vx.y.z is released, the next canary is x.y.z+1-canary.1, and the canary number starts again at 1 for every new version. The build writes that number into the binary (it reports plain x.y.z); the channel and the canary or candidate number live in the signed manifest.

Repositories ship independently

The daemon (turbopaneld), the control plane (turbopanel), the web app (ui) and the website each have their own version and their own two merges. A daemon-only or a web-app-only release is normal: no release waits on a matching release in another repository. The website ships no binary, so its candidates and releases are notes-only tags on a commit.

Starting a minor or a major

A patch needs nothing. A minor (x.y.0) or a major (x.0.0; the first is 1.0.0) is the one deliberate step: run Start Next Version in the turbopaneld repository (Actions → Start Next Version → Run workflow, pick minor or major). Only people with write access to that repository can run it. Tick dry-run first to see what each repository would get.

This button is the only way to start a minor or a major. There is no label on a pull request that bumps the version, and no "Start x.y.z" pull request to merge.

It pushes a start/vx.y.0 tag at the head of trunk in turbopaneld, turbopanel, ui and the website, each one the next minor (or major) after that repository's own newest release, and re-runs each repository's trunk build. When those builds finish (about 25 minutes for the control plane), the canaries and the Release Candidate pull requests carry the new number. Running it twice is harmless: a repository already on that version is skipped.

After a start, every release of that repository carries the new number, a hotfix included, so start a minor only when everything on trunk may ship as it. A candidate that is already on staging still ships under its own number.

When something goes wrong

What you seeWhat to do
The candidate pull request shows a failed ci-okFix it on trunk; the pull request refreshes on the next green build
The candidate run says it is waiting for a canaryThe merged commit's canary is still building — the run waits up to 45 minutes. If a newer merge superseded it, re-run the Publish Release Candidate workflow (Run workflow, the commit to tag)
The release run is waitingApprove the release environment on the run page
The automatic path cannot run at allUse the Promote workflow in that repository (to=rc with a canary, then to=release with the candidate tag). It is a break-glass form, not the normal path
A candidate was published from the wrong commitMerge the fix and publish the next candidate; a published candidate is not edited

Who needs what

  • Merging to trunk, and to staging and live, is pull request only — squash on trunk, merge commits only on staging and live. The one required check is ci-ok.
  • Tags and the staging / live moves are made by the TurboPanel Release App, not by a person.
  • Approving the release environment is a maintainer action. The first candidate merge needs no approval.
Edit on GitHub

Last updated on

On this page