Skip to content

Serve Helm charts from the OCI registry only, with a chart page in the web UI - #435

Merged
schmitch merged 2 commits into
mainfrom
claude/43-helm-oci-only
Oct 24, 2026
Merged

schmitch merged 2 commits into
mainfrom
claude/43-helm-oci-only

Conversation

@schmitch

@schmitch schmitch commented Oct 23, 2026 •

Copy link
Copy Markdown
Member

Fixes #43

Helm charts are pushed to and installed from docker repositories (helm push, helm install oci://…). Forge no longer serves classic chart repositories (index.yaml, ChartMuseum uploads). 2.0.0 is a breaking release, so no upgrade note is written for this.

Classic chart repositories removed

  • The Helm plugin is no longer built in. helm is gone from GET /admin/formats, the web UI's format badge and connect/install snippets, and the Nexus import (nuget and docker only).
  • plugins/helm stays as the example plugin the format-plugin tests run, built in for the test and as a WebAssembly component. forge-server keeps it as a dev-dependency only. xtask plugins now counts only the server's [dependencies] as built in. Remove WebAssembly format plugins and Wasmtime: built-in plugins only #440 (stacked on this) removes it with WebAssembly plugins altogether.
  • Tests that used Helm as the stand-in plugin format now use NuGet, raw or a generic example/acme format. The e2e Nexus import drops its Helm scenario.
  • Changelog fragments that described only the classic plugin are dropped or reduced to their general plugin part: 232 and 422 are removed; 228, 231, 233 and 283 are edited.

OCI charts

  • GET /browse/chart?repo=&image=&digest= (browse_images.rs) returns the chart's Chart.yaml metadata (from the config blob), its README and its values.yaml (from the chart archive), with the same authorization as the image browse: signed in, read on the repository, content selectors, group members by priority, offline repositories.
    • It reads only blobs Forge already holds. A proxy shows archive_stored: false until the chart has been pulled through it.
  • forge_oci::chart holds the Helm media types and keeps a bounded subset of the metadata: strings up to 4 KiB, lists up to 100 entries. A small tar reader (ustar, GNU long names, pax paths) finds the chart's top-level README and values.yaml the way Helm's loader does.
    • It decompresses at most 100 MiB (Helm's limit for a whole chart) and returns at most 512 KiB per file, flagged as cut.
    • It does not read a stored archive larger than 16 MiB.
  • Web UI: an image whose top-level manifests are all charts shows a chart view instead of the docker pull panel.
    • Versions are ordered by SemVer, and the newest release is selected by default.
    • The Install panel has helm install and helm pull for the selected version, with the helm registry login to run first.
    • The page shows the chart's facts, deprecation, README and default values. Home and source links are rendered only for http(s) URLs.
    • The versions and manifests tables stay.
  • Docs: docs/docker.md#helm-charts covers the commands, proxies and groups. docs/format-plugins.md, the README, DEVELOPMENT.md, AGENTS.md and plugins/README.md describe plugins/helm as the example plugin.

CI

The oci-e2e job builds the pinned Helm v4.3.1, the same go install and cache as the kubernetes job. The script then runs:

  • registry login, helm push, and helm pull, checked byte for byte;
  • a pull with a ~1.2 version range, helm show chart and helm template;
  • the browse API, which must return the chart's appVersion, README and values;
  • a pull through the proxy of the registry:2 upstream and pulls through the group;
  • a push to the group, which must land in its writable member.

Admin screen

No admin API changes. The new endpoint is a browse API, and its screen is the image page.

Tests run locally

  • cargo fmt --all --check; cargo clippy --workspace --all-targets -- -D warnings; cargo clippy -p forge-e2e --features forge-e2e --tests -- -D warnings; cargo xtask plugins-check; cargo xtask changelog --check
  • cargo test -p forge-oci --lib chart (5 new unit tests); cargo test -p xtask; cargo test -p forge-server --lib
  • cargo test -p forge-server --test registry (32, including the new helm_charts_are_browsable for hosted, group and proxy before and after a pull), --test plugins (13), --test browse, --test plugin_contract, --test nexus_import
  • web: pnpm run tsc, pnpm run test (399), pnpm run build
  • The new helm step of oci-e2e.sh (with the script's setup) against a live forge-server with Helm v4.3.1, crane and a registry:2 upstream. The other steps of the script (conformance suite, buildx, cosign) were not run locally.
  • Not run locally: the gated forge-e2e suite, including the Nexus import against a real Nexus.

🤖 Generated with Claude Code

https://claude.ai/code/session_01JpCggxduZYrAYTnobHTzhY

Helm charts are pushed to docker repositories (`helm push`, Helm 3.8+)
and installed from there (`helm install oci://…`). Classic chart
repositories (`index.yaml`, ChartMuseum uploads) are no longer a format
of the server: the Helm plugin is not built in, the web UI drops its
`helm repo add` snippets, and the Nexus import no longer copies Helm
repositories. `plugins/helm` stays as the example plugin the
format-plugin tests run, built in for the test and as a WebAssembly
component; `xtask plugins` counts only the server's own dependencies as
built in.

An image of Helm charts gets a page of its own: the versions, newest
release first by SemVer, the `helm install` and `helm pull` commands of
the selected one with the `helm registry login` to run first, its
Chart.yaml facts, README and default values. `GET /browse/chart` reads
them from the chart's config blob and archive (`forge_oci::chart`:
bounded metadata, a minimal tar reader that finds the README and
values.yaml the way Helm's loader does, at most 100 MiB unpacked and
512 KiB shown per file), through groups, and from a proxy once the chart
has been pulled through it.

CI's oci-e2e job builds the pinned helm and drives a chart with it:
registry login, push, pull, a version range, show and template, the
browse API, and pulls through the proxy of the registry:2 upstream and
the group, which also takes a push to its writable member.

Fixes #43

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JpCggxduZYrAYTnobHTzhY
@github-actions

Copy link
Copy Markdown


Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA


You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

@schmitch

Copy link
Copy Markdown
Member Author

I have read the CLA Document and I hereby sign the CLA

Conflicts in DEVELOPMENT.md (main's "every format lives in plugins/"
next to this branch's example plugin) and the Edit screen's doc comment
(main's retention link next to the Nexus import without Helm). Main's
new Helm mentions follow this branch: fragment 422 (a classic Helm fix)
is dropped, 283 and the retention UI name NuGet only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JpCggxduZYrAYTnobHTzhY
@schmitch
schmitch enabled auto-merge October 23, 2026 23:51
schmitch pushed a commit that referenced this pull request Oct 23, 2026
Brings in main via #435. The Helm plugin's files and the WebAssembly
plugin tests stay deleted; main's #283 test there (a proxy of an
unreachable upstream answers 503) moves to group_proxy.rs with its NuGet
half. Main's new "every format lives in plugins/" text in AGENTS.md,
README.md and DEVELOPMENT.md now says plugins are linked into the
server.

A leftover [plugins] section is now ignored, like any other unknown
top-level key, rather than refused at startup.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JpCggxduZYrAYTnobHTzhY
@schmitch
schmitch added this pull request to the merge queue Oct 24, 2026
Merged via the queue into main with commit d4b77a4 Oct 24, 2026
21 checks passed
@schmitch
schmitch deleted the claude/43-helm-oci-only branch October 24, 2026 00:11
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.

Helm charts: classic chart repositories and OCI charts

2 participants