Skip to content

Releases

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 11 Nov 15:48
Immutable release. Only release title and notes can be modified.
v0.4.0
46b719f

A pre-v1 release with every change made since v0.3.0: an independent central
panel, languages, the extended telemetry tier, safer backups and restores,
fleet-wide node inventory, and a pre-release security hardening pass. Read the
upgrade notes below before upgrading; several of them change behaviour. It
does not claim v1 or production support; see docs/roadmap.md.

Fixed

  • Backup, restore and wipe exclusion (#718): backups, restores and wipes
    of the same server now take one lifecycle ownership, so a backup can no
    longer read a filesystem a restore or wipe is changing, and wipe workers are
    drained before workloads come back (PRs #760, #619).
  • Backup captures: backup workers are prepared before quiesce, CSI
    snapshot captures are bounded, and a capture taken across a game container
    restart is invalidated instead of being kept (PRs #836, #846).
  • Backups with retention disabled are kept (PR #618).
  • Wake on connect: wake requests are bounded, HostPort hand-offs are
    preserved, and shared wakes retry within their budget instead of failing on
    the first cold-start error (PRs #840, #860).
  • Tunnels: frp identities are isolated per server and report relay
    connection health; Tailscale forwards every advertised TCP and UDP port and
    keeps active UDP sessions (PRs #768, #765).
  • New files are created atomically and never overwrite an existing file
    (PR #621).
  • Standalone Helm CRD isolation: the central panel profile excludes bundled
    native CRDs and their apply hook/RBAC without requiring --skip-crds.
    Default operator installations keep Helm's native CRD lifecycle; existing
    CRDs and their custom resources are retained when a profile omits them.

Upgrade Notes

  • Breaking: admin-level grants need a full administrator: holders of
    users:manage, roles:manage or config:manage without * can no longer
    grant * or another admin-level permission, edit or reset an administrator,
    or edit auth providers (/admin/config/auth, /admin/auth need *)
    (PR #862).
  • Breaking: kubelet probes reach only probe ports: a new per-server
    <server>-probes NetworkPolicy admits kubelet CIDRs to the game container's
    probe ports only, on by default with networkPolicies.probeIngress.enabled.
    The old all-ports allow-kubelet-probes rule renders only when that is
    false or extra probePorts are listed. Set
    networkPolicies.probeIngress.enabled: false to restore the old rule
    (PR #862).
  • Breaking: custom CSS: stylesheets with \ escapes or absolute,
    http(s): or protocol-relative // references are now rejected (PR #862).
  • Share links get their own Ingress: /share and /shares go through a
    second Ingress, gameplane-share, with access logging off for ingress-nginx
    (ingress.shareLinks.*). Other controllers need their own switch in
    ingress.shareLinks.annotations; see docs/install.md
    (PR #862).
  • Password reset ends every session of that account (migration
    019_session_epoch.sql, applied on API startup) (PR #862).
  • The API is a singleton in every mode: every database driver uses the
    Recreate strategy and api.replicas other than 1 is rejected, so upgrades
    no longer overlap two API processes (#726, PR #758).
  • Auxiliary resource requests and management placement: agent,
    config-init, sentinel, tunnel and Restic pods now request resources on every
    install, and chart-managed pods accept placement settings. Game and
    auxiliary pods can restart on upgrade; see
    docs/release-notes.md (#724, PR #762).
  • Standalone panel/API: run the central panel with Docker Compose or the
    standalone Helm profile, without a local game cluster or operator. Compose
    needs no Kubernetes installation on the panel host.
    Register remote clusters explicitly. Back up the database and matching
    credential encryption key separately, with restricted access and encrypted
    storage for key backups. Supplied profiles use key storage outside the database
    volume. Preserve the original key when migrating legacy /data/panel.key
    installations. See standalone installation.
  • Breaking: selected-cluster module/template grants: in combined and
    standalone installations, catalog permissions now require a cluster-wide
    grant on the selected cluster or wildcard cluster. A grant on local retains
    local access but no longer authorizes a remote catalog. Before upgrading,
    identify users who rely on remote catalog access and grant a role containing
    modules:read, modules:manage, templates:read, and/or templates:write
    on each intended remote cluster, selecting All namespaces. Grant only the
    operations each user needs; namespace-only grants do not authorize catalogs.
    See grant workload access.
  • Telemetry is on by default for new installs, after a first-login
    notice:
    a new install with a telemetry destination in effect now shares
    basic and extended data by default; the stock destination is the project's
    receiver at telemetry.gameplane.net. The first admin to sign in sees a
    notice that lists every field of both tiers and names the destination;
    nothing is sent before then. Basic is version, servers and
    templates. Extended adds a random install ID, the Kubernetes minor
    version, a distribution category, node architectures and a node-count
    band, server counts per official module plus one custom count, feature
    flags (wake-on-connect, tunnel types, packet capture, backups, single
    sign-on, audit forwarding), a cluster-count band, the database kind, the
    UI language, the install's public signing key and the send time. Each
    tier has its own toggle in Admin Settings → Telemetry, which also
    shows the destination, a preview of the next report and an install-ID
    reset. The data-handling statement is at
    https://gameplane.net/telemetry/. See
    docs/install.md.
  • Installs whose basic toggle was already on start sending to the
    project's default receiver:
    an install that saved Send anonymous usage
    metrics
    while no destination was configured (so it had no effect) starts
    sending basic reports to the project's default receiver
    (telemetry.gameplane.net) after upgrade.
    Extended stays off until an admin turns it on, and installs that never
    saved a choice stay off. Installs already using a custom
    api.telemetry.endpoint or the bundled receiver keep sending only there.
    Set api.telemetry.enabled=false before upgrading to prevent any
    sending.
  • Empty api.telemetry.endpoint now means the project default:
    It now means the project's default receiver
    (https://telemetry.gameplane.net/ingest), so the admin toggles have an
    effect on a stock install. Set api.telemetry.enabled=false for a hard off (air-gapped
    clusters, privacy-sensitive installs); it overrides the endpoint, the
    bundled receiver and the admin toggles, and hides the notice.
  • The receiver's /metrics moved to the dashboard port and needs the
    dashboard token:
    the receiver's Prometheus endpoint is no longer on
    :8080; it is on :8081 and accepts only
    Authorization: Bearer <DASHBOARD_TOKEN>. Without
    api.telemetry.receiver.dashboard.tokenSecretRef.name there is no
    dashboard listener and no metrics endpoint, and the chart renders no
    ServiceMonitor for the receiver. Update your Prometheus scrape config
    or set the token Secret. See
    docs/telemetry-provider.md.
  • The bundled receiver now stores data: with
    api.telemetry.receiver.persistence.enabled (default true, 1Gi) it
    keeps daily aggregates for 24 months and activity records for 90 days in
    SQLite on a PVC, and runs a single replica with a Recreate strategy.
    helm upgrade --reuse-values from 0.3.0 needs no new values; with no
    persistence block the receiver keeps using an emptyDir, as before.
  • The receiver's DASHBOARD_TOKEN must be at least 32 characters: a
    receiver with DASHBOARD_TOKEN set to a shorter value now exits at
    startup (DASHBOARD_TOKEN must be at least 32 characters). Replace the
    Secret behind api.telemetry.receiver.dashboard.tokenSecretRef with a
    value generated from 32 random bytes, for example
    openssl rand -base64 32, before upgrading. Replacing the token
    invalidates browser sessions and loses no data. Receivers with no token
    (no dashboard) are unaffected. See
    docs/telemetry-provider.md.

Added

  • Independent central panel: Docker Compose runs the API/dashboard without
    host Kubernetes; a standalone Helm profile runs them without a central game
    operator or workloads. SQL stores registrations, settings, and encrypted
    credentials; explicitly selected remote clusters host games through their own
    operators and agents.
  • Credential maintenance: standalone keys have separate generated storage
    or read-only provisioned custody, the offline transactional rotate-panel-key
    command, and PUT /clusters/{name}/kubeconfig preserving registration identity
    and grants. PUT/DELETE /clusters/{name}/gateway manage remote gateway
    credentials; api.remoteAllowedCIDRs restricts workload API and gateway
    destinations. See standalone setup.
  • Extended telemetry tier: a second, separately consented tier with a
    random install ID, environment, game-usage and feature-adoption
    categories. Every value comes from a fixed set, a band or a number; no
    names, namespaces, hostnames, addresses, player counts or custom module
    names. Reports are signed (Ed25519, key derived from a per-install secret
    and the install ID); a receiver binds each ID to its first key and refuses
    forged, stale and replayed reports. See
    [docs/security.md](docs/security.md#telemet...
Read more

v0.3.0

Choose a tag to compare

@github-actions github-actions released this 06 Oct 04:10
v0.3.0
040e10e

The first Gameplane release without a pre-release suffix, a pre-v1 release. It
contains every change made since v0.2.0-beta.8, including the changes first
previewed in v0.3.0-rc.1 and the pre-release audit fixes summarized under
0.3.0-rc.2 below. It does not claim v1 or production support; see
docs/roadmap.md.

Upgrade Notes

  • Network capture feature adds an emptyDir volume to every game pod: The
    network capture feature (protocol reverse-engineering and admin-only traffic
    diagnostics) requires a pre-provisioned volume on every game pod, whether or
    not that server will ever opt into capture. This is a structural requirement:
    Kubernetes ephemeral containers can add containers to a running pod without pod
    recreation, but cannot add volumes. The capture emptyDir volume must exist in
    the pod template before the ephemeral sidecar is injected, so it is provisioned
    unconditionally at cluster install time.
    Consequence: every existing GameServer will roll once on upgrade to this
    release.
    Each pod will be recreated with the new template (containing the
    empty capture volume), interrupting any active player sessions. This is a
    one-time event at upgrade time and does not repeat on each server start. Plan
    your upgrade window for a time when you can tolerate a rolling restart of all
    game servers. The upgrade note for FR-001 and SC-007 (specification items
    tracking pod immutability) is updated to reflect this: non-opted-in game servers
    are no longer byte-identical between captures disabled and enabled; they carry
    an empty, unused capture volume. What they do NOT carry is the capture sidecar
    container itself (no ephemeral container, no CAP_NET_RAW, no network access
    change).

  • Owner-only server operations need the owner or an admin: transferring
    ownership, editing collaborators, wiping data and deleting a server now need
    the server's owner or an admin. Operator-role users keep their other server
    permissions, but can no longer run these four operations on servers they
    don't own. Servers without a recorded owner (for example ones created with
    kubectl or GitOps) can be transferred, wiped or deleted only by an admin.

  • Playit tunnel NetworkPolicy egress widened: the operator-managed
    NetworkPolicy for a GameServer using the playit tunnel provider now adds
    an unrestricted egress rule (all ports and protocols, any destination)
    alongside the DNS/advertised-ports rule every provider gets. Previously
    playit got only that rule, so it could not reach its relay (F-262).

  • Helm 3 reinstalling over leftover CRDs runs the CRD-apply hook: a
    helm install onto Gameplane CRDs left behind by an uninstalled release
    runs the crds.autoApply hook to bring them up to date, so air-gapped
    clusters need crds.autoApply.image mirrored for that case. Under Helm 4,
    existing CRDs are applied natively; CRDs last applied by v0.2.0-beta.8 or
    earlier need a one-time helm install --force-conflicts (F-218).

Added

  • Configurable backup/restore Job limits: the restic backup and restore Jobs' retry limit and deadline are now Helm values (operator.backupJobBackoffLimit, default 2; operator.backupJobActiveDeadlineSeconds, default 86400), passed to the operator as --backup-job-backoff-limit / --backup-job-active-deadline-seconds.
  • Multicluster gateways and unified server management: an optional
    private mTLS agent gateway (with its own Helm deployment) lets one dashboard
    and API manage authorized game servers across independent clusters.
    Dashboard, Servers, Backups and Search combine every site with optional
    location filters, and console, files, players, mods and captures are routed
    to the selected server's cluster (#542).
  • User theme customization (feature 016): Settings → Theme & Appearance
    offers preset themes (Modern Pink, Legacy Orange) and custom color selection
    with live WCAG AA contrast validation. Custom accent and surface colors are
    persisted per user; appearance mode (light/dark) can follow the surface color.
    Custom CSS overlay allows per-user style tweaks; all customizations support
    import/export. Safe mode (?safe-mode=1 or keyboard shortcut) suspends custom
    CSS and shows a banner without reloading. Theme bootstrap on login prevents
    flash; preferences are read/write controlled via RBAC (every user sees only
    their own) (#415).
  • Network capture sidecar (feature 003): Admin-only, on-demand packet capture
    from running GameServer pods. Enabled per server via a Dashboard toggle, capture
    runs as an ephemeral sidecar container (no pod restart), is recorded as PCAPNG
    (Wireshark-compatible), and auto-expires after 7 days or a configurable size/duration
    limit. Download streams directly from the capture sidecar via the existing
    <gs>-agent Service. The capture emptyDir volume is pre-provisioned on every
    pod at cluster install time (the upgrade consequence above). Every capture
    session is recorded in the audit log with admin-only playback to the
    captures:manage role. For protocol reverse-engineering and diagnostics (#256).
  • Easy module building & authoring toolkit (feature 010): Scaffolds, validates,
    previews, and packages custom game modules. The gp-module CLI supports three
    starter archetypes (steamcmd, java, generic) with configurable ports,
    storage, and metadata; offline validation with source-line diagnostics; dry-run
    manifest rendering (simulates autoFromMemoryLimit); and OCI bundle packaging
    with media-type and size-limit enforcement. The web dashboard (Modules page)
    offers a BuildModuleDialog with live validation, YAML editor, bundle download,
    and cluster installation. API endpoints: /modules/builder/{scaffold,validate,preview,export} (#370).
  • 13 new top-steam-game modules (feature 015): FiveM, Farming Simulator 25,
    Euro Truck Simulator 2, Mount & Blade Bannerlord, tModLoader, Team Fortress 2,
    BeamMP, Left 4 Dead 2, The Isle, ARK: Survival Evolved, Arma Reforger, Hell
    Let Loose, and Squad. Gameplane publishes four Gameplane-owned container
    images: ghcr.io/valgulnecron/gameplane/fivem (FiveM + txAdmin), farming-simulator-25
    (Wine/Xvfb runner), euro-truck-simulator-2 (Wine runner), and beammp
    (BeamMP + non-crashing diagnostic idle). All modules are signed with Cosign
    keyless signatures (#369).
  • Nuclear Option dedicated server support: New nuclearoption remote-command
    protocol implemented in the agent's RCON client set, wired into console /
    players / quiesce; a Gameplane-owned, SteamCMD-based nuclear-option
    container image (no official image exists upstream); generic min / max /
    minLength / maxLength constraints on ConfigField, enforced in
    materializeConfig for every module, landed alongside it (#252, #255, #260).
  • Install-time configuration (feature 006): Two Helm values for zero post-deploy
    configuration:
    • Helm-seeded OIDC role mappings: api.oidc.groupsClaim, api.oidc.defaultRole,
      and api.oidc.roleMappings.{admin,operator,viewer} seed a read-only "helm"
      OIDC provider, so OIDC-only installs need no bootstrap-admin run. Dashboard
      Settings → Authentication can override any role's group list (stored in
      helmOverride.roleMappings); changes take effect on next login (no restart).
      Reset via DELETE /admin/config/auth/role-mappings/{role}.
    • Default StorageClass for game-data PVCs: operator.gameDataStorage.storageClassName
      (Helm value) sets a cluster-wide default with precedence: GameServer >
      GameTemplate > install-time > cluster default. Missing StorageClass surfaces
      as PVCProvisioningFailed (recoverable) (#282).
  • Share link expiry options (feature 017): Removed the hard 90-day cap that
    outlived long-running servers. Create requests now carry expiresAt (RFC3339
    instant) or neverExpires: true (not both, not neither = 400 error). Dashboard
    offers presets (15/30/60/90 days, No expiry) and custom date picker; 30 days
    is pre-selected. Past instant dates are rejected. The deprecated expiresIn
    field still works for one release (#392, #396).
  • Console WebSocket robustness: Fixed 403 errors when dashboard is reached
    on non-default ports (e.g., kubectl port-forward svc/gameplane-web 8088:80)
    by forwarding $http_host instead of $host in the nginx config. Added guard
    on send() before socket open: input sent while CONNECTING is queued (max 500
    items) and flushed on open; input after reconnect is dropped (no silent replay);
    input after close is no-op. Queue tests verify behavior with fake sockets that
    throw like real browsers (#416).
  • Existing PVC for SQLite: Helm api.storage.existingClaim allows installs
    to point the API database to a pre-existing PersistentVolumeClaim, enabling
    storage migration and lifecycle separation from the main Helm release (#390).
  • REST and CLI console protocols: Agent implementation for rest (generic HTTP
    for games with HTTP admin APIs like FiveM txAdmin) and cli (local process
    execution for PTY-only games like Terraria). Both are wired to console, players,
    quiesce, lifecycle, and quick-action endpoints. The rcon.protocol enum is
    now source;telnet;websocket;battleye;satisfactory;palworld;nuclearoption;rest;cli;none (#369).
  • Security audit remediation: Multiple fixes from a comprehensive security
    audit: share links are isolated by cluster; GameServer setting/image/service
    account/environment/tunnel changes are permission-checked; Secret and ConfigMap
    references must belong to the target server; optional network policies restrict
    audit and telemetry services to API traffic; SteamCMD image pinned to a stable
    version (#350).
  • Mod archive path confinement: Symlink-escape and zip-slip guards hardened
    across every extraction and non-extract upload call site in the agent's mods
    handler (ConfinePath / `Con...
Read more

v0.2.0-beta.8

v0.2.0-beta.8 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 22 Aug 22:55
v0.2.0-beta.8
ed0a886

A dependency sweep: all Go modules bumped to latest available versions,
web dependencies updated, and CI image pins aligned to current stable releases.

Added

  • Wake-on-connect for idle auto-sleep: a sentinel component (distroless Docker
    image, configured via operator.sentinelImage) holds advertised ports while a GameServer
    is asleep and wakes it on a genuine connection attempt. Opt-in per server via
    spec.idle.wakeOnConnect (default false). New CRD fields:
    GameServer.spec.idle.wakeOnConnect (bool) and GamePort.wakeProtocol
    (enum: minecraft|terraria|generic|none, default generic). New shared
    module gameproto/ for Minecraft and Terraria handshake parsing; UDP-only
    games use a generic packets-in-window heuristic. Works across all four expose
    modes; Hostport has asymmetric limitations documented in docs/roadmap.md.
    Costs one small pod per sleeping server.
  • Load-balancer address pools: GameServers can now request a specific address
    pool or explicit public IP when exposed as LoadBalancer services, via optional
    spec.networking.addressPool and spec.networking.address CRD fields. The
    operator translates these to the cluster's load-balancer flavor (configured
    via operator.addressManager Helm value: metallb | cilium | none,
    default none): MetalLB gets pool → metallb.io/address-pool annotation and
    address → metallb.io/loadBalancerIPs; Cilium gets pool →
    gameplane.local/lb-pool label (admin mirrors it in
    CiliumLoadBalancerIPPool.spec.serviceSelector) and address →
    lbipam.cilium.io/ips. A new AddressAssignment status condition tracks the
    assignment outcome with eight reason codes (Assigned, AssignmentPending,
    PoolNotFound, AllocationFailed, AddressInUse, ServiceNotReady,
    IgnoredForExposureMode, NoAddressManagerConfigured). Dashboard support added
    for setting and viewing pool/address. See docs/networking.md.

Security

  • Signing key rotated: cosign key type changed from Ed25519 to ECDSA P-256
    (cross-signed for trust continuity; see docs/key-rotation.md).
  • Transparency logging enabled: all published images, the Helm chart (now
    signed for the first time), and official module bundles are signed and
    recorded in the public Sigstore Rekor transparency log. Signing is now
    fail-closed in CI (missing COSIGN_PRIVATE_KEY fails the release).

Changed

  • Go dependencies: telemetry-receiver, sentinel, and mcp-server updated
    to latest go-openapi versions (github.com/go-openapi/{jsonpointer,jsonreference,swag}
    v0.2x → v1.x); operator updated with 50+ indirect dependency bumps (go-git
    v5.19.1 → v5.19.2); api's modernc.org/sqlite v1.54.0 → v1.55.0; agent and
    e2e test suite indirect dependencies (k8s.io, golang.org/x packages) brought
    current.
  • Web dependencies: @tanstack/react-virtual v3.14.8 → v3.14.9,
    lucide-react v1.26.0 → v1.27.0, @types/node v26.1.1 → v26.1.2,
    globals v17.7.0 → v17.8.0, jsdom v29.1.1 → v30.0.1, postcss v8.5.23 →
    v8.5.25.
  • CI image pins: setup-envtest release-0.19 → release-0.24, Kubernetes
    (envtest) 1.31.0 → 1.36.2 (now in sync with the Makefile), and kind v0.24.0 →
    v0.32.0.
  • Container image defaults: restic/restic 0.18.1 → 0.19.1 (charts/gameplane/values.yaml operator.resticImage default) and nginxinc/nginx-unprivileged 1.30-alpine → 1.31-alpine (web/Dockerfile base image).
  • modules/build.sh gained --tlog-upload flag (passed by the release
    pipeline for official bundles); default stays offline for air-gapped authoring.
  • Module bundles are now signed by the pushed manifest digest. build.sh
    previously took the first sha256: token in oras push output, which is not
    necessarily the manifest — a layer digest printed in full would have been
    signed instead (operator verification unchanged).

Notes

  • TypeScript held at 6.x: @typescript-eslint/parser@8.65.0 declares
    peerDependencies: typescript >=4.8.4 <6.1.0, so upgrading to TS 7.x would
    break type-aware linting. Reevaluate when @typescript-eslint/parser publishes
    a v8.x major that supports TS 7+.
  • ESLint held at 9.x: eslint-plugin-react@7.37.5 declares no ^10 peer
    range, so upgrading to ESLint 10.x would break React linting. Reevaluate when
    eslint-plugin-react publishes a v8+ major or a 7.x patch that widens the
    peer range.
  • Prometheus client_golang: telemetry-receiver's
    github.com/prometheus/client_golang v1.24.1 is at latest; no update
    available.

v0.2.0-beta.7

v0.2.0-beta.7 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 18 Jul 19:04
a417682

A stabilization release: a full audit of code, the live dashboard, the API, and
the docs ahead of wider external testing. Highlights below.

Security

  • api: the WebSocket console/logs/files/players/actions/status/mods routes
    and the mod-id / mod-update handlers now reject a ?cluster= selector that
    isn't the local cluster
    (404). These handlers only ever act on the control
    plane's own cluster, but RBAC authorized the namespaced permission against the
    caller-supplied ?cluster= — so a user bound only to a registered remote
    cluster could pass ?cluster=<remote> to satisfy RBAC and reach same-named
    local servers (RCON/PTY console, mod writes, log/file reads).
    Single-cluster installs were unaffected.
  • operator: Expose: Hostport now binds only advertised template ports to
    the node — non-advertised admin ports (RCON/query/telnet consoles) are no
    longer exposed on the node IP, matching the Service and NetworkPolicy filters.

Fixed

  • api: the long-lived SSE /events stream and the WebSocket routes are no
    longer force-closed after 60 s by the global request-timeout middleware (which
    also spammed superfluous response.WriteHeader into the API log every
    minute). The 60 s deadline still applies to every normal request/response
    route.
  • api: /modules/catalog never emits "sources": null for an
    installed-but-uncatalogued module (it serializes []), which previously
    crashed the entire Modules page at render.
  • web: a Failed module can now be uninstalled — its Uninstall button was
    disabled, trapping the user with a broken install and no way to remove it.
  • agent: the Source-RCON and telnet console clients gained the auth-failure
    cooldown the other protocol clients already had — a wrong RCON password is no
    longer re-sent on every poller tick (which could self-inflict a Source-engine
    sv_rcon_maxfailures ban). Both now wrap the shared ErrAuth sentinel, and
    ban/kick reasons reject all control characters, not just CR/LF.
  • operator: BackupSchedule.status.lastSuccessfulTime is now populated from
    the newest successful backup (the dashboard "Last run" and kubectl "Last"
    columns were always blank); the Module Pending path clears a stale Pulling
    condition; GameServer setPhase stamps observedGeneration; and the
    ModuleSource "indexed N of M" status message no longer goes negative for
    git/http/local/upload sources.
  • chart: the operator (and API) metrics ServiceMonitors now select a
    Service that actually exists and carries the matching
    app.kubernetes.io/name label — operator metrics, the PrometheusRule alerts,
    and the Grafana dashboard were never scraped before.
  • web: per-node pod counts show — instead of a fake 0/<cap> when the
    count is unavailable (matching CPU/memory), plus assorted accessibility labels
    and a fix to the cluster page's developer-facing empty-state copy.

Changed

  • chart: the defaultModuleSource template fallback is now oci (matching
    the shipped values.yaml default) rather than git.

Docs

  • Refreshed stale references: the current version, the 8th (Cluster) CRD, the
    RBAC database tables, the OCI default module source, the telemetry-receiver
    and mcp-server components, the full ModuleSource type list, the
    architecture diagram's reconcilers, and the changelog link footer. Clarified
    that SQLite is the production-tested database driver and Postgres is
    experimental (build-tag-gated, work-in-progress).

v0.2.0-beta.5

v0.2.0-beta.5 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 03 Jul 20:52
d897c60

Added

  • ci/supply-chain: the cosign public key is now published — committed
    at the repo root as cosign.pub, exported by CI (job summary +
    artifact on every edge publish), and shipped as a release asset. Both publish
    workflows now verify each signature right after signing with the key
    derived from the CI secret, and fail the publish if the committed
    cosign.pub drifts from the signing key. README and docs gained
    cosign verify instructions (the key is Ed25519; offline/keyed, so
    verification takes --insecure-ignore-tlog=true).
  • ci: tagged releases now get a GitHub Release page automatically —
    notes extracted from the tag's CHANGELOG section, prereleases flagged,
    cosign.pub attached, idempotent on re-runs. (beta.4's page was backfilled
    by hand.)
  • website: Gameplane has a public marketing + docs site at
    https://valgulnecron.github.io/gameplane-website/ — features, game
    showcase, an AMP comparison, and the full documentation set, designed
    screen-first in design.pen (18 frames) and built with Astro. The source
    lives in the separate
    gameplane-website
    repo, mounted here as the website/ submodule.
  • web: the last UI-audit parity items — a show/hide toggle on the login
    password field, user emails shown under display names on the Users page,
    port overrides editable in the Create Server wizard's Network step (the CRD
    and Settings tab already supported them), and "Back up now" relocated to a
    header button + dialog on the Backups page, matching the design.

Changed

  • ci: the three kind e2e jobs (core / extended / game bot) were collapsed
    into a single job running the same three suites, in the same order, against
    one cluster — they were already fully serialized by the shared concurrency
    group, so the split only cost duplicate image builds, cluster setups, and
    queue slots (~15-20 min per run). Docs-only changes no longer trigger the
    test pipeline at all (paths-ignore); no test was removed.

v0.2.0-beta.4

v0.2.0-beta.4 Pre-release
Pre-release

Choose a tag to compare

@ValgulNecron ValgulNecron released this 03 Jul 17:04
7a03289

Added

  • operator: fleet metric gameplane_gameservers{phase=…} exported on the
    operator's /metrics endpoint — one gauge per GameServer lifecycle phase,
    computed from the controller cache at scrape time (so it never drifts from
    reconcile state). The bundled Grafana dashboard gains "GameServers
    running/failed" stats and a stacked "GameServers by phase" graph, and
    prometheusRules.enabled gains a GameplaneGameServerFailed alert. Until
    now the dashboard and alerts plotted only controller-runtime internals; this
    is the first domain metric.
  • operator: companion fleet metric gameplane_backups{phase=…} (one gauge
    per Backup phase), with a "Backups failed" stat + stacked "Backups by phase"
    graph on the dashboard and a GameplaneBackupFailed alert — a silently failed
    backup is a data-loss risk, so it's worth paging on.
  • ci: the published component images (:edge on every main push and the
    versioned images on a v* release) are now keyed-cosign-signed by digest
    (offline, no Rekor), matching the official module bundles. Verify with
    cosign verify --key cosign.pub ghcr.io/valgulnecron/gameplane/<component>.
    Gated on COSIGN_PRIVATE_KEY, so publishing still works before the key is set.
    Signing and publishing run only on main/tags, never on PRs.
  • api: server-side audit-log export — GET /admin/audit/export?format=csv|json
    (admin-only) streams the entire audit trail, optionally bounded by RFC3339
    since/until. Unlike the dashboard's client-side CSV (only the loaded page),
    this returns the full log in one download for compliance/archival, streamed
    row-by-row so a large table isn't buffered in memory.
  • api: outbound audit-log webhook push sink — set api.audit.webhook.url
    and the API POSTs each audit event as JSON to that endpoint (a log aggregator's
    push API, a SIEM, or your own receiver), alongside the database. It mirrors,
    never gates: events always persist, and a slow or unreachable endpoint never
    blocks or fails a request (bounded async buffer, drop-and-count on overflow,
    surfaced at gameplane_audit_webhook_events_total{result=sent|failed|dropped}
    on /metrics). An optional Authorization header is Secret-sourced
    (api.audit.webhook.authSecretRef), never a flag.
  • audit-syslog-bridge: a new, generic HTTP-JSON → syslog relay image that
    sits behind the audit webhook sink, so audit events can be forwarded to a
    syslog/SIEM collector (RFC 5424 over TCP, TCP+TLS, or UDP). Deploy the bundled
    relay with api.audit.webhook.syslogBridge.enabled=true +
    …syslogBridge.syslog.addr, and the chart auto-points the webhook at it (off
    by default). The bridge forwards the request body verbatim, so it works for
    any JSON webhook source, not just Gameplane.

Changed

  • chart: the bundled defaultModuleSource now defaults to a git source
    that indexes the public gameplane-module repository, so the official games
    appear in the Modules page out of the box — no OCI registry to publish first.
    Set defaultModuleSource.type: oci to pull (optionally cosign-signed) bundles
    from a registry instead. Breaking values change: the former top-level
    url / insecure / modules / pullSecretName / verify keys moved under
    defaultModuleSource.oci.*.
  • chart: the official module-signing public key (ed25519) now ships in
    defaultModuleSource.oci.verify.cosignPublicKey, so verifying official bundles
    is just type: oci + oci.verify.enabled: true — no key to paste. Still off
    by default.

Fixed

  • operator: the Servers list "Node" column was always blank — nothing ever
    set the gameplane.local/node annotation the dashboard reads. The GameServer
    reconciler now keeps it in sync with the node the game pod is scheduled on
    (and clears it when the server is stopped), so the column shows real placement.

v0.2.0-beta.3

v0.2.0-beta.3 Pre-release
Pre-release

Choose a tag to compare

@ValgulNecron ValgulNecron released this 27 Jun 11:23

First release published to the GitHub Container Registry — installable with a single Helm command (no helm repo add).

Install

helm upgrade --install gameplane oci://ghcr.io/valgulnecron/charts/gameplane \
  --version 0.2.0-beta.3 \
  --namespace gameplane-system --create-namespace \
  --set ingress.host=gameplane.your-domain.test

Track the rolling beta instead with --set image.tag=edge. See docs/install.md.

Published artifacts (GHCR)

  • Chart: oci://ghcr.io/valgulnecron/charts/gameplane:0.2.0-beta.3
  • Images (linux/amd64 + arm64): ghcr.io/valgulnecron/gameplane/{operator,api,agent}:0.2.0-beta.3

Highlights

  • Full GHCR publishing — release.yaml publishes version-pinned multi-arch images + the OCI Helm chart on every v* tag; publish-edge.yaml publishes rolling :edge + :sha-<short> images on every main push.
  • One-command Helm install — chart image.tag defaults to appVersion, so a released chart pulls matching images with no overrides.
  • BREAKING: CRD API group renamed gameplane.gg → gameplane.local — manifests are now apiVersion: gameplane.local/v1alpha1. Recreate CRDs after upgrading; no v* release ever shipped the .gg group.
  • Operator image now reports its real build version; bundled observability (prometheusRules, grafanaDashboards); signed-module-bundle support (opt-in).

Note: GHCR packages are private on first publish — the maintainer must flip gameplane/{operator,api,agent} + charts/gameplane to public for anonymous installs.