dependencies in each project.json.
The same selection powers local
execution, JSON project lists, and weighted GitHub Actions matrices.
Local commands
affected --print-matrix prints only a sorted JSON array, such as ["api","shared"].
plan prints { "include": [...] } for a full GitHub matrix. Both keep diagnostics
on stderr, even with --verbose. Empty selections produce [] or
{"include":[]} respectively and exit successfully.
Without --print-matrix, affected executes the selected command. run-many
defaults to all projects that have the requested command. For an exact selection,
use --projects-json='["api","shared"]': every project and command must exist, and
the list is neither filtered nor redistributed. An empty JSON list runs nothing.
--config, --configuration, -c, and --prod have the same meaning as for a
single project. --parallel defaults to 1 and limits concurrent child CLI
processes. Each child has its own cwd, environment, and module state. The first
failure cancels active children and stops queued work; SIGINT/SIGTERM propagate
to the children and return exit codes 130/143.
What counts as affected?
- Committed changes are
git diff <merge-base(base, head)> <head>. Defaults areISOX_BASE, thenaffected.defaultBaseinisox.json, thenorigin/mainfor the base;ISOX_HEADorHEADfor the head. Use--baseand--headto override them. Isox uses the currently checked-out project definitions. - Staged and unstaged files are included only with
--uncommitted; non-ignored untracked files only with--untracked.--allbypasses Git and cannot be combined with Git selection flags. The actions compare committed changes only. - Each changed file belongs to the most specific project root, using directory boundaries. Renames include both paths and deleted files still count. Changes outside a nested Isox workspace are ignored.
- Changes to root manifests, lockfiles,
isox.json, roottsconfig*.json,eslint.config.*, or.github/**affect every project, even with a root project. Other files, including paths outside project roots, select targets whose inputs consume them. Add shared scripts toaffected.globalFileswhen their changes should affect every project regardless of inputs. affected.ignoreFilesexcludes matching files before checking global patterns or target inputs and project ownership. Ignored changes do not select projects or their dependents.- Targets without explicit inputs or a customized
defaultnamed set retain conservative selection: file owners and all transitive dependents are included before command and tag filtering. On-demand analysis combines source imports, TypeScript aliases, local package references, and explicitly declared project dependencies. Type-only imports and tests count. Dynamically selected plugins need explicit dependencies; executor selections alone do not add edges. Unknown references and cycles fail with an explanation. See dependency discovery. - Projects without the requested command, with
plan.enabled: false, or taggedci=offare excluded from selection. Explicitrun-many --projects-jsonruns exactly its list, including projects excluded from automatic selection.
Target inputs and prerequisites
affected and each target in plan use the same resolved file inputs as task
caching, even when cache is false. Target defaults apply first; target-level
inputs replace inherited arrays. Named sets can nest, project sets override
workspace sets, and exclusions win within each selection. Shared workspace paths
select every consuming target, regardless of file ownership. Deleted paths and
both rename paths are matched without requiring the files to exist.
For example, code targets can use inputs: ["production", "^production"] with
production: ["{projectRoot}/**/*", "!{projectRoot}/**/*.md"]. A website target
can instead include "{workspaceRoot}/packages/**/*.md". No Markdown files are
excluded by default.
Without a ^ input, dependency inputs come from each dependency’s same-named
target (or its default set when that target is absent). ^production replaces
that automatic source selection and resolves the set in every transitive
dependency. Separate dependency branches retain independent exclusions.
Project definitions, package manifests and cached dependency outputs remain
automatic inputs even with inputs: []. Built-in and configured global files
still select all eligible projects; affected.ignoreFiles takes precedence.
Environment values, installed tool versions and runtime changes have no Git path;
use --all when those changes need validation.
Pre/post stages and dependsOn prerequisites also participate: a matching
prerequisite selects its consuming project. Once selected, execution schedules
all required prerequisites, including projects excluded from automatic selection.
Input exclusions do not remove required tasks from that schedule. Circular named-input
references, unknown dependency ^ sets, and invalid task graphs fail with an
explanation rather than silently skipping work. Other unrecognized input strings
are treated as workspace-relative file patterns, so a typo may match no files.
Exclude a project from automatic selection
Setplan.enabled to false in project.json to exclude it from affected,
plan (including --all), and ordinary run-many selection:
true. Direct commands such as isox test tools and exact
--projects-json lists can still run the project. The existing ci=off tag also
excludes projects for backward compatibility, even with plan.enabled: true.
This is a selection filter. The project remains in the dependency graph, and its
changes still propagate to dependents. It cannot hide a cycle. To skip only one
target, leave that target undefined on the project instead.
Shared and ignored files
For shared tools inside a project, add workspace-relative globs toisox.json:
ignoreFiles also uses workspace-relative globs and defaults to an empty list.
It takes precedence over both built-in global files and globalFiles.
Only exclude files whose changes do not need to trigger your targets; for example,
omit the Markdown exclusions above if your documentation needs building or testing.
Projects can still be selected through other changed files or dependencies.
Affected selection, planning and run-many scan current project.json files and
refresh workspace.json. They do not require isox reset after project
changes. Single-project commands reuse cached definitions until reset or an
explicit refresh. Affected selection validates and reuses per-project dependency
entries from .isox/discovery.json, computing missing or invalid analysis before
finding dependents. The sources SHA uses source paths and metadata; a changed
project is reanalyzed as a whole, including tests. --all and run-many selection
do not request dependency inference. Execution additionally resolves
dependencies when selected targets cache outputs, so selected dependencies finish
before their consumers. Executors can also request analysis.
Every run-many invocation refreshes definitions; its child commands then load
that definitions cache. These caches do not transfer build outputs between CI
jobs or skip task execution. See cache behavior.
Missing revisions or incomplete history are errors with fetch guidance; Isox
does not turn a Git failure into a successful empty plan.