Files
govoplan/docs/operations/FULL_REGISTRY_CANDIDATES.md
T

139 lines
8.1 KiB
Markdown

# Full registry candidates / Vollständige Registry-Kandidaten
## Operator workflow (EN)
The canonical `release-catalog.py full-registry` command takes `--package-set`,
`--package-lock`, `--wheelhouse`, `--webui-packages`, `--output-dir`, and a
configured `--catalog-signing-key`. Generate the package set with
`generate-release-package-set.py --profile full` and download its exact artifacts
with `resolve-package-artifacts.py`; do not substitute locally rebuilt wheels.
The candidate compares the package set with the exact developer meta-package
pins, checks archive bytes and package metadata against the lock, and synthesizes
every entry from its immutable tagged manifest. Native package publication and
its CI authority remain trusted: this verifies the published artifact identity,
not independent reproducible-build equivalence to source.
Pass `--selected-repository` once for each newly released repository, including
Core when it changes. These selected units must have clean, version-aligned
named branches whose HEAD equals the annotated local and remote release tag.
Other full-profile packages retain their exact older annotated tags; a later
workflow-only commit on `main` does not relabel those package contents or force
a version bump. Every source fetch/push endpoint must match the registered
origin, and all entries bind their source commit and annotated tag object.
Git replacement objects, caller Git configuration, and executable-path
redirection cannot substitute another tagged manifest tree.
The fixed existing website catalog and keyring are authenticated before signing.
An older catalog without a signed keyring hash can be migrated only through this
complete rebuild, only when its signature verifies and its entire keyring
exactly matches the configured known signers. No old entries or artifact hashes
are reused. The new catalog signs the exact unchanged website keyring hash;
key rotation remains a separate reviewed operation. Selective candidates still
reject unpinned base keyrings. New candidate directories are private and
exclusive: a retry must choose a new directory, not overwrite a reviewed one.
Run these commands on the trusted host, with an operator-private source workspace
and artifact directory. `RELEASE_PYTHON` must select its private environment and
`RELEASE_NPM` an absolute npm executable with a trusted sibling Node 22 binary.
In Flatpak, execute host commands through `flatpak-spawn --host`; sandbox and
host UID mappings are not interchangeable. Do not weaken trust gates or change
system-wide permissions.
```sh
# These paths identify previously prepared private operator resources.
RELEASE_WORKSPACE=/path/to/private/workspace
RELEASE_PYTHON="$RELEASE_WORKSPACE/govoplan/.host-venv/bin/python"
RELEASE_NPM=/path/to/private/node22/bin/npm
ARTIFACT_ROOT=/path/to/private/artifacts
RELEASE_CANDIDATE=/path/to/private/new-candidate
RELEASE_VERSION=0.1.45
RELEASE_TOOLS="$RELEASE_WORKSPACE/govoplan/tools/release"
umask 077
"$RELEASE_PYTHON" "$RELEASE_TOOLS/generate-release-package-set.py" \
--version "$RELEASE_VERSION" --profile full \
--workspace "$RELEASE_WORKSPACE" --output "$ARTIFACT_ROOT/packages.json"
PATH="$(dirname "$RELEASE_NPM"):/usr/bin:/bin" \
"$RELEASE_PYTHON" "$RELEASE_TOOLS/resolve-package-artifacts.py" \
--package-set "$ARTIFACT_ROOT/packages.json" \
--wheelhouse "$ARTIFACT_ROOT/wheels" \
--webui-packages "$ARTIFACT_ROOT/webui" \
--lock-output "$ARTIFACT_ROOT/artifacts.lock.json" \
--python "$RELEASE_PYTHON" --npm "$RELEASE_NPM"
# Repeat --selected-repository for EVERY newly released unit, not just Core.
"$RELEASE_PYTHON" "$RELEASE_TOOLS/release-catalog.py" full-registry \
--workspace-root "$RELEASE_WORKSPACE" \
--package-set "$ARTIFACT_ROOT/packages.json" \
--package-lock "$ARTIFACT_ROOT/artifacts.lock.json" \
--wheelhouse "$ARTIFACT_ROOT/wheels" --webui-packages "$ARTIFACT_ROOT/webui" \
--output-dir "$RELEASE_CANDIDATE" --selected-repository govoplan-core \
--catalog-signing-key known-key=/path/to/private/known-key.pem --json
"$RELEASE_PYTHON" "$RELEASE_TOOLS/release-catalog.py" publish-candidate \
--workspace-root "$RELEASE_WORKSPACE" --candidate-dir "$RELEASE_CANDIDATE" \
--channel stable --npm "$RELEASE_NPM" --build-web \
--commit --tag --push --tag-name "catalog-v$RELEASE_VERSION" --json
```
The last command is a strict non-mutating preview because `--apply` is absent.
Review its output, then repeat it with `--apply` to publish. The website's locked
build dependencies must already be installed before `--build-web`. The publisher
sanitizes the build and Git environments and pushes the verified immutable
website commit/tag. Source tag publication and registry package availability
must be complete before candidate generation.
Source tags, registry packages, and a signed module catalog do not imply that a
new runtime distribution exists. While runtime images are held, leave the Meta
Gitea runtime Release held too: a normal source-only Release can replace Gitea's
`releases/latest` discovery result despite having no deployment assets. The
deployer still requires an explicit signed manifest, digest, and trusted
keyring; it does not deploy a tag or module catalog directly.
## Betriebsablauf (DE)
`release-catalog.py full-registry` übernimmt den vollständigen Paketbestand,
die Registry-Sperrdatei, das Wheel-Verzeichnis, die WebUI-Archive und den
konfigurierten Signaturschlüssel. Zuerst mit
`generate-release-package-set.py --profile full` die exakten Meta-Paketversionen
ermitteln und mit `resolve-package-artifacts.py` die veröffentlichten Artefakte
herunterladen. Lokal neu gebaute Wheels sind kein Ersatz. Der Kandidat prüft
Paketidentitäten, Dateigrößen und Hashes und erzeugt alle Einträge aus den
unveränderlichen getaggten Manifesten. Die Registry und ihre veröffentlichende
CI bleiben eine Vertrauensgrundlage; dies ist kein unabhängiger Nachweis eines
reproduzierbaren Builds aus dem Quellcode.
Jedes neu veröffentlichte Repository wird mit `--selected-repository`
angegeben. Nur diese Auswahl muss mit dem sauberen, versionsgleichen HEAD eines
benannten Branches und dem annotierten lokalen und entfernten Tag übereinstimmen.
Unveränderte Pakete behalten ihren ursprünglichen Tag, auch wenn auf `main`
bereits eine spätere Workflow-Korrektur liegt. Alle Quelladressen müssen dem
registrierten Ursprung entsprechen; Commit und annotiertes Tag-Objekt werden
für jeden Eintrag gebunden. Git-Ersetzungsobjekte oder fremde Git-Konfiguration
können dabei keinen anderen Manifestbaum unterschieben.
Vor dem Signieren werden der bestehende Website-Katalog und sein Schlüsselbund
geprüft. Ein alter Katalog ohne signierten Schlüsselbund-Hash darf ausschließlich
durch diesen vollständigen Neuaufbau migriert werden: Seine Signatur muss gültig
sein und der gesamte Schlüsselbund exakt den konfigurierten bekannten Signierern
entsprechen. Alte Einträge oder Artefakt-Hashes werden nicht übernommen. Der neue
Katalog bindet den unveränderten Schlüsselbund-Hash; ein Schlüsselwechsel bleibt
ein eigener geprüfter Vorgang. Selektive Kandidaten verlangen weiterhin einen
bereits gebundenen Schlüsselbund. Kandidaten werden nur in neuen privaten
Verzeichnissen erzeugt und niemals überschrieben.
Das obige Befehlsbeispiel wird auf dem vertrauenswürdigen Host ausgeführt. Dafür
die private Python-Umgebung und einen absoluten `--npm`-Pfad zu Node 22 verwenden;
unter Flatpak die Host-Werkzeuge über `flatpak-spawn --host` aufrufen. Die
gesperrten Website-Build-Abhängigkeiten vorher installieren. Keine
Vertrauensprüfung umgehen und keine globalen Rechte ändern. Die Artefaktordner
müssen privat und bei der Auflösung leer sein. Vor der Kandidatenerzeugung
müssen Quell-Tags und Registry-Pakete vollständig veröffentlicht sein.
Die Veröffentlichung zunächst mit `publish-candidate --commit --tag --push
--build-web` ohne `--apply` prüfen und erst nach Prüfung mit `--apply` ausführen.
Solange Laufzeit-Images zurückgestellt sind, bleibt auch das Meta-Gitea-Runtime-
Release zurückgestellt: Ein reines Quellcode-Release könnte sonst als neuestes
Release erscheinen. Eine Installation benötigt weiterhin ein signiertes
Laufzeitmanifest, dessen Digest und einen explizit vertrauenswürdigen Schlüsselbund.