Upgrading ​
An upgrade replaces the application images and applies new database migrations. There is no quavon upgrade command: with Compose you re-run the installer from a newer checkout, with Kubernetes you run helm upgrade. Release versions, channels and versions.json are described in releases.md.
Before every upgrade ​
- Read the release notes of every release between your version and the target.
- Check that your version can be upgraded directly (see Supported upgrade paths).
- Take a backup of the database, the secrets and the settings as described in backup.md. A rollback to an older schema is only possible by restoring this backup.
- Run
./deploy/compose/quavon doctorand fix failures first, so new problems are easy to spot afterwards.
Docker Compose ​
Update the checkout to the new release, then re-run the installer:
git fetch --tags && git checkout <RELEASE_TAG> # or: git pull
./deploy/compose/quavon install --yesinstall keeps the secrets and .env, rebuilds the images and starts the stack. The one-shot init service updates the database roles and applies new migrations before api and worker start; if a migration fails, init exits with an error and api and worker are not started with the new version.
After the upgrade:
./deploy/compose/quavon status
./deploy/compose/quavon logs init
./deploy/compose/quavon doctordoctor reports QD205 if migrations are missing (see doctor.md).
Kubernetes (Helm) ​
helm upgrade codelotse deploy/helm/codelotse -n codelotse -f values.yaml
helm test codelotse -n codelotse- The
db-initJob runs as apre-upgradehook before the new pods start. It has the same role and migration steps as the Composeinitservice. If it fails, Helm stops the upgrade and the running pods keep the old version. - Build and push the images of the new release first and update
image.tagor the digests in your values file. - Generated secrets are kept.
helm rollbackrolls back the workloads but not the migrations; see kubernetes.md.
Migration policy ​
Migrations are expand/contract, so the previous release keeps working against the migrated schema while pods are replaced:
| Step | Allowed | Example |
|---|---|---|
| Expand | Additive changes in any release | New table, new nullable column, new index |
| Contract | Destructive changes only in a migration marked -- quavon:contract, after the code that used the object is gone | DROP COLUMN, DROP TABLE, RENAME, column type change |
pnpm verify:migrations enforces this in CI: a destructive statement outside a contract migration fails, and a contract migration may only drop or rename objects that the current schema no longer defines. Applied migrations are checksummed; init refuses to run when an applied migration was changed or is missing. Migrations run under an advisory lock, so two init runs cannot apply them twice.
Because of contract migrations, skipping releases is only supported along the paths below.
Migration 0030 ships one release after 0029 ​
| Migration | Step | Ships in |
|---|---|---|
0029_wave16a_posted_comments_scope | Expand: adds the unique key (tenant_id, pull_request_id, external_id) on posted_comments | The first published release that contains it (release N) |
0030_wave16a_posted_comments_contract | Contract: drops the old unique key (tenant_id, external_id) | Release N+1, one release later |
Releases before N record posted comments with ON CONFLICT (tenant_id, external_id). If 0030 were applied in the same upgrade, pods of the previous release that are still running during the rollover would fail to record comments, because their conflict target no longer exists. Release N already uses the new key, so 0030 is safe once every api and worker pod runs release N.
- Upgrade through release N. Wait until
apiandworkerrun release N everywhere before you upgrade to N+1. - If you cannot upgrade through N, stop the worker of the old release before the upgrade to N+1 (Kubernetes: scale the worker Deployment to 0; Compose:
docker compose -p quavon stop workerbeforeinstall), so no old pod records comments while 0030 is applied. - In release N both keys exist. A tenant with two connections to different servers of GitLab, Gitea, Forgejo or Bitbucket Data Center can still hit the old key when both servers return the same comment id; recording that comment fails until N+1. GitHub comment ids are unique, so GitHub is not affected.
quavon doctoron release N does not report 0030 as missing, because release N does not contain the file. After the upgrade to N+1,initapplies 0030; the runner applies every missing migration in name order, so 0030 runs after the already applied 0031.
How the release is cut is described in releases.md.
Supported upgrade paths ​
Every release listed in tests/upgrade/matrix.json is upgraded directly to the current version by the upgrade suite (pnpm test:upgrade, nightly in CI). For each release the suite installs that release's migrations into a fresh database, seeds representative data, applies the current migrations and checks that only the missing migrations ran, that every seeded row is still readable through the current schema, that row-level security is still forced on every tenant table, that the audit hash chain still verifies, that the old release's writes still succeed against the new schema, and that the new migrations pass the expand/contract lint.
| Release | Migrations at that release | Status |
|---|---|---|
phase-3-done (minUpgradableFrom) | 0000–0015 | Tested |
phase-4-done | 0000–0018 | Tested |
774731d | 0000–0025 | Tested |
6049ead | 0000–0027 | Tested |
Upgrades are supported from minUpgradableFrom to the current release in one step. Installations older than that are not tested.
Upgrading from a release that still used the Quavon name ​
- The check run is now called
CodeLotseinstead ofQuavon review. Branch protection rules or rulesets that requireQuavon reviewblock merges until you requireCodeLotseinstead. Pull requests reviewed before the upgrade keep the old check run. - Review policies saved before the upgrade keep the label
Automated review by Quavon. To use the new label, change Review label in the repository's Policy tab. Policies that were never saved use the new default. - Existing GitHub Apps keep their names. Only apps created from the manifest after the upgrade are called
CodeLotseandCodeLotse Fixer. You can rename an existing app in its GitHub settings.
If an upgrade fails ​
| Symptom | What to do |
|---|---|
init or db-init exits with an error | Read quavon logs init (Compose) or the Job log (Helm). The failed migration was rolled back; fix the cause and run the upgrade again. |
api or worker does not become healthy | quavon logs api, quavon logs worker; quavon doctor names configuration problems (QD101). |
| You need the previous version | Check out the previous tag and restore the backup taken before the upgrade (backup.md). The previous release keeps running against an expanded schema, but only a restore removes migrations and data written by the new release. |