CI/CD builds

Your game, built on every push.

Fresh machines born in seconds, presets that speak Unreal, and caches that keep steady-state builds warm. Push, and a playable build comes out the other side.

neostack.dev/main-inc/mygame/builds/47
~4.5 minwarm push → playable build
6.8 vs 21.8minutes, warm vs cold run
faster cooks with warm DDC
14 sfrom VM requested to runner online
01

Workflows you already know how to write

A YAML file in your repo, the expression grammar you use today, and machines tuned for game builds. If you can write a GitHub Actions workflow, you already know NeoStack — or skip the file entirely and author workflows in the UI.

    # .neostack/workflows/build.yml
    name: Build
    on:
      push:
        branches: [main]
      workflow_dispatch:
        inputs:
          config:
            type: choice
            options: [Development, Shipping]
    concurrency:
      group: build-${{ github.ref }}
      cancel-in-progress: true
    jobs:
      build:
        runs-on: [linux]
        strategy:
          matrix:
            platform: [Win64, Linux]
        steps:
          - uses: neostack/checkout@v1
          - uses: unreal/compile@v1
            with:
              platform: ${{ matrix.platform }}
      package:
        needs: build
        runs-on: [linux]
        steps:
          - uses: unreal/package@v1
    02

    The grammar, all of it

    This isn’t a YAML-shaped subset. The needs DAG, matrix fan-out, expressions, secrets, schedules, and concurrency groups all behave the way your muscle memory expects.

    • Push triggers + manual dispatch with typed inputs
    • strategy.matrix fan-out across parallel machines
    • needs DAG with job outputs flowing between jobs
    • ${{ }} expressions — evaluated by the same grammar GitHub uses
    • Secrets encrypted at rest, masked in logs (base64 tricks included)
    • Cron schedules, concurrency groups, re-run failed, step-level if
    03

    A fresh machine for every job

    No shared runners marinating in last week’s state. Each job gets a machine born for it — it boots, claims the job, streams every step live, uploads artifacts, and disappears.

    • VM born in ~14 s; boot → claim in about a minute on the custom image
    • Live per-step logs, plus the machine’s whole life on a timeline
    • On any Unreal step failure, the editor log tail is surfaced right in the run
    • Artifacts with 30-day retention, downloadable straight from the run page
    04

    Presets that speak Unreal

    Compiling and cooking an Unreal project is its own discipline. The unreal/* presets encode it, so your workflow says what you mean and the machine does the rest.

    • unreal/compile — UnrealBuildTool against a real baked engine
    • unreal/package — BuildCookRun in, playable archived build out
    • unreal/test — headless Automation tests with a DDC shader-prewarm first
    • unreal/buildgraph — one push explodes into parallel jobs across VMs
    05

    Warm where it counts

    Cold Unreal builds are brutal, so the platform hoards heat. Engines are baked into reusable images, shaders cook once per org, and each build lane keeps a workspace disk so compiles stay incremental.

    • Self-serve engine bakes — need a new UE version? It’s cached for your org
    • Per-org Zen DDC: 256 GB of shared cook cache that sleeps when idle
    • Workspace disks: 5,728 compile actions cold became 3 warm
    • “Re-run without cache” escape hatch when you want a clean room