Windows and Linux Unreal Builders
Create replaceable Unreal Engine build workers across Windows and Linux with explicit state, identity, and recovery boundaries.
- Last reviewed
- Version
- 1.0
- Unreal Engine
- Windows
- Linux
- build workers
An Unreal Engine build worker is a controlled execution boundary, not a workstation with a build command added. A dependable worker can be recreated from a declared baseline, receive only the access needed for its assigned work, and leave behind evidence without becoming the only place where a build can succeed.
Define the worker baseline#
Version the worker baseline as an image definition, provisioning script, or configuration contract. State the operating system release, Unreal Engine revision, toolchains, build-agent software, and expected storage locations. Record its revision with the build definition.
Keep source, outputs, caches, and secrets outside the baseline. It should obtain and validate those inputs rather than embed a workspace or long-lived credential. That makes replacement practical and exposes local adjustments.
Assign capabilities instead of assumptions#
Describe workers by capabilities such as packaging, server compilation, cooking, signing, or tests. Build definitions should request them explicitly rather than assume every worker can perform every target. Windows and Linux pools can then share a contract while retaining needed platform tools.
Keep privileged functions narrow. A general compile worker should not inherit packaging credentials merely because another job requires them. If a stage needs a different trust level or an uncommon SDK, make that distinction visible in its worker class.
Handle Windows and Linux differences#
The common baseline should not hide differences that affect correctness. Treat the operating system as a declared build input and test the paths that cross between worker types.
Filesystem behavior#
Windows and Linux differ in case handling, paths, locking, links, permissions, and line endings. Names distinct on one filesystem can collide on another. Validate naming at source intake, use path-safe scripts, and avoid current-directory or drive-specific assumptions.
Cleanup also differs. A process that has exited may still leave locked files on Windows, while Linux permissions can prevent a later identity from removing generated content. Make workspace creation and removal owned by the worker lifecycle rather than by ad hoc cleanup commands in individual jobs.
Toolchains and packaging#
Declare the host operating system for every target and packaging task. Portable source does not make a target portable between workers: compilers, SDKs, shells, executable formats, and packaging utilities may be host-specific.
Build definitions should select the appropriate worker before work begins and fail clearly if no matching capability exists. That is safer than falling back to a nearby machine with an unknown toolchain. Keep environment variables, command shells, and path construction inside a small platform adapter where they can be reviewed and tested.
Process and service behavior#
Run the build agent under a dedicated service identity and define how child processes are started, observed, and terminated. A job cancellation must clean up its process tree and temporary files on both operating systems. Capture logs and exit status before cleanup so a failed task does not become indistinguishable from a worker failure.
Bound identities and secrets#
Separate the worker identity from identities that fetch source, retrieve cache, publish artifacts, or sign outputs. Issue scoped, revocable credentials for the job and exclude them from images, workspaces, command lines, diagnostic bundles, and logs.
Document who can rotate a credential and how a revoked credential affects queued work. Test that rotation on a noncritical path. Licensing material, signing keys, and source-control access deserve separate boundaries because a compromise in one should not automatically grant the others.
Control workspace and cache lifecycle#
Create a known workspace for each job or manage reuse deliberately. Source hydration must identify the exact revision, and cleanup must remove generated state that could affect later work. Reuse is acceptable only when a clean checkout remains supported.
Treat compiler caches and Derived Data Cache as performance layers. Place durable cache storage outside the disposable workspace, give it an owner and eviction policy, and ensure a cache miss produces a slower build rather than a different build. Artifacts belong in immutable storage with a manifest; they should never be recovered from a worker disk.
Prove replacement and recovery#
Exercise replacement before the worker is urgently needed. Remove a worker from service, provision a replacement from the documented baseline, run a clean checkout with an empty cache, and compare its declared inputs and outputs with the expected build record. Then confirm that an older artifact can be located through its manifest without contacting the original worker.
This reveals manually installed tools, local certificates, untracked engine patches, and caches that supply more than derived data. Fix the dependency instead of preserving the failed machine as a special case.
Plan capacity from constrained stages#
Capacity belongs to worker classes, not to a single fleet total. Identify which stages contend for the same compiler, storage path, packaging access, or specialized hardware, then isolate those constraints in scheduling policy. Keep ordinary compilation separate from scarce or privileged work so a routine queue cannot starve release-critical tasks.
Add workers only after the baseline, source access, cache locality, and artifact publication path are repeatable.
Implement in dependency order#
- Write the baseline and capability contract for one worker class.
- Reproduce a known build from a clean worker and declared inputs.
- Separate source workspace, cache, artifacts, and secrets into distinct lifecycles.
- Add the alternate operating system only after its differences are encoded in the build definition.
- Exercise replacement, credential rotation, and artifact recovery.
- Expand capacity by class while preserving the same recovery test.
Practical checklist#
- The worker baseline is versioned and reviewable.
- Build definitions request explicit operating system and capabilities.
- Filesystem, path, permission, and cleanup differences are accounted for.
- Toolchains and packaging utilities are declared for their host worker.
- Worker, source, cache, artifact, and signing identities are separate.
- Secrets are injected at runtime and excluded from logs and workspaces.
- A clean workspace and cold-cache build are supported.
- Artifacts are published outside worker storage with a manifest.
- A replacement worker has been exercised from the documented baseline.
- Capacity changes preserve the same identity and recovery boundaries.