Skip to main content

Documentation Index

Fetch the complete documentation index at: https://grounds-feat-grounds-runtime-libraries.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

./gradlew groundsPush                       # default target
./gradlew groundsPush --target=staging
./gradlew groundsPush --target=dev
This is the task the CLI’s grounds push invokes under the hood. Run it directly when you don’t have the CLI on your machine, or from CI.

What it does

  1. Validate — parses grounds.yaml, checks required fields, and verifies that baseImage is a source key allowed for the selected workload type.
  2. Resolve JAR — uses the jarFile extension property, or auto-detected shadowJar/jar output. Builds it if needed (this task dependsOn the JAR task).
  3. Upload — multipart POST of the JAR + manifest to <apiUrl>/v1/pushes. Returns a push ID.
  4. Stream — opens an SSE connection to <apiUrl>/v1/pushes/<id>/logs and tails until terminal status.
  5. Exit — fails the build (non-zero exit) on build_failed or deploy_failed. Logs the public URL on ready.
Forge performs the final runtime image selection server-side from the base image catalog. The Gradle plugin sends the manifest source key, not an OCI tag or digest.

Flags

FlagPurpose
--target=<dev|staging>Override the manifest’s target. Highest precedence.
--forceSkip forge’s content-hash dedup and force a fresh build. Use after a base image catalog promotion when the manifest and JAR bytes did not change, or when you want to re-observe the build flow.
Everything else is configured via the groundsPush extension or grounds.yaml.

Multi-plugin bundles

When grounds.yaml contains plugins:, groundsPush resolves every source, packs the resolved JARs into a tar.gz bundle, and uploads that bundle as the artifact. Forge unpacks it into /app/plugins/ in manifest order.
grounds.yaml
name: velocity-stack
type: plugin-velocity
baseImage: velocity
plugins:
  - id: plugin-agones
    variant: velocity
    source: github:groundsgg/plugin-agones@v0.5.0
  - id: plugin-player
    variant: velocity
    source: github:groundsgg/plugin-player@v0.1.0
If you run grounds push --local ... or grounds push --with-local, the CLI resolves local workspace artifacts before Gradle starts and passes those resolved sources to groundsPush. The shared manifest still contains release sources; local filesystem paths stay in the CLI workspace config.
Bundle uploads are capped at 100 MB. Keep dependency JARs out of the plugin artifact when the runtime already provides them.
For the developer workflow around this feature, see Test multi-plugin stacks.

Output

> Task :groundsPush
[grounds-push] uploading my-plugin-0.1.0-all.jar (4.2 MB)
[grounds-push] pushId=018f9c12-…
[build] step 1/5 …
[build] step 5/5 done — image registry.platform.grnds.io/my-plugin@sha256:…
[deploy] reconciling deployment
[deploy] pod scheduled
[deploy] pod ready
[grounds-push] ✔ ready — connect at my-plugin-hendrik.mc.grnds.io
When run via grounds push, the CLI re-rendres these messages with colour and progress indicators. As a raw Gradle task it’s plaintext.

Failure handling

The build fails on:
  • Manifest parse error (caught locally before upload).
  • Upload error (network, 4xx from forge, file not found).
  • Terminal build_failed or deploy_failed from the SSE stream.
  • Connection lost for longer than timeoutMinutes (default 5).
  • Whitelist warning when failOnWhitelistError = true (the default).
Each prints a GradleException with the diagnostic from forge. For build/deploy failures, the message includes the push ID so you can re-run with groundsPushRetry or fetch logs separately.

Inputs / outputs (Gradle terms)

PropertyTypeDefault
manifestFileRegularFileProperty (input)<projectDir>/grounds.yaml
jarFileRegularFileProperty (input)auto from shadowJar / jar
apiUrlProperty<String> (input)from credentials, else https://platform.grnds.io
targetProperty<String> (input)dev
timeoutMinutesProperty<Int>5
connectTimeoutSecondsProperty<Int>20
failOnWhitelistErrorProperty<Boolean>true
This task has no Gradle outputs and is not cacheable — it always re-runs (a push is by definition not idempotent, even though forge dedupes by content hash).

Calling from CI

.github/workflows/push.yml
jobs:
  push:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: '21'
      - run: ./gradlew :plugin:groundsPush --target=staging
        env:
          GROUNDS_TOKEN: ${{ secrets.GROUNDS_TOKEN }}
          GITHUB_ACTOR:  ${{ github.actor }}
          GITHUB_TOKEN:  ${{ secrets.GITHUB_TOKEN }}      # for plugin pull
GROUNDS_TOKEN should be a service-account token scoped to the project. Don’t use a personal user token — it has too-broad permissions and can’t be rotated independently.