Skip to content

feat[auto-upgrade]: Ship trust deployment assets as versioned artifacts instead of a git checkout - #1752

Open
garciadias wants to merge 1 commit into
developfrom
1646-oci-chart
Open

garciadias wants to merge 1 commit into
developfrom
1646-oci-chart

Conversation

@garciadias

Copy link
Copy Markdown
Collaborator

What

Publishes the trust Helm chart to GHCR as a versioned OCI artifact on every release.

Closes #1646 (OCI half — see "Deliberately not here" below).

Why

A Kubernetes trust currently has no versioned deployment artifact. Chart.yaml has sat at version: 0.1.0 / appVersion: "1.0" since it was written, and the chart is only ever installed from a working checkout. So "upgrade this trust to v0.13.0" has nothing to name.

#1644's in-cluster upgrade CronJob is the forcing function: it runs as a namespace-scoped service account inside the cluster. It cannot clone the repo and run make. It can only pull a chart.

How

trust/deploy/helm/scripts/package_chart.py stamps three fields from the release tag, then packages and pushes:

Field Becomes
Chart.yaml version 0.13.0
Chart.yaml appVersion v0.13.0
values.yaml global.image.tag v0.13.0

That third one is why this stays small: global.image.tag is already the single pin for every FLIP-built image (FLIP#1204), so flip-trust:0.13.0 deploys v0.13.0's images and nothing else. No per-service stamping.

The stamping lives in a script rather than inline workflow YAML, following deploy_verdict.py and cstore_verdict.py, so it is unit-testable without a cluster or a registry — and runnable by hand:

python3 trust/deploy/helm/scripts/package_chart.py --version v0.13.0 --no-push

In-tree the chart becomes explicitly un-versioned (0.0.0-dev, floating image tag), because a development checkout should deploy what you built, not the last release.

The publish step sits after the image builds go green and before the production apply, so a published chart never references images that do not exist. A workflow test pins that ordering; it needs packages: write, which the release job did not hold.

Verification

Packaged the chart for real and rendered it — not just unit tests:

stamped helm 0.13.0 (appVersion v0.13.0, global.image.tag v0.13.0)
Successfully packaged chart and saved it to: /tmp/1646pkg/flip-trust-0.13.0.tgz

Rendering the packaged tarball shows every FLIP image pinned and upstream images untouched:

ghcr.io/londonaicentre/data-access-api:v0.13.0
ghcr.io/londonaicentre/flare-fl-client:v0.13.0
ghcr.io/londonaicentre/imaging-api:v0.13.0
ghcr.io/londonaicentre/omop-db:v0.13.0
ghcr.io/londonaicentre/orthanc:v0.13.0
ghcr.io/londonaicentre/trust-api:v0.13.0
ghcr.io/londonaicentre/xnat-{db,nginx,web}:v0.13.0
grafana/grafana:11.5.0        <- untouched
busybox:1.36                  <- untouched
  • Chart suite: 449 passed (423 on develop + 26 new).
  • Workflow tests: ReleasePublishesTheTrustChart, plus the existing permissions and step-order guards, pass.
  • ruff check + format clean.

Mutation-tested the new suite — four mutations, all caught:

Mutation Caught by
never stamp values.yaml (images float on stag) test_publish_stamps_values_on_disk
accept a malformed tag test_a_malformed_version_is_refused
push despite --no-push test_no_push_does_not_push
ship the 0.1.0 default test_the_unpublished_defaults_never_ship

The first one is the bug this whole slice exists to prevent — a chart that claims to be 0.13.0 while deploying whatever stag points at today. The unit tests called stamp_values directly and would not have caught it, so I added disk-level assertions on publish().

Deliberately not here

#1646 as filed also covers a compose/make deployment bundle for non-Kubernetes trusts. That half lives in scripts/site_upgrade.py (669 lines, hard-codes _REPO_ROOT) and is load-bearing for the existing upgrade path. Splitting it out keeps this PR reviewable; follow-up issue to come.

Worth a careful look

  • The chart is pushed before the production apply. If the apply then fails, a chart is published for a release that was never deployed. I think that is the right order — a chart referencing images that exist is the stronger invariant, and a published-but-unapplied chart is inert until someone pulls it — but the opposite order is defensible.
  • appVersion: "v0.13.0" carries the v, version: 0.13.0 does not. Helm requires SemVer for version; appVersion is free-form and matching the git tag seemed more useful. Easy to make consistent if you disagree.

A Kubernetes trust has no versioned deployment artifact. `Chart.yaml` has sat
at version 0.1.0 / appVersion "1.0" since it was written, and the chart is only
ever installed from a working checkout — so "upgrade this trust to v0.13.0"
has no artifact to name. #1644's in-cluster upgrade CronJob needs one: it
cannot clone the repo, it can only pull a chart.

Every release now publishes the chart to GHCR as an OCI artifact, versioned
with the release. scripts/package_chart.py stamps three fields from the release
tag -- Chart.yaml version, Chart.yaml appVersion, and values.yaml
global.image.tag, which is already the single pin for every FLIP-built image
(FLIP#1204) -- then packages and pushes. So flip-trust:0.13.0 deploys v0.13.0's
images and nothing else.

The stamping lives in a script rather than inline workflow YAML, following
deploy_verdict.py and cstore_verdict.py, so it is unit-testable without a
cluster or a registry, and runnable by hand with --no-push for a dry run.

In-tree the chart is now explicitly un-versioned (0.0.0-dev, floating image
tag): a development checkout should deploy what you built, not the last
release. Shipping the old 0.1.0/"1.0" defaults would have been the bug, so a
test asserts neither survives stamping.

The publish step sits after the image builds go green and before the
production apply, so a published chart never references images that do not
exist. It needs packages: write, which the release job did not previously
hold.

Signed-off-by: R. Garcia-Dias <rafaelagd@gmail.com>
@github-actions github-actions Bot changed the title trust/helm: publish the trust chart as a versioned OCI artifact (#1646) Ship trust deployment assets as versioned artifacts instead of a git checkout Nov 2, 2026
@garciadias garciadias changed the title Ship trust deployment assets as versioned artifacts instead of a git checkout feat[auto-upgrade]: Ship trust deployment assets as versioned artifacts instead of a git checkout Nov 2, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ship trust deployment assets as versioned artifacts instead of a git checkout

2 participants