Prepare GovOPlaN self-hosted release workflow
This commit is contained in:
@@ -107,6 +107,15 @@ cd /mnt/DATA/git/govoplan-core
|
||||
scripts/push-release-tag.sh --version 0.1.6
|
||||
```
|
||||
|
||||
`scripts/generate-release-catalog.py` reads installed/discovered
|
||||
`ModuleManifest` objects while writing catalog entries. When a manifest is
|
||||
available, the catalog entry uses the manifest version, points package refs at
|
||||
`v<manifest.version>`, and copies `provides_interfaces` /
|
||||
`requires_interfaces` from the manifest. If a manifest cannot be discovered,
|
||||
the entry falls back to the release version passed with `--version` and omits
|
||||
interface metadata. This keeps the catalog aligned with independently
|
||||
versioned module packages instead of relying on a hardcoded compatibility table.
|
||||
|
||||
The script also includes GovOPlaN roadmap/scaffold module repositories that do
|
||||
not yet have package metadata. Those repositories are committed, tagged, and
|
||||
pushed with the same release tag, but they are tag-only until they contain
|
||||
@@ -196,10 +205,109 @@ Each module entry can declare:
|
||||
- WebUI package name and pinned install reference
|
||||
- display metadata and tags
|
||||
- `license_features`, the feature entitlements required to plan that install
|
||||
- `provides_interfaces`, named interface contracts exported by this module
|
||||
- `requires_interfaces`, named interface contracts and version ranges required
|
||||
by this module
|
||||
|
||||
The signature is Ed25519 over canonical JSON with both `signature` and
|
||||
`signatures` removed. Core accepts the legacy single `signature` field and the
|
||||
new `signatures` array.
|
||||
When `APP_ENV` is `prod` or `production`, module package catalog signature
|
||||
verification is required by default unless
|
||||
`GOVOPLAN_MODULE_PACKAGE_CATALOG_REQUIRE_SIGNATURE=false` is set explicitly.
|
||||
|
||||
### Independent Module Versions And Interface Ranges
|
||||
|
||||
Modules do not need to ship on the same version number. Release catalogs should
|
||||
pin each package to the exact backend/WebUI ref being installed and declare any
|
||||
cross-module API compatibility through named interfaces.
|
||||
|
||||
Provider shape:
|
||||
|
||||
```json
|
||||
"provides_interfaces": [
|
||||
{ "name": "files.campaign_attachments", "version": "1.4.0" }
|
||||
]
|
||||
```
|
||||
|
||||
Requirement shape:
|
||||
|
||||
```json
|
||||
"requires_interfaces": [
|
||||
{
|
||||
"name": "files.campaign_attachments",
|
||||
"version_min": "1.0.0",
|
||||
"version_max_exclusive": "2.0.0"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
`version_min` is inclusive. `version_max_exclusive` is exclusive, so the range
|
||||
above means `>= 1.0.0` and `< 2.0.0`. Use this for SemVer major-version
|
||||
compatibility lines. Set `"optional": true` only when the module can operate
|
||||
without that interface being present. If a provider is installed but its
|
||||
version is outside the declared optional range, activation is still blocked.
|
||||
|
||||
Catalog validation normalizes these fields and warns when catalog entries do
|
||||
not satisfy each other's ranges. Registry activation and installer preflight
|
||||
perform the blocking checks against the discovered installed manifests before
|
||||
the desired module set is activated.
|
||||
The admin module-management UI shows catalog warnings in the package catalog
|
||||
section and repeats them as warning-level installer preflight issues while a
|
||||
package install is planned.
|
||||
|
||||
Install-plan items carry a `source` field. Manually entered items use
|
||||
`source: "manual"`; entries planned from the package catalog use
|
||||
`source: "catalog"`. Catalog-sourced items also carry a `catalog` metadata
|
||||
object with the validation snapshot used when the item was planned: catalog
|
||||
source/path, source type, cache path, channel, sequence, generated/validity
|
||||
timestamps, signature state, trusted key id, and cache state where available.
|
||||
Catalog provenance changes preflight severity:
|
||||
|
||||
- catalog-sourced installs require a configured, valid package catalog before
|
||||
activation
|
||||
- invalid, untrusted, expired, not-yet-valid, replayed, or unapproved-channel
|
||||
catalogs block catalog-sourced installs
|
||||
- the same catalog validation failures remain warnings for manual install
|
||||
plans, so operators can still use offline or emergency package refs
|
||||
- valid-catalog warnings, such as intentionally unsigned local catalogs when
|
||||
signature enforcement is disabled, remain warnings
|
||||
- selected catalog entries with unsatisfied non-optional named interface ranges
|
||||
block activation before the installer runs
|
||||
|
||||
### Update Paths
|
||||
|
||||
Package updates are target-state operations, not one-module-at-a-time runtime
|
||||
toggles. The safe unit of planning is a desired module version set plus a
|
||||
catalog validation snapshot. The installer may install multiple packages into
|
||||
the environment before activation, then validate the discovered manifests and
|
||||
activate the resulting set together.
|
||||
|
||||
This avoids circular "upgrade A first / upgrade B first" traps: named interface
|
||||
requirements are solved against the target set, not against each intermediate
|
||||
package-install moment. If the target set cannot satisfy all non-optional
|
||||
interfaces and module dependencies at once, the plan is invalid. Operators
|
||||
should add the necessary module updates to the same plan instead of trying to
|
||||
force an order.
|
||||
|
||||
Live data upgrades need an even stricter rule:
|
||||
|
||||
- migrations must be idempotent and ordered by module migration metadata
|
||||
- destructive schema/data changes need an explicit retirement or cleanup plan,
|
||||
not an automatic package update side effect
|
||||
- cross-module data migrations must be compatible with both the old and target
|
||||
provider interface until activation finishes
|
||||
- rollback must restore the package set and database state together, or be
|
||||
documented as forward-only with a tested recovery procedure
|
||||
- if two modules require mutually incompatible live-data states, the catalog
|
||||
must publish an intermediate compatibility release rather than a circular
|
||||
update chain
|
||||
|
||||
In practice, circular dependencies are avoided by designing interfaces with
|
||||
compatibility windows and by publishing bridge releases. A bridge release keeps
|
||||
the old interface while introducing the new one, allowing dependent modules to
|
||||
move first; a later release can retire the old interface after every dependent
|
||||
module has a compatible target version.
|
||||
|
||||
Trusted catalog keys are configured locally:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user