Skip to content

M3.4 — Builds and build sources

What you'll learn

  • The build interfaces — IBuildSource, IBuild, and the Unreal-specific UnrealBuildSource.
  • Staged vs. packaged builds, and why Gauntlet needs one of them pre-made.
  • How "build not found" failures actually arise, and how to pin down the build you tested.

How it applies (QA)

Every result is only as meaningful as the build it ran against. "We tested CL 48211" must mean a specific cooked artifact for a specific platform/configuration — not "the project at that CL." Build provenance is the difference between a reproducible result and a rumor.

Concepts

IBuildSource, IBuild, UnrealBuildSource

  • IBuild (tier 1) — one specific build: a platform, a configuration, and the files that make it up.
  • IBuildSource (tier 1) — where builds come from: something that can discover and enumerate IBuilds.
  • UnrealBuildSource (tier 3) — the Unreal-aware IBuildSource. It knows how Unreal lays out cooked builds and resolves your -build/-platform/-configuration into a concrete IBuild.

When RunUnreal starts, UnrealBuildSource is what turns "I want the PS5 Test build at this path" into the actual artifact a device will install.

Gauntlet does not cook — restating the boundary with teeth

From M1.1: Gauntlet consumes builds, it does not create them. Concretely, before Gauntlet runs, something upstream must have:

  1. Compiled the game/server target for the platform/configuration ([UBT]).
  2. Cooked the content for that platform (editor assets → runtime format).
  3. Staged or packaged the result into a runnable layout.

Usually steps 1–3 are a BuildCookRun invocation or a BuildGraph node. Gauntlet starts at step 4: take that artifact and run it. If steps 1–3 didn't happen (or produced a different platform/configuration than you asked for), UnrealBuildSource finds nothing and you get "build not found" — an upstream failure surfaced at Gauntlet's door.

Staged vs. packaged

Two shapes of "runnable build":

A loose-file cooked build laid out in the platform's runtime directory structure — the files sit on disk ready to launch, not wrapped. Fast to produce and to iterate; common for development and CI. Often what -build=local / a staged path points at.

A wrapped/installable artifact — a .pak-backed package, an .apk (Android), a console package, etc. Closer to what ships and to what cert checks; required for some platforms and for install/PLM-accurate testing. Slower to produce.

Which you test changes what you can catch: a staging-only test won't surface a packaging/install bug that only a packaged build exhibits, and vice-versa. Record which shape you ran.

Pitfall: 'tested CL 48211' is not provenance

A result is reproducible only if you can name the platform + configuration + build shape + build location/id, not just the changelist. "Passed at 48211" that ran a staged Development Win64 build says nothing about the packaged Shipping PS5 build cert will use. Always log the full build identity next to the verdict.

Worked example — anatomy of "build not found"

RunUAT.bat RunUnreal -test=UE.BootTest -project=ShooterGame -platform=PS5 -configuration=Shipping -build=\\builds\ShooterGame\CL-48211\PS5
...
LogGauntlet: Error: UnrealBuildSource found no build matching platform=PS5 configuration=Shipping at \\builds\ShooterGame\CL-48211\PS5

Diagnose with the boundary: UnrealBuildSource looked where you pointed and found no PS5/Shipping IBuild. Most likely causes, in order:

  1. The pipeline cooked PS5 Test, not Shipping (configuration mismatch).
  2. PS5 wasn't cooked for CL 48211 at all (the platform was skipped/failed upstream).
  3. The path is right but the stage step failed, leaving the directory incomplete.

None of these is a test bug. The fix is upstream (cook the right configuration) or in the command (point at the configuration that exists).

Exercise 1 — Place the build classes

Match each to its description: IBuild, IBuildSource, UnrealBuildSource.

a. Knows Unreal's cooked-build layout and resolves -build/-platform/-configuration. b. One specific build (platform + configuration + files). c. The general abstraction for "where builds come from."

Exercise 2 — Write the provenance line

A boot test passed. Write the single provenance line you'd attach to the result so another tester could reproduce it exactly. Include every field that matters.

Lab — Trace a red nightly to a root layer

A nightly PS5 Shipping job is red. You have: the command line, a UnrealBuildSource "no build matching" error, and a green Win64 Development job for the same CL. In 4–5 steps, write the triage that ends at a single root cause and a concrete next action — and explicitly rule out "the test is broken."

Self-check — answers

Exercise 1: a → UnrealBuildSource, b → IBuild, c → IBuildSource.

Exercise 2 (example): ShooterGame · platform=PS5 · configuration=Test · staged · \\builds\ShooterGame\CL-48211\PS5 · UE 5.x. Project, platform, configuration, build shape, location/id, engine version — anything less is not reproducible.

Lab (example): (1) Error is from UnrealBuildSource → pre-launch, build resolution, not test logic. (2) Same-CL Win64 Development is green → the code/content at this CL is fine and the test runs; the problem is specific to PS5 Shipping. (3) Therefore suspect the upstream cook/stage for PS5 Shipping (did it run? did it produce Shipping or only Test? did staging complete?). (4) Check the pipeline's PS5 Shipping cook/stage step for this CL. (5) Root cause likely: that artifact was never produced (or wrong configuration); next action — fix/trigger the PS5 Shipping cook, not the Gauntlet test. The test is exonerated by the green Win64 run.

Done when

  • [ ] You can place IBuild, IBuildSource, and UnrealBuildSource in tiers and roles.
  • [ ] You can list the upstream steps (compile → cook → stage/package) Gauntlet depends on.
  • [ ] You can distinguish staged from packaged and what each shape can catch.
  • [ ] You can read "build not found" as an upstream/command problem and write build provenance.

Next: M4.1 — Project setup & the test node.