Runners
How ci-parity reads each task runner’s files statically, and how calls to each runner are parsed.
Taskfile
Section titled “Taskfile”Static parsing of Taskfile v3 (a missing version is treated as 3; any other version
exits 2). Collect:
- Task names from
tasks, plus every entry of each task’saliases. internal: trueper task.includes: a string value is a path to a Taskfile or to a directory (the first of the root discovery names found there); a map value supportstaskfile,dir,optional,internal,aliases,flatten. Included tasks are named<namespace>:<task>(also under each alias namespace), or unprefixed whenflatten: true.internal: trueon an include marks all its tasks internal. Resolve relative to the including file’s directory, cap recursion at depth 10, ignore cycles. A missing include is a parse error (exit 2) unlessoptional: true. An include path holding a template ({{OS}}) is treated as missing.- An included Taskfile with a
defaulttask also makes the bare namespace a valid name. - File names are matched exactly against the directory listing.
- Each task’s command strings for suggestion matching:
cmd:on the task, string entries ofcmds, andcmd:map entries ofcmds. Ignoretask:,for:anddefer:entries.
Make, just and mise
Section titled “Make, just and mise”runner selects taskfile, make, just or mise. Each has a reader behind the same
interface and its own call syntax; the rules are unchanged.
- Discovery: the root file is found in the repository root, names matched exactly.
make:
GNUmakefile,makefile,Makefile. just:justfile,Justfile,.justfile. mise: every one of.config/mise/config.toml,.config/mise.toml,mise/config.toml,.mise/config.toml,mise.tomland.mise.tomlthat exists, read in that order, a later file’s task replacing an earlier one’s; messages name the last one found. Thetaskfilekey is only forrunner: taskfile; set with another runner it is a config error. A missing root file exits 2. - Defaults by runner:
invokers.shellis[make, gmake],[just]or["mise run", "mise r", "mise tasks run"], andinvokers.actionsis empty, unless the config sets them. Unlesstools.replaceis set, the configured runner’s commands leave the tools list and the other runners’ are on it, includingtaskandgo-task. - make: a target is a rule line outside a recipe; special targets (
.PHONY), pattern rules (%), variable assignments (including target-specific ones),defineblocks and names holding$define none.include,-includeandsincludeof literal paths, resolved from the repository root, are followed to depth 10; a missing file is skipped, as make may generate it. Recipe lines, without leading@,-or+and with whitespace collapsed, are a target’s commands. No target is internal. In a call,-f,--file,--makefile,-Cand--directory(in any form) select another makefile and the call is ignored;-I --include-dir -o --old-file --assume-old -W --what-if --new-file --assume-newtake a value;-j --jobs -l --load-average --max-loadtake the next argument only when it is a number;NAME=valueis a variable; a call naming no target runs the default goal and is ignored. - just: recipes, their parameters,
alias a := b,importof literal paths andmod(recipes namedmod::recipe, fromname.just,name/mod.just,name/justfileor a given path). A recipe is internal when it is[private]or its name starts with_. Body lines without leading@or-are its commands. In a call, the words after a recipe are its arguments, as many as its parameters take (all the rest for a variadic one);just mod recipeandjust mod::recipeboth name a module recipe.-f,--justfile,-dand--working-directoryselect another justfile;--settakes two values. - mise:
[tasks.name]tables andname = "cmd"(or list) entries, withrun(string or list) as the commands,alias(string or list) as aliases andhide = trueas internal; file tasks under.config/mise/tasks/,mise/tasks/,.mise/tasks/,mise-tasks/and.mise-tasks/(named from the path,db/migrateasdb:migrate, hidden by a#MISE hide=trueline, with no commands), where a file is a task when it is executable or starts with a#!or#MISEline, so Windows checkouts, which have no executable bit, find the same tasks; andtask_config.includes, each a task TOML file whose top-level tables are tasks or a directory of file tasks, a missing one skipped. A call names one task, then its arguments;:::starts another task.-Cand--cdselect another directory; a task name holding a glob (lint:*) is not checked;-j --jobs -E --env -t --tool --timeout -o --output -s --shelltake a value.
Where tasks run
Section titled “Where tasks run”P001 suggests a task only when it runs in the step’s working directory and calling the runner from there reads the same root file (rules). Paths are repo-relative; anything templated is unknown, and an unknown directory never matches.
| Runner | A task runs in | Called from a step’s directory, reads the root file when |
|---|---|---|
| Taskfile | The root Taskfile’s directory. An include’s dir:, relative to the including file, moves its tasks; without one they run where the including file’s tasks do. A task’s own dir: is relative to that. |
Neither that directory nor one between it and the root Taskfile’s holds a Taskfile, which task would find first |
| make | The repository root | It is the root: make reads only the Makefile where it starts |
| just | The root justfile’s directory; a module’s recipes run in the module file’s directory, and imported recipes where the importing file’s do. Unknown under [no-cd], [working-directory] or set working-directory. |
Neither that directory nor one between it and the root holds a justfile |
| mise | The repository root, or the task’s dir, relative to the root |
Always: mise reads every parent directory’s config |
See also
Section titled “See also”Last reviewed: 2026-10-28