For AI agents: the complete documentation index is available at /llms.txt, the full documentation bundle is available at /llms-full.txt, and this page is available as Markdown at /reference/docs/platform-releases.md.

Verified platform releases

Decision 0056 separates official release publication from personal development and production activation.

Shared sources

gitops/manifests/images.yaml defines every image's Dockerfile, context, target, arguments and fingerprint inputs. Both in-cluster builds and the reusable CI workflow read it. Add an image there, with its owner manifest; no handwritten CI matrix is required. Existing optional development publication retains its image lock artefacts and adds complete evidence for official packaging.

Shared release code lives in devops/platform/scripts/platform_release: plan.py reads that catalogue, package.py produces deterministic OCI payloads, promotion.py selects a package through Git and health.py waits for Argo's exact-release notifications. Workstation takeover and browser tooling stay in DX.

Commands

Changelog preparation

Before tagging a platform release, create a release-preparation PR from current main. Pending notes live in changelog fragments. Preview them with the intended tag and release date:

pnpm changelog:preview --version platform-v1.2.3 --date 2026-11-04

Preview leaves files and the Git index unchanged. Commit any edits to the fragments, changelog or Towncrier configuration before assembling:

pnpm changelog:build --version platform-v1.2.3 --date 2026-11-04

The pinned Towncrier dependency inserts the new release above earlier history, stages CHANGELOG.md and removes and stages the consumed fragments. Review the staged diff, commit it and merge the release-preparation PR. Tag its merge commit once that commit's main-push CI succeeds. An existing version is rejected even if a different date is supplied.

Assemble once per release. Feature PRs continue to add unique fragments while release preparation is reviewed; notes merged after preparation remain pending for the next release. The tag workflow retains its existing generated GitHub release notes and performs no changelog commits.

Release and deployment commands

These commands run from a clean checkout of the selected source:

make release-plan VERSION=platform-v1.2.3 SOURCE=<40-character-commit>
make release VERSION=platform-v1.2.3 SOURCE=<40-character-commit>
make release-status VERSION=platform-v1.2.3

The first command is read-only. release checks that HEAD matches SOURCE and is on main's history, refuses an existing remote tag, then creates and pushes an annotated tag. It applies the same forward-only check before creating the tag. Configure protected release tags and the workflow's package permissions before using it. Release tags are forward-only and must be greater than every earlier tag reachable from main. Never move a published tag. The workflow repeats the policy check and waits for successful main-push CI for the exact source before building and publishing.

Every catalogue image participates, including administration and identity images. The catalogue at the audited main commit 32cea6102 contained fourteen images; the workflow always reads gitops/manifests/images.yaml, so no documentation or CI matrix carries a second count. Their credentials remain runtime private inputs, never build arguments. The workflow verifies signatures and complete source-matched evidence before publishing ghcr.io/pharos-ai-factory/pharos-platform/release:<version>. Consumers resolve that name once and use its digest.

One built archive supplies both publication channels. The workflow pushes the exact release.tar.gz to OCI and uploads the same bytes to the GitHub Release, together with the extracted release.json, SHA256SUMS and a Sigstore blob bundle. It never rebuilds the bytes between channels. The archive contains only committed GitOps files plus release.json; it excludes workstation files and private runner state. Archive reading is bounded and never extracts untrusted paths.

The repository tag ruleset must protect refs/tags/platform-v*, refs/tags/hpc-site-v* and refs/tags/dx-v*, as well as the legacy v* rule. Ruleset administration is an external repository-owner action; a workflow cannot enforce it.

The HPC Site archive follows the same reviewed tag path:

make hpc-release-plan VERSION=hpc-site-v1.2.3
make hpc-release VERSION=hpc-site-v1.2.3 SOURCE=<40-character-commit>

hpc-release refuses a source outside main, an existing remote tag or a version not greater than every earlier hpc-site-v* tag reachable from main. The tag workflow then builds, verifies and signs pharos-hpc-site-v1.2.3.tar.gz and publishes it with its checksum and Sigstore bundle. A tag can be created only after the reviewed installer source is on main; this release-management PR itself does not publish or activate an HPC Site release.

After activation, the ordinary interface selects an existing release:

make deploy ENV=production RELEASE=platform-v1.2.3
make rollback ENV=production RELEASE=platform-v1.2.2

These commands require oras, cosign, authenticated GHCR access and GH_TOKEN with the intended selection-branch permission. Set PHAROS_RELEASE_STATUS_CREATOR_ID to the dedicated notification App bot's numeric user ID. CI uses the corresponding RELEASE_STATUS_CREATOR_ID repository variable. Selection validates these inputs before changing Git, verifies package/image signatures and waits for all selected Applications to report exact-release health from that App. Another CI status or an older deployment attempt cannot satisfy it. No cluster credential is required.

Rollback requires unchanged contract/migration fingerprints. One conservative fingerprint covers all packaged compositions: committed contracts, every PostgreSQL context's manifest and SQL from the migration catalogue, service delivery migrations and retained Themelio migrations. Catalogue owners and checksums are validated against the selected Git commit; untracked files cannot contribute. SQLite and storage-free contexts need no PostgreSQL manifest. Rollback does not undo database migrations or restore data. A removed Application or unknown selection branch file requires an explicit reviewed transition rather than ordinary promotion.

Production remains disabled

devops/platform/environments/production.yml declares release.enabled: false. Tags can publish artefacts; the production selection job remains skipped. No production overlay or external-identity integration is fabricated by this change.

Before enabling selection, the deferred identity/application composition must add the reviewed production Application overlay and pass real environment qualification. Bootstrap must configure Argo OCI repository access and permit that exact source in each existing owner AppProject. A root Application follows the engineering repository's deploy/production branch at path apps; child Applications use the verified OCI package. Fence earlier writers before adopting existing services.

Install the dedicated notification App and triggers matching the selected child's pharos.platform/deployment-context and pharos.platform/source annotations. Success requires Synced, Healthy, a successful operation and both observed sync revisions equal to spec.source.targetRevision. Failure must identify that same revision. Bootstrap credentials and public origin/AAI client bindings stay outside the release package. Package publication alone does not establish a working site.

Verification

scripts/test_platform_release.py exercises real Git fixtures, Kustomize rendering and archive bytes, complete image evidence, tamper/path rejection, disabled targets, non-forced selection and notification identity/attempt fencing. pnpm verify includes these checks. Live GHCR publication, signature identity, Argo OCI rendering, notification delivery, browser/UAT and production rollout require separate evidence.

Page source

Source snapshot ยท Revision f928834c8.