Upgrade checks

Open Forms has upgrade checks built-in to prevent inconsistent database states. This consists of a couple of components, given that:

  1. You are currently on version X and

  2. you are trying to upgrade to version Y

Then, the check will:

  1. Validate that upgrading from version X to version Y is a supported upgrade path.

  2. Run specified check management commands - if any command raises CommandError, the upgrade is blocked

  3. Run specified check scripts from the bin folder

Check configuration

The upgrade paths are specified in openforms.conf.base.UPGRADE_CHECK_PATHS. It uses the underlying django-upgrade-check library.

For every target version (=version to upgrade to), you can specify:

  • the supported version ranges to upgrade from

  • code checks that need to pass (optional), such as:

    • management commands through upgrade_check.CommandCheck

    • custom scripts in the bin folder that need to pass through openforms.upgrades.script_checks.BinScriptCheck.

Custom scripts

Custom scripts must implement a main callable, taking the skip_setup boolean (keyword) argument. If the function returns False or raises an exception, then the upgrade is blocked.

How does it work?

The version ranges are specified in semantic version format, and thus primarly target official releases.

Note

Non-official releases are possible in the form of custom image builds, or even development/nightly builds that don’t have an explicit version number.

  1. When a release is created, it is assigned an explicit version number (see also: Versioning policy) in semantic version format, e.g.:

    1.0.0, 2.0.0-beta.1

  2. The CI pipeline bakes this version number into the container image in the RELEASE environment variable (and the VCS commit hash is baked into GIT_SHA, accordingly)

  3. The container start script (bin/docker_start.sh) runs migrations as part of the initialization, through the migrate management command.

  4. Django runs the system checks before executing the migrations. django-upgrade-check hooks into this mechanism. It compares the current version with the version being deployed (from the baked-in version information) and runs the relevant checks.

  5. If upgrading is not possible, an error is emitted and the migrate command does not execute - your database is thus left untouched. Because of the error exit code, the container will also not start. All information to correct this situation is available in the container logs.

  6. If upgrading is possible, migrations are executed and at the end the version registered in the database is automatically updated with the value of RELEASE.

  7. This cycle repeats for the next upgrade.

If your upgrade is blocked, you should be able to safely deploy the old version again, make the necessary changes to resolve the problems preventing the upgrade, and then try again.

Developers and people deploying latest (don’t do this unless you’re willing to debug breaking changes!) usually receive warnings instead of errors, so their usual flow is not broken.