Skip to content

Task Declaration

Leonard Ramminger edited this page Aug 14, 2026 · 2 revisions

Task Declaration

Tasks are named shortcuts invoked with beez <taskname>. Two forms exist.

See also: Plugin System for importing tasks from plugins and step[scope] / phase[scope] syntax.

Shell task

task("hello", "echo hello > hello.out")

Runs one shell command. Equivalent to a single-action task list.

Task with multiple actions

task("check", {
    "echo starting",
    { name = "compile" },
    { name = "test:unit" },
    "echo done",
})

Actions run sequentially in list order (integer keys 1, 2, 3, ...).

Action types

Entry Type Behavior
"shell command" string Run shell command
{ name = "step-name" } table Run registered step by name
{ name = "...", config = { ... } } table Run step with config overlay
{ plugin = "org/plugin", step = "name[scope]" } table Run a plugin step (scoped)
{ phase = "compile[app]" } table Run all steps in phase+scope
{ task = "other" } table Invoke another task

Plugin step references

task("debug", {
    { plugin = "coditary/conan", step = "configure[debug]" },
    { plugin = "coditary/clang-build", step = "compile[debug]" },
})

Import a task exported by a plugin:

task("coditary/demo:format")                    -- shorthand
task("alias", { plugin = "coditary/demo", task = "format" })  -- alias

The deprecated scope field on task actions is rejected; use bracket syntax instead.

Step invocation with config

Config from the task merges over the step's existing config (inline config field and configure_step()):

configure_step("compile", { flags = "-O2" })

step({
    name = "compile",
    phase = "build",
    scope = "default",
    run = "make",
})

task("release", {
    { name = "compile", config = { flags = "-O3" } },
})

Task overlay wins for duplicate keys.

Validation rules

  • Task list must be non-empty
  • List entries must be strings or step invocation tables
  • Step invocation must have name (string)
  • Optional config must be a table
  • Tables that look like step definitions (phase, scope, run without list form) are rejected

Invalid example (fails at load):

task("broken", { phase = "build", scope = "x", run = "true" })

Tasks vs workflows

Task Workflow
Invoked as beez taskname beez workflowname
Runs Shell strings and/or steps in order Phase+scope pairs
Parallelism None (strictly sequential) Workflow parallel groups
Typical use Shortcuts, one-off chains Full pipelines

Tasks vs steps

Tasks reference steps by name; they do not define new steps. The step must already be registered (usually earlier in the same build.lua).

Name collision with workflows

If a task and workflow share the same name, the task wins when you run beez <name>.

Examples

Cleanup:

task("clean", "rm -rf build .cache")

Format then lint:

task("fix", {
    { name = "format" },
    { name = "lint" },
})

Ad-hoc shell + step mix:

task("quick-test", {
    "cmake --build build",
    { name = "test:unit" },
})

Next steps

Clone this wiki locally