Use this when adding a new component to a bundle, debugging an unexpected resolved value, or building tooling that consumes the bundle. A bundle is a versioned, curated list of platform components and the default versions of each. Engineers pin against a bundle release for reproducible runs (CI), or against the moving edge for daily iteration. Forge resolves a bundle plus an optional override file into a concrete set of Helm releases, then applies them inside your per-engineer vCluster.Documentation Index
Fetch the complete documentation index at: https://docs.grounds.gg/llms.txt
Use this file to discover all available pages before exploring further.
Top-level shape
| Field | Type | Required | Notes |
|---|---|---|---|
apiVersion | string | yes | Must equal platform.grnds.io/v1. Forge rejects other values. |
kind | string | yes | Must equal PlatformBundle. |
metadata.version | semver | yes | Source-of-truth for the bundle’s own version. release-please bumps this in lockstep with the git tag. |
metadata.description | string | no | Human-readable. |
shared | object | yes | Tailnet-exposed backends shared across all engineer vClusters. |
components | map | yes | Map of release-name → BundleComponent. |
shared
Backends that don’t run inside an engineer’s vCluster. Each in-vCluster service connects out via Tailscale to these endpoints.
| Field | Type | Required | Notes |
|---|---|---|---|
<endpoint>.tailnet | string | yes | MagicDNS hostname on the internal Grounds tailnet. The engineer must be on the tailnet and have the matching dev-routes ACL enabled. |
<endpoint>.port | int | yes | TCP port at the endpoint. |
<endpoint>.description | string | no | Human-readable. |
keycloak.realm | string | yes for keycloak | Realm name. Currently grounds-test. |
The shared block is informational — forge doesn’t push these values into helm values automatically. The component charts are responsible for connecting using the same names (e.g. the in-vCluster
service-config chart has NATS_URL=nats://nats.dev:4222 baked into its env).components
A map: each key is the Helm release name (also used as namespace-DNS-label inside the vCluster, so it must be a valid DNS-1123 label — lowercase, hyphens, no underscores). Each value is a BundleComponent:
BundleComponent fields
| Field | Type | Required | Notes |
|---|---|---|---|
type | string | yes | Component-type string. See below. |
chart.url | string | yes | OCI Helm chart URL. |
chart.version | semver | yes | Pinned Helm chart version. |
image | string | yes | Container image without tag. Forge passes this as image.repository into helm values. |
version | string | yes | Image tag — semver, edge, or any other ref. Passed as image.tag. |
optional | bool | no, default false | When true, the component is not deployed by default. Override with enabled: true to bring it in. |
helm | map | no | Free-form Helm values. See merging rules below. |
devspace.workflow | string | no | Selects a DevSpace template when the component is overridden into gradle-local mode. |
Component types
Thetype field is a string for forward-compat, but the platform-test environment understands these values:
| Type | What it is | DevSpace workflow | Iter-Latency |
|---|---|---|---|
plugin-velocity-base | The Velocity proxy itself | jar-sync-pod-restart | ~10–20 s |
plugin-velocity | A JAR plugin loaded by Velocity at startup | jar-sync-pod-restart | ~10–20 s |
plugin-paper (planned) | A JAR plugin loaded by Paper | jar-sync-plugin-reload | ~5–15 s |
gamemode | Minestom or Paper game-server | jar-sync-pod-restart | ~10–20 s |
grpc-service | Quarkus-based gRPC backend | quarkus-dev | ~1–3 s |
utility | Test/debug tooling (e.g. nats-recorder) | – | – |
type only for default-behavior decisions (today: which DevSpace workflow template to suggest). Adding a new type is a bundle PR, not a forge PR.
Helm value merging
The values forge passes tohelm install for a component are produced by:
Inject image.repository + image.tag
Deep-merge
{ image: { repository: <component.image>, tag: <resolved-tag> } } on top.- Plain-object values are merged recursively.
- Arrays are replaced wholesale (no list-merge).
- Primitives are replaced.
Override-File schema
Engineers write an override YAML and pass it togrounds cluster up --bundle X --override ./me.yaml. Schema:
<ComponentOverride> is a discriminated union — exactly one of these shapes:
- image (default)
- gradle-local
- enabled: false
Use the bundle’s image but optionally override the tag.
| Field | Type | Required | Notes |
|---|---|---|---|
mode | "image" | yes | |
tag | string | no | Replaces the bundle’s version: for this component. Omit to keep the default. |
Pod annotations
The fieldsproject, artifact, reload, and devspace aren’t applied by forge — they’re echoed as Pod annotations for DevSpace to read on the engineer’s laptop. The annotations forge writes:
| Annotation | Value |
|---|---|
grounds.gg/devspace-mode | gradle-local |
grounds.gg/devspace-project | the project value |
grounds.gg/devspace-artifact | the artifact value |
grounds.gg/devspace-reload | the reload value (only when set) |
grounds.gg/devspace-quarkus-dev | "true" when devspace: true |
Resolution algorithm
When forge gets(bundle, override-file):
Filter components
Drop everything where
override.enabled === false. Drop optional: true components that aren’t explicitly enabled.Resolve per remaining component
- If override is
mode: imagewithtag: replaceimageTagwith the override. - If override is
mode: gradle-local: keep image+tag from bundle; mark mode for annotation injection later. - If no override: use bundle defaults.
Adding a new component
Ensure the chart exists
Make sure the component-type’s Helm chart is in
groundsgg/charts and published as an OCI artifact (or co-publish it in the same PR).Mark optional if it shouldn't run by default
Add
optional: true and document the opt-in in examples/.Versioning
release-please drives the bundle version:| Commit type | Bump |
|---|---|
feat: | minor |
fix: | patch |
feat!: / BREAKING CHANGE: | major |
bundle: main always tracks the latest commit on main — useful for daily iteration, not for CI.
See also
- Test Environment overview — engineer onboarding from
grounds loginto a hot-reload loop groundsgg/charts— the Helm charts each component type maps to
