Graph
Terrabuild represents each run as a directed acyclic graph, or DAG. The graph contains the selected targets and every prerequisite Terrabuild must consider before it can run them.
What the graph contains
When you run terrabuild run <target>, Terrabuild analyzes your workspace and builds a graph where:
- Nodes represent tasks, such as the
buildtarget for project A. - Edges represent dependencies between tasks.
- Edges have a direction. A dependent node points to the prerequisite it requires.
- Circular dependency chains are invalid.
Terrabuild uses these relationships to order work and identify independent tasks that can run in parallel. Cache fingerprints determine whether a selected task executes or restores saved output.
How Terrabuild constructs the graph
Graph construction happens before any target command runs:
- Terrabuild reads
WORKSPACEandPROJECTfiles. - It builds the full graph for all configured project targets.
- It selects the requested targets and the dependencies reachable from them.
- It resolves extension commands, cacheability, outputs, hashes, and batch compatibility.
- It assigns each node an action: build, restore, or report a previous failed summary.
- It marks the required nodes and adds any valid batch nodes.
- The runner receives the final graph and starts executing only then.
This means target dependencies, selected project filters, cache status, lazy targets, and batch constraints are all settled before execution begins.
Dependency references are permissive by project:
target.^buildadds thebuildtarget on upstream dependency projects that define it.target.buildadds thebuildtarget on the current project only when that project defines it.
Circular target dependency chains are rejected during graph construction and reported with the cycle path.
How projects become a graph
This example has two applications and one library behind each application. Extensions can discover project dependencies, and a PROJECT file can also declare them explicitly.
The configuration comes from the Terrabuild Playground.
Selecting deploy produces a task graph like this:
Arrows point from a dependent task to the prerequisite it requires. The runner executes prerequisites first.
How changes affect a run
The graph defines which tasks can affect one another. Fingerprints and cache state decide the action assigned to each selected node.
- A forced, non-cacheable, or uncached node executes.
- A node with a successful matching cache entry can restore its outputs.
- A node with a failed cache summary reports that failure unless the run uses
--retry. - When a non-lazy prerequisite executes, Terrabuild also executes the dependent work required by the graph.
Cache reuse depends on declared inputs. Branches and machines can reuse an entry only when they produce the same fingerprint and can access the stored artifacts. See Caching for the inputs and exclusions that matter.