Skip to content

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 ​

  1. Read the release notes of every release between your version and the target.
  2. Check that your version can be upgraded directly (see Supported upgrade paths).
  3. 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.
  4. Run ./deploy/compose/quavon doctor and 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:

sh
git fetch --tags && git checkout <RELEASE_TAG>    # or: git pull
./deploy/compose/quavon install --yes

install 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:

sh
./deploy/compose/quavon status
./deploy/compose/quavon logs init
./deploy/compose/quavon doctor

doctor reports QD205 if migrations are missing (see doctor.md).

Kubernetes (Helm) &ZeroWidthSpace;

sh
helm upgrade codelotse deploy/helm/codelotse -n codelotse -f values.yaml
helm test codelotse -n codelotse
  • The db-init Job runs as a pre-upgrade hook before the new pods start. It has the same role and migration steps as the Compose init service. 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.tag or the digests in your values file.
  • Generated secrets are kept. helm rollback rolls back the workloads but not the migrations; see kubernetes.md.

Migration policy &ZeroWidthSpace;

Migrations are expand/contract, so the previous release keeps working against the migrated schema while pods are replaced:

StepAllowedExample
ExpandAdditive changes in any releaseNew table, new nullable column, new index
ContractDestructive changes only in a migration marked -- quavon:contract, after the code that used the object is goneDROP 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 &ZeroWidthSpace;

MigrationStepShips in
0029_wave16a_posted_comments_scopeExpand: adds the unique key (tenant_id, pull_request_id, external_id) on posted_commentsThe first published release that contains it (release N)
0030_wave16a_posted_comments_contractContract: 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 api and worker run 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 worker before install), 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 doctor on release N does not report 0030 as missing, because release N does not contain the file. After the upgrade to N+1, init applies 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 &ZeroWidthSpace;

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.

ReleaseMigrations at that releaseStatus
phase-3-done (minUpgradableFrom)0000–0015Tested
phase-4-done0000–0018Tested
774731d0000–0025Tested
6049ead0000–0027Tested

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 &ZeroWidthSpace;

  • The check run is now called CodeLotse instead of Quavon review. Branch protection rules or rulesets that require Quavon review block merges until you require CodeLotse instead. 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 CodeLotse and CodeLotse Fixer. You can rename an existing app in its GitHub settings.

If an upgrade fails &ZeroWidthSpace;

SymptomWhat to do
init or db-init exits with an errorRead 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 healthyquavon logs api, quavon logs worker; quavon doctor names configuration problems (QD101).
You need the previous versionCheck 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.

The open core is released under the Apache License 2.0.