# Upgrades and versions

> How self-hosted MergeHarbor is versioned, how to upgrade and roll back with Helm or Docker Compose, and which versions are supported.

## Versions

Releases use semantic versioning: `vMAJOR.MINOR.PATCH`.

- Images are tagged `X.Y.Z` and `X.Y`, signed with Sigstore cosign, and published with an SBOM.
- The Helm chart is versioned with the release.
- Each release has an [air-gap bundle](https://mergeharbor.com/docs/self-hosting-air-gapped).
- **Patch releases** contain fixes only and are safe to apply at any time.
- **Minor releases** add features. They may add database migrations, and they never need manual data steps.
- **Major releases** may remove settings. Their release notes list every required change.

## Supported versions

MergeHarbor supports the **latest two minor releases**: security fixes and bug fixes ship as patch releases for both. Upgrade at least once every six months to stay on a supported release. You can skip minor versions within a major version, for example from 1.2 to 1.4 directly. Across a major version, upgrade to the latest minor release of your current major version first.

## How migrations run

Database migrations run automatically, before any new code starts.

- **Helm:** a pre-upgrade Job applies them once, then the new pods start. Pods wait until the schema they need is in place.
- **Compose:** `upgrade.sh` runs the `migrate` service before it starts the new containers.

Migrations take short locks and retry, so reviews keep running on the old version while a migration is applied. Schema changes follow expand-and-contract: a column or table is removed only in a release after the code stopped using it. The previous release therefore keeps working on the new schema, which is what makes a rollback possible.

## Upgrade with Helm

1. Read the release notes.
2. Back up the database (a snapshot of your managed PostgreSQL).
3. Upgrade:

   ```sh
   helm upgrade mergeharbor oci://ghcr.io/mergeharbor/charts/mergeharbor --version <new> \
     -n mergeharbor -f values.yaml
   kubectl -n mergeharbor rollout status deploy/mergeharbor-api
   ```

4. Check **Settings → System status** in the console.

**Air-gapped:** load the new bundle into your registry first, then upgrade from the bundle's chart package.

**Roll back:**

```sh
helm rollback mergeharbor -n mergeharbor
```

The previous release runs on the migrated schema. If a release note says a migration cannot be rolled back, restore the database snapshot from step 2 instead.

## Upgrade with Docker Compose

```sh
./upgrade.sh 1.5.0            # or: ./upgrade.sh 1.5.0 --offline, after loading the new bundle
```

`upgrade.sh` does the following:

1. Backs up the database and configuration to `backups/` (tagged `pre-1.5.0`).
2. Pulls the new images.
3. Runs the migrations.
4. Starts the new version and checks that the API is healthy.

If the pull or the migrations fail, it keeps the old version. To roll back afterwards:

```sh
./upgrade.sh 1.4.0
```

To restore the database from before the upgrade, run `./backup.sh restore backups/<pre-1.5.0 file>.dump`.

## License renewals

License renewals are not upgrades: replace the license file, and it applies within a minute. See [Self-hosted licensing](https://mergeharbor.com/docs/self-hosting-licensing).
