Release Notes
🚀 Updates
- Action pipeline
- Improved the performance of the action pipeline's job dispatcher by 10-15x. Dependency
relationships are now extracted from the action graph once up front, and completed jobs unblock
their dependents incrementally, instead of re-traversing the graph for every dispatch check. - Changed persistent tasks to run when they are processed in the action graph, instead of being
batched and ran last, in parallel, once all other actions have finished. Persistent tasks now
run alongside other tasks, and a persistent task no longer blocks the persistent tasks that
depend on it. Non-persistent tasks are still not allowed to depend on persistent tasks, unless
they only wait for them to start, with the newwaitdependency type. - Interactive tasks now only block the pipeline until they have completed themselves, instead of
until every task that was already running has completed. - Removed the action graph's "transitive reduction", which never removed any edges, as it started
from the workspace sync action, which has no dependencies to walk. Edges that are implied by a
longer path don't change the order that actions run in.
- Improved the performance of the action pipeline's job dispatcher by 10-15x. Dependency
- CLI
- Added OpenTelemetry metrics for the action pipeline, which are exported when
--otel(or
MOON_OTEL) is enabled.- Records
moon.task.runsandmoon.task.durationfor every task that runs, labeled with the
target, project, task, toolchains, status, and flakiness. - Records
moon.action.executionsandmoon.action.durationfor every action that runs,
labeled with the target, project, or toolchain that it operated on. - Records
moon.operation.executionsandmoon.operation.durationfor every operation within
those actions, labeled with the operation type, status, and plugin.
- Records
- Added a new
--output-styleoption tomoon run,moon ci,moon check, andmoon exec,
which controls how output is displayed for all tasks, overriding theiroptions.outputStyle.
Since it is requested explicitly, it also applies to primary targets. For example,
moon ci :test --output-style buffer-only-failurekeeps passing tasks quiet and prints the full
output of failing ones. - Updated the MCP server (
moon mcp) to the stateless MCP2026-07-28protocol. Clients must
support this protocol version, as older versions (2025-11-25and below) and theinitialize
handshake are no longer supported.
- Added OpenTelemetry metrics for the action pipeline, which are exported when
- Cache
- Hash manifests are now stored as blobs in the local content-addressable cache, instead of as
individual files in.moon/cache/hashes. The local cache backend is now always enabled, as it
backs these manifests; storing task outputs in it remains gated by thecas_outputs_cache
experiment. Blobs that no task manifest references (like hash manifests) are now garbage
collected once older than the cache lifetime, instead of after an hour, while blobs of evicted
task manifests are still removed after an hour. - Added request retries to the HTTP remote cache, which retries a request that failed with a
transient error (connection failure, timeout,5xx,408, or429response) with exponential
backoff. Previously, a single failed blob download would fail the task with
task_runner::missing_outputs(#2680).- Added a new
remote.cache.retryCountsetting, which defaults to3, and can be set to0to
disable retries. Can also be set with theMOON_REMOTE_CACHE_RETRY_COUNTenvironment
variable. - The HTTP remote cache is now disabled when its host is unreachable while connecting, instead
of every request failing, as each request would have exhausted its retries.
- Added a new
- Hash manifests are now stored as blobs in the local content-addressable cache, instead of as
- Configuration
- Added Pkl modules for every configuration file, which are generated to
.moon/cache/schemas/pkl
whenpklis installed. A.pklconfig that amends (or extends) its module is type checked by
Pkl itself, and editors with Pkl support provide completion and documentation for each setting. - Added an
argssetting to toolchainbinsentries, which passes additional arguments to the
install command, like feature flags (--no-default-features --features postgres). Support is
dependent on each toolchain plugin (#2708).
- Added Pkl modules for every configuration file, which are generated to
- Experiments
- Added a new
experiments.explicitTaskOutputStylesetting, which applies a task's
options.outputStyleto all targets, instead of only transitive (non-primary) ones. Can also be
enabled with theMOON_EXPERIMENT_EXPLICIT_TASK_OUTPUT_STYLEenvironment variable.
- Added a new
- Tasks
- Added a new
typesetting to taskdeps, which controls when a dependency runs in relation to
the task. Supports the following values:required(default) - Runs before the task, and must complete successfully.cleanup- Runs after the task has ran its command, even when the task fails, or the failure
aborts the pipeline. Useful for tearing down resources, like stopping a database. It's skipped
when there's nothing to clean up (the task was skipped, or hydrated from the cache, without
having started awaitdependency).wait- Runs before the task, but the task only waits for it to start running, not to
complete. Useful for long-running dependencies, like a development server, and allows
non-persistent tasks to depend on persistent tasks.- Since
cleanupandwaitdependencies don't complete before the task runs, they don't
contribute to the task's hash, and they always run their command, instead of being hydrated
from the cache.
- Changed
runDepsInParallel(when disabled) to skip persistent dependencies when ordering the
dependencies that follow them, as a persistent dependency never completes. Those dependencies
are now ordered against the previous dependency that does complete. - Added a new
options.expectFailuretask setting, which expects the task to fail, and fails the
pipeline if it passes instead, with an error to remove the setting. Useful for checks that are
known to be broken, like after enabling a stricter compiler or lint rule during a migration, so
that future regressions are caught once fixed (#2536).- Unlike
allowFailure, other tasks can depend on the task, as an expected failure is
successful. - Exit codes
126(command not executable),127(command not found), and129-192(killed
by a signal) don't satisfy the expectation, nor do timeouts or signals. - The task is never cached, and is not retried after failing as expected, or passing.
- Cannot be combined with
allowFailureorpersistent.
- Unlike
- Added a new
options.envOverridetask setting, which allows the task'senv(anddeps.*.env)
to override system environment variables (those set in the shell or CI), instead of only being
set when missing. Supportstruefor all variables, or a list of variable names, like
['NODE_ENV', 'TZ'].PATHandenvFilevariables are never overridden (#2679).
- Added a new
- Toolchains
- Added support for the proto
activate_environmentplugin function to toolchains. When building
a command (for tasks and toolchain operations), the environment of each toolchain that has been
setup is now activated, which may set environment variables (likeJAVA_HOMEfor Java) and
prepend paths toPATH. Variables that are already configured, like a task'senv, are not
overridden, and the first toolchain configured for a task takes precedence (#2568).
- Added support for the proto
🧰 Toolchains
- Deno, Go, Rust
- Added
bins.*.argssupport, which are custom arguments passed their respective install command.
Bins with args are installed in separate commands.
- Added
🐞 Fixes
- Fixed an issue where a task dependency's
env(deps.*.env) would override system environment
variables, instead of only being set when missing, like the task'senv. - Fixed an issue where a task's resolved
toolchainslist was ordered by an internal hash set,
instead of by what was configured. The toolchains configured for a task (or inherited from the
project) now come first, followed by any toolchains they require. This also fixes the
$taskToolchaintoken, which would expand to a required toolchain (likenpm) instead of the
configured one (likenode), and makes theappend/prependmerge strategies apply to
toolchains as they do to other task fields. Since this list is part of a task's hash, existing
caches will be invalidated once. - Fixed an issue where a task's
options.outputStylewas applied to primary targets (those
explicitly requested on the command line) when running in CI, or when the task was hydrated from
the cache. Primary targets now always display their output, as documented, unless the
explicitTaskOutputStyleexperiment is enabled. - Fixed an issue where JSON output containing project configuration (
moon project --json,
moon query projects, MCP responses, and webhook payloads) serialized renamed settings under the
wrong keys:typeOfinstead oftype(tasks),runInCiinstead ofrunInCI(task options), and
schemainstead of$schema. The output now matches the documented JSON schemas and
@moonrepo/types. - Fixed an issue where environment variables removed through moon's internal environment bag (for
exampleNO_COLORwhen colors are forced) were not removed from the current process, and could be
inherited back into the bag on a subsequent read. - Fixed an issue where a task with
options.retryCountwould attempt to run again after the
pipeline was aborted (because another task failed) or interrupted (like with Ctrl+C), which
started a new process that was never terminated, and could continue running after moon exited. - Fixed an issue where a task that had yet to run its command when the pipeline was aborted or
interrupted (it was still generating its hash, or waiting on amutex) would run it afterwards,
which started a process that was never terminated. - Fixed an issue where tasks that depend on a persistent task would still run when the persistent
task was skipped (because one of its own dependencies failed), when failures don't abort the
pipeline (like withmoon ci). - Fixed an issue where a task dependency would be inserted into the action graph (and ran) more than
once, when itsenvwas defined in a different order by the tasks that depend on it. - Fixed an issue where a task that is ran more than once in the same pipeline (with different
args
orenv, as a dependency of other tasks) would fail with a missing dependency hash error, or
ignore its own dependencies, when running with--upstream direct. Its dependencies are now
linked for every instance of the task, once they are in scope for one of them. - Fixed an issue where the action graph would fail with a cycle error, when the order of
dependencies for a task withoptions.runDepsInParalleldisabled contradicts a dependency between
them, and that dependency is linked after they were ordered (like when running with
--upstream direct). Dependencies now always take precedence over the configured order. - Fixed an issue where a persistent task would run in CI by default, when it defined
outputs, or a
typeofbuildortest, which keeps the pipeline running. Persistent tasks no longer run in
CI, unlessoptions.runInCIis explicitly enabled. - Fixed an issue where a persistent task with
options.runInCIenabled would be ran in CI on its
own (bymoon ciwhen it was affected, or when a task that it depends on was ran), which keeps
the pipeline running. In CI, persistent tasks are now only ran when another task depends on them,
or when they're explicitly passed as a target. - Fixed an issue where
moon checkwould run persistent tasks (those that defineoutputs, or a
typeofbuildortest), so the command would never complete. Persistent tasks are now only
ran bymoon checkwhen another task depends on them. - Fixed an issue where
moon checkwould prompt for a list of tasks to run, or fail with an
identifier error in non-TTY environments, when the projects being checked have no build or test
tasks. It now reports that there's nothing to check.
⚙️ Internal
- Updated proto to v0.62.2 from 0.60.2.
- Updated Rust to v1.99.0.
- Updated dependencies.
Install moon_cli 2.6.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/moonrepo/moon/releases/download/v2.6.0/moon_cli-installer.sh | shInstall prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/moonrepo/moon/releases/download/v2.6.0/moon_cli-installer.ps1 | iex"Download moon_cli 2.6.0
| File | Platform | Checksum |
|---|---|---|
| moon_cli-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| moon_cli-x86_64-apple-darwin.tar.xz | Intel macOS | checksum |
| moon_cli-x86_64-pc-windows-msvc.zip | x64 Windows | checksum |
| moon_cli-aarch64-unknown-linux-gnu.tar.xz | ARM64 Linux | checksum |
| moon_cli-x86_64-unknown-linux-gnu.tar.xz | x64 Linux | checksum |
| moon_cli-aarch64-unknown-linux-musl.tar.xz | ARM64 MUSL Linux | checksum |
| moon_cli-x86_64-unknown-linux-musl.tar.xz | x64 MUSL Linux | checksum |