-
Notifications
You must be signed in to change notification settings - Fork 0
How Phases and Scopes Work
A phase is a string label for a pipeline stage. A scope is a string label for a variant within that stage.
Beez treats both as opaque text. There is no built-in list like configure or test. You define meaning in your build.lua.
phase "build" + scope "default" -> selects steps tagged build:default
phase "build" + scope "debug" -> selects steps tagged build:debug
Both fields are required on every step():
step({
name = "compile",
phase = "build",
scope = "default",
run = "...",
})If either is missing, build.lua fails to load.
When Beez runs a phase+scope pair (P, S), it collects every registered step where:
step.phase == P AND step.scope == S
No other fields are considered for selection. In particular:
- Step
nameis not part of the selector -
input/output/mutateglobs do not define scope - Tasks and workflows do not auto-infer scope from file paths
Many steps can share the same phase and scope. They all run when that pair is invoked.
step({ name = "compile", phase = "build", scope = "default", run = "..." })
step({ name = "link", phase = "build", scope = "default", run = "..." })Both run for build:default. See Parallel Execution and Dependencies for ordering.
Step name must be unique in the registry. Phase and scope do not namespace names.
-- Valid: different names, same phase+scope
step({ name = "compile:release", phase = "build", scope = "default", ... })
step({ name = "link:release", phase = "build", scope = "default", ... })
-- Invalid: duplicate name (second registration replaces first)
step({ name = "compile", phase = "build", scope = "default", ... })
step({ name = "compile", phase = "test", scope = "unit", ... }) -- overwritesUse distinct names like build:compile and test:compile if that helps clarity. order() references name, not phase:scope.
For one invocation of (phase, scope):
- Collect all matching steps
-
Order into levels using
order()hints andmutateoverlap rules -
Execute each level (parallel within a level unless
-j 1) -
Flush buffered cache writes for this phase+scope (when
cache_write_strategy = "phase")
If no steps match, Beez succeeds immediately with nothing to do.
When multiple scopes are requested (for example beez -p test:unit,integration), Beez runs each scope completely before starting the next. Scopes are not parallel with each other unless you use a workflow parallel block.
| Invocation | Scope behavior |
|---|---|
beez -p build |
All scopes for build, alphabetically sorted, sequential |
beez -p build:debug,release |
debug then release, in listed order |
| Workflow sequential step | One pair per workflow step |
Workflow parallel block |
Multiple pairs at once |
Scope does not mean "which directories this step owns."
| Concern | Belongs on |
|---|---|
| Which files a step reads/writes |
input, output, mutate on the step |
| Which steps run together |
phase and scope
|
| Run order inside a group |
order(), mutate inference |
Two steps in qa:default may touch completely different paths.
Phases and scopes exist because steps declare them. Beez does not register empty phases.
beez --list phases # phases derived from steps
beez --list steps # shows Name, Phase, Scope columnsA workflow can reference a phase+scope pair that has no steps yet. That workflow step becomes a no-op until you add matching steps.
Step cache index files include phase and scope in the filename:
.cache/index/<name>__<phase>__<scope>.index
Success cache misses files use the same pattern under .cache/success/misses/.
Run logs may show segments like build:default when executing a phase+scope block.
| Action | Behavior |
|---|---|
beez -s compile |
Runs step compile regardless of phase/scope |
beez my-task with { name = "compile" }
|
Runs that step by name |
| Shell task string | No steps involved |
Workflows and -p are the main ways to run by phase+scope.
build.lua
steps (each has phase + scope + name)
|
v
registry: group by (phase, scope)
|
+-- workflow / -p -> pick pairs -> run matching steps
+-- -s / task -> pick by step name directly
- Selecting with Phases and Scopes - workflows and CLI syntax
- Designing Phases and Scopes - how to name and structure pairs
- Order Declaration - dependencies between steps in the same pair
Quick Reference · Glossary · FAQ
- Fundamentals
- Core Concepts
- Project Layout
- First Pipeline
- Phases and Scopes
- How Phases and Scopes Work
- Selecting with Phases and Scopes
- Designing Phases and Scopes
- Parallel Execution and Dependencies
- Configuration
- Configuration Overview
- Global User Config
- Project Config
- Environment Variables
- Performance Settings
- Cache Settings
- Config Reference
- CLI
- CLI Overview
- Running Targets
- Filtering by Phase
- Running a Single Step
- Listing Entities
- Output and Logging Flags
- Cache and Maintenance Flags
- Meta and Utility Commands
-
Project Scaffolding —
beez --init(embedded Tempify) - CLI Flag Reference
- Lua DSL
- DSL Overview
- Plugin System — Plugins, Config DSL, Standard-Workflows
- Step Declaration
- Task Declaration
- Workflow Declaration
- Order Declaration
- Configure Step
- ReqPack Declaration
- Beez API
- Step Context
- DSL Patterns
- Caching
- Caching Overview
- Step Cache
- Success Cache
- Glob Metadata Cache
- Artifact Patterns
- Cache Keys and Invalidation
- Cache Storage and Maintenance
- Caching Troubleshooting
- UI and Output
- Output Modes
- Progress and Animation
- Colors and Themes
- Run Summaries
- Logging and Log Files
- Development and Contribution
- Building and Setup
- Repository Layout
- Testing
- Code Quality
- Feature Development Workflow
- Submitting Changes