Files
govoplan-core/docs/RELEASE_CATALOG_WORKFLOW.md
2026-07-07 16:00:38 +02:00

4.0 KiB

Release Catalog Workflow

GovOPlaN release catalogs are published by govoplan-web as static JSON and verified by govoplan-core before installer plans are accepted.

Private signing keys must stay outside all git repositories. Public keyrings are published with the website.

One-Time Key Setup

Create the first catalog signing key on the release machine:

cd /mnt/DATA/git/govoplan-core
KEY_DIR="$HOME/.config/govoplan/release-keys"
mkdir -p "$KEY_DIR"
./.venv/bin/python scripts/generate-catalog-keypair.py \
  --key-id release-key-1 \
  --private-key "$KEY_DIR/release-key-1.pem" \
  --public-key "$KEY_DIR/release-key-1.pub" \
  --keyring "$KEY_DIR/catalog-keyring.json"

Keep release-key-1.pem private. The generated keyring contains only public material.

Publish Current Release Catalog

Generate the signed catalog into govoplan-web:

cd /mnt/DATA/git/govoplan-core
KEY_DIR="$HOME/.config/govoplan/release-keys"
scripts/publish-release-catalog.sh \
  --version 0.1.4 \
  --sequence 202607071340 \
  --catalog-signing-key "release-key-1=$KEY_DIR/release-key-1.pem" \
  --build-web

This writes:

  • /mnt/DATA/git/govoplan-web/public/catalogs/v1/channels/stable.json
  • /mnt/DATA/git/govoplan-web/public/catalogs/v1/keyring.json

The wrapper validates the catalog with core using the generated public keyring.

Publish After A New Release

For normal module/core releases, first tag and push the module/core repos. Then publish the website catalog:

cd /mnt/DATA/git/govoplan-core
KEY_DIR="$HOME/.config/govoplan/release-keys"
scripts/publish-release-catalog.sh \
  --version <x.y.z> \
  --catalog-signing-key "release-key-1=$KEY_DIR/release-key-1.pem" \
  --build-web \
  --commit \
  --tag \
  --push

The website tag is catalog-v<x.y.z>. The public URL is:

https://govoplan.add-ideas.de/catalogs/v1/channels/stable.json

The public keyring URL is:

https://govoplan.add-ideas.de/catalogs/v1/keyring.json

Integrated Release Script

scripts/push-release-tag.sh can publish the web catalog after module and core tags have been pushed:

cd /mnt/DATA/git/govoplan-core
KEY_DIR="$HOME/.config/govoplan/release-keys"
scripts/push-release-tag.sh \
  --bump subversion \
  --publish-web-catalog \
  --catalog-signing-key "release-key-1=$KEY_DIR/release-key-1.pem" \
  --build-web-catalog

Use --catalog-signing-key more than once during a key rotation window. The catalog will contain multiple signatures and the public keyring will include the corresponding public keys.

Consumer Configuration

On a GovOPlaN installation that should consume the official stable catalog:

GOVOPLAN_MODULE_PACKAGE_CATALOG_URL=https://govoplan.add-ideas.de/catalogs/v1/channels/stable.json
GOVOPLAN_MODULE_PACKAGE_CATALOG_CACHE=/srv/govoplan/runtime/catalog-cache/stable.json
GOVOPLAN_MODULE_PACKAGE_CATALOG_REQUIRE_SIGNATURE=true
GOVOPLAN_MODULE_PACKAGE_CATALOG_APPROVED_CHANNELS=stable
GOVOPLAN_MODULE_PACKAGE_CATALOG_TRUSTED_KEYS_FILE=/srv/govoplan/trust/catalog-keyring.json
GOVOPLAN_MODULE_PACKAGE_CATALOG_SEQUENCE_STATE=/srv/govoplan/runtime/catalog-sequences.json
GOVOPLAN_MODULE_PACKAGE_CATALOG_ENFORCE_SEQUENCE=true

For production, copy the public keyring into deployment configuration and pin it locally. Do not rely on a URL-fetched keyring as the only trust root.

Core Updates

stable.json includes a top-level core_release section for operator/update tooling. Core is intentionally not listed as a normal module entry, because it must not be added to saved enabled-module state. Core upgrades should remain an operator-supervised package update with restart and health checks.

Key Rotation

  1. Generate the next private key outside git.
  2. Run publish-release-catalog.sh with both signing keys.
  3. Publish the web catalog/keyring.
  4. Roll the new public keyring into installations.
  5. Stop signing with the old key after the supported fleet trusts the new key.
  6. Mark compromised keys as revoked in the public keyring and publish a higher sequence catalog signed by a trusted uncompromised key.