Key Concepts

This section summarizes Terrabuild’s core concepts and terminology. Use this as a reference after you’ve explored the other documentation sections.

Core Terminology

Workspace vs Project

Workspace is the root of your monorepo - the top-level directory containing all your projects. It has a single WORKSPACE file that defines global configuration, default extensions, and workspace-level target dependencies.

Project is a subdirectory within the workspace that contains a PROJECT file. Each project represents a buildable unit (an application, library, or service) with its own configuration, dependencies, and targets.

workspace/
├── WORKSPACE          # Global configuration
├── project-a/
│   └── PROJECT        # Project-specific configuration
└── project-b/
    └── PROJECT

Target vs Task vs Node

  • Target - A named build goal (e.g., build, test, dist) defined in configuration files. Specifies what to build and dependencies.

  • Task - A concrete execution instance: “build target X for project Y”. Created when you run a target.

  • Node - A task represented in the build graph. Nodes enable dependency resolution and parallel execution.

Relationship: Target (what to build) → Task (execution instance) → Node (graph representation)

Extension vs Action vs Command

  • Extension - A plugin providing build capabilities (e.g., @dotnet, @npm, @docker). Configured in WORKSPACE or PROJECT files.

  • Action - An operation provided by an extension (e.g., build, test, publish).

  • Command - Invoking an action within a target: @extension action { arguments }.

Dependency Types

Terrabuild handles two types of dependencies:

  1. Project Dependencies - Declared in the project block using dependencies = [ "../other-project" ]. These represent build-time dependencies where one project needs another project’s outputs.

  2. Target Dependencies - Declared in target blocks using depends_on = [ target.^build ]. These control the execution order of targets. See Dependency Resolution below.

Cluster

A cluster is a group of compatible targets built together in a batch operation. This enables compiler-level optimizations (like building multiple .NET projects in one solution build) without maintaining solution files. See Batch Builds for details.

Key Concepts

Build Graph (DAG)

Terrabuild uses a Directed Acyclic Graph (DAG) to represent the build. Nodes are tasks, edges are dependencies. This structure enables Terrabuild to determine what needs building, identify parallel execution opportunities, and detect dependency cycles. See Graph for examples and details.

Cache Key Generation

Each task has a unique cache key computed from project files, dependencies, commands, and variables. This creates a Merkle tree structure where any change triggers a new hash. Cache keys are deterministic and branch-agnostic (unless using commit-specific variables), enabling cache reuse across branches.

Dependency Resolution

Terrabuild uses special syntax to express target dependencies:

  • target.^build - Ancestor dependency. This means “ensure the build target is completed for ALL dependency projects before building this target”. The ^ symbol indicates “ancestor” or “upstream” dependencies.

  • target.build - Current project dependency. This means “ensure the build target is completed for the current project before building this target”.

Example:

# In WORKSPACE
target build {
    depends_on = [ target.^build ]  # All dependency projects must build first
}

target dist {
    depends_on = [ target.build ]  # Current project's build must complete first
}

If Project A depends on Projects B and C:

  • When building Project A’s build target, Terrabuild ensures Projects B and C’s build targets complete first
  • When building Project A’s dist target, Terrabuild ensures Project A’s build target completes first

See Workspace Target Block for more details.

Change Detection

Terrabuild detects changes through file hashing (not file watching). Files are hashed based on includes/ignores patterns, and changes are detected by comparing current hash to cached hash. This approach works across branches and is deterministic.

Build vs Restore

For each task, Terrabuild decides whether to Build (execute commands) or Restore (recover from cache). The decision considers: force flag, cache availability, dependency changes, and retry status. See Tasks for the decision tree.

Syntax Patterns

Target Dependency Syntax

  • target.^build - All dependency projects’ build target must complete
  • target.build - Current project’s build target must complete
  • target.^dist - All dependency projects’ dist target must complete

Rebuild Modes

  • ~auto - Rebuild when changes detected (default)
  • ~always - Always rebuild, ignore cache
  • ~cascade - Rebuild with parent within a cluster (for batch builds)

Artifact Cacheability

  • ~none - Do not cache artifacts
  • ~workspace - Cache in workspace-local cache
  • ~managed - Cache in managed cache (Insights backend)
  • ~external - Cache externally

Extension Identifiers

Extensions are identified with @ prefix:

  • @dotnet - .NET build extension
  • @npm - npm/Node.js extension
  • @docker - Docker extension
  • @terraform - Terraform extension

Custom extensions can be defined using F# scripts. See Extensibility for details.

Last updated on