Skip to content

refactor(config): consolidate flat task_* settings into nested task.*#8239

Merged
jdx merged 3 commits intomainfrom
chore/consolidate-task-settings
Feb 18, 2026
Merged

refactor(config): consolidate flat task_* settings into nested task.*#8239
jdx merged 3 commits intomainfrom
chore/consolidate-task-settings

Conversation

@jdx
Copy link
Owner

@jdx jdx commented Feb 18, 2026

Summary

  • Moves 9 flat `task_` settings to the `task.` namespace (e.g. `task_output` → `task.output`)
  • Old names remain fully functional via migration in `set_hidden_configs()` — no breaking changes
  • Deprecation warnings will appear starting at mise `2026.8.0`; `debug_assert!` fires at `2027.2.0` to remind devs to remove the old names
  • Extends `settings.toml` schema to support `deprecated_warn_at` / `deprecated_remove_at` fields, enabling version-gated deprecation to be declared in TOML rather than scattered in code

Settings migrated:

Old New
`task_disable_paths` `task.disable_paths`
`task_output` `task.output`
`task_remote_no_cache` `task.remote_no_cache`
`task_run_auto_install` `task.run_auto_install`
`task_show_full_cmd` `task.show_full_cmd`
`task_skip` `task.skip`
`task_skip_depends` `task.skip_depends`
`task_timeout` `task.timeout`
`task_timings` `task.timings`

Test plan

  • `mise run build` — compiles cleanly
  • `mise run test:unit` — 481 tests pass
  • `mise run test:e2e test_task_raw_output test_task_skip_deps test_task_file_auto_install test_auto_install_false` — all pass
  • Old setting names still work (backwards compat via migration)
  • `MISE_TASK_OUTPUT=prefix` env var routes to new `task.output` setting

🤖 Generated with Claude Code


Note

Medium Risk
Touches config parsing/migration and task execution behavior via renamed settings, so mistakes could silently change task defaults or deprecation timing; scope is contained and largely refactor/migration-driven.

Overview
Consolidates task-related configuration under task.* by adding a new nested task settings namespace (e.g. task.output, task.run_auto_install, task.skip_depends) and updating runtime/task code paths to read from the nested struct.

Maintains backward compatibility by migrating legacy task_* keys in Settings::set_hidden_configs() while introducing version-gated deprecation metadata (deprecated_warn_at/deprecated_remove_at) and warnings/assertions driven from settings.toml/generated SETTINGS_META. Documentation, manpage/usage text, schemas, and E2E tests are updated to use the new task.* keys, and legacy keys are marked deprecated/hidden in the schema and settings definitions.

Written by Cursor Bugbot for commit 95b5fc6. This will update automatically on new commits. Configure here.

… settings

Add 9 new nested task.* settings (task.disable_paths, task.output,
task.remote_no_cache, task.run_auto_install, task.show_full_cmd, task.skip,
task.skip_depends, task.timeout, task.timings) and deprecate the corresponding
flat task_* settings with version-gated warnings (deprecated_warn_at="2026.8.0",
deprecated_remove_at="2027.2.0"). Extend SettingsMeta and build.rs codegen to
support deprecation fields, add warn_deprecated() helper, and migrate all code
references from settings.task_xxx to settings.task.xxx.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings February 18, 2026 13:38
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @jdx, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly refactors the configuration settings related to tasks by moving them from a flat task_* structure to a more organized nested task.* namespace. This change aims to improve the maintainability and readability of the configuration. Crucially, it includes a robust migration path to ensure backward compatibility, allowing users to continue using old settings while receiving deprecation warnings. A new system for version-gated deprecation has also been introduced, enabling a clear roadmap for future setting changes.

Highlights

  • Configuration Refactoring: Consolidated nine flat task_* settings into a nested task.* namespace for improved organization and clarity.
  • Backward Compatibility: Implemented a migration mechanism in set_hidden_configs() to ensure old task_* setting names remain fully functional, preventing breaking changes for existing configurations.
  • Version-Gated Deprecation: Extended the settings.toml schema to support deprecated_warn_at and deprecated_remove_at fields, allowing for declarative, version-controlled deprecation warnings and eventual removal of old settings.
  • Documentation and Schema Updates: Updated documentation, man pages, and JSON schemas to reflect the new task.* naming convention and the added deprecation fields.
Changelog
  • build.rs
    • Added a new helper function push_deprecated_fields to dynamically include deprecation metadata (deprecated, deprecated_warn_at, deprecated_remove_at) when generating settings metadata.
  • docs/configuration.md
    • Updated the example configuration to use task.output instead of task_output.
  • docs/tasks/running-tasks.md
    • Updated documentation to reference task.output instead of task_output.
  • e2e/config/test_auto_install_false
    • Updated the test configuration to use task.run_auto_install instead of task_run_auto_install.
  • e2e/tasks/test_task_file_auto_install
    • Updated the test configuration to use task.run_auto_install instead of task_run_auto_install.
  • e2e/tasks/test_task_raw_output
    • Updated test comments and configuration to use task.output instead of task_output.
  • e2e/tasks/test_task_skip_deps
    • Updated test comments and configuration to use task.skip_depends instead of task_skip_depends.
  • man/man1/mise.1
    • Updated references from task_output to task.output in the man page for mise commands.
  • mise.usage.kdl
    • Updated help messages for interleave and prefix flags to reference task.output instead of task_output.
  • schema/mise-settings.json
    • Added deprecated_warn_at and deprecated_remove_at properties to the settings metadata schema.
  • schema/mise.json
    • Introduced a new nested task object containing properties like disable_paths, output, remote_no_cache, run_auto_install, show_full_cmd, skip, skip_depends, timeout, and timings.
    • Marked the old flat task_* properties as deprecated within the schema.
  • settings.toml
    • Moved several task_* settings into the new [task.*] namespace.
    • Added deprecated, deprecated_warn_at, and deprecated_remove_at metadata to the old task_* settings to manage their deprecation lifecycle.
  • src/cli/run.rs
    • Updated command-line argument documentation to refer to task.output instead of task_output.
    • Modified the logic to use Settings::get().task.skip_depends instead of Settings::get().task_skip_depends.
  • src/cli/watch.rs
    • Updated commented-out documentation for prefix and interleave flags to reference task.output.
  • src/config/mod.rs
    • Updated task path filtering to use Settings::get().task.disable_paths.
    • Updated remote task fetching to use Settings::get().task.remote_no_cache.
  • src/config/settings.rs
    • Added deprecated, deprecated_warn_at, and deprecated_remove_at fields to the SettingsMeta struct.
    • Implemented a warn_deprecated function to issue warnings for deprecated settings based on version numbers.
    • Added migration logic within set_hidden_configs to transfer values from old task_* settings to their new task.* counterparts and trigger deprecation warnings.
    • Updated task_timeout_duration to retrieve the timeout from self.task.timeout.
  • src/task/task_executor.rs
    • Updated task timing logic to use Settings::get().task.timings.
    • Updated task skipping logic to use Settings::get().task.skip.
  • src/task/task_fetcher.rs
    • Updated task remote cache logic to use Settings::get().task.remote_no_cache.
  • src/task/task_output.rs
    • Updated command truncation logic to use Settings::get().task.show_full_cmd.
  • src/task/task_output_handler.rs
    • Updated output handling logic to use Settings::get().task.output.
  • src/task/task_tool_installer.rs
    • Updated tool installation logic to use Settings::get().task.run_auto_install.
Activity
  • The author ran mise run build which compiled cleanly.
  • The author ran mise run test:unit and all 481 tests passed.
  • The author ran specific end-to-end tests (test_task_raw_output, test_task_skip_deps, test_task_file_auto_install, test_auto_install_false) and all passed.
  • The author manually verified that old setting names still work, confirming backward compatibility.
  • The author manually verified that the MISE_TASK_OUTPUT=prefix environment variable correctly routes to the new task.output setting.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This is a solid refactoring that consolidates task-related settings into a task.* namespace, improving configuration organization. The implementation is thorough, covering documentation, tests, and schemas, and includes a well-designed migration path with deprecation warnings for backward compatibility. The suggestion to improve the maintainability of the settings migration logic by reducing code duplication is valid and has been kept.

Comment on lines +364 to +404
// Migrate task_* settings to task.* (must run before auto_install override below)
if let Some(v) = self.task_disable_paths.take() {
if !v.is_empty() {
warn_deprecated("task_disable_paths");
self.task.disable_paths.extend(v);
}
}
if let Some(v) = self.task_output.take() {
warn_deprecated("task_output");
self.task.output = Some(v);
}
if let Some(v) = self.task_remote_no_cache {
warn_deprecated("task_remote_no_cache");
self.task.remote_no_cache = Some(v);
}
if let Some(v) = self.task_run_auto_install {
warn_deprecated("task_run_auto_install");
self.task.run_auto_install = v;
}
if let Some(v) = self.task_show_full_cmd {
warn_deprecated("task_show_full_cmd");
self.task.show_full_cmd = v;
}
if let Some(v) = self.task_skip.take() {
if !v.is_empty() {
warn_deprecated("task_skip");
self.task.skip.extend(v);
}
}
if let Some(v) = self.task_skip_depends {
warn_deprecated("task_skip_depends");
self.task.skip_depends = v;
}
if let Some(v) = self.task_timeout.take() {
warn_deprecated("task_timeout");
self.task.timeout = Some(v);
}
if let Some(v) = self.task_timings {
warn_deprecated("task_timings");
self.task.timings = Some(v);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The migration logic for each of the task_* settings is very repetitive. To improve maintainability and reduce boilerplate, you could use a macro to handle the common pattern of checking for a value, warning about deprecation, and assigning it to the new setting.

        macro_rules! migrate_task_setting {
            // For settings that are moved, e.g. Option<T> -> Option<T> where T is not Copy
            ($s:ident, $old:ident, $new:ident) => {
                if let Some(v) = $s.$old.take() {
                    warn_deprecated(stringify!($old));
                    $s.task.$new = Some(v);
                }
            };
            // For settings that are moved and are Copy, e.g. Option<bool> -> Option<bool>
            ($s:ident, copy $old:ident, $new:ident) => {
                if let Some(v) = $s.$old {
                    warn_deprecated(stringify!($old));
                    $s.task.$new = Some(v);
                }
            };
            // For bool settings, e.g. Option<bool> -> bool
            ($s:ident, bool $old:ident, $new:ident) => {
                if let Some(v) = $s.$old {
                    warn_deprecated(stringify!($old));
                    $s.task.$new = v;
                }
            };
            // For collection settings
            ($s:ident, extend $old:ident, $new:ident) => {
                if let Some(v) = $s.$old.take() {
                    if !v.is_empty() {
                        warn_deprecated(stringify!($old));
                        $s.task.$new.extend(v);
                    }
                }
            };
        }

        // Migrate task_* settings to task.* (must run before auto_install override below)
        migrate_task_setting!(self, extend task_disable_paths, disable_paths);
        migrate_task_setting!(self, task_output, output);
        migrate_task_setting!(self, copy task_remote_no_cache, remote_no_cache);
        migrate_task_setting!(self, bool task_run_auto_install, run_auto_install);
        migrate_task_setting!(self, bool task_show_full_cmd, show_full_cmd);
        migrate_task_setting!(self, extend task_skip, skip);
        migrate_task_setting!(self, bool task_skip_depends, skip_depends);
        migrate_task_setting!(self, task_timeout, timeout);
        migrate_task_setting!(self, copy task_timings, timings);

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors the configuration surface by moving legacy flat task_* settings into a nested task.* namespace, while preserving backwards compatibility through migration logic and adding version-gated deprecation metadata to the settings schema/tooling.

Changes:

  • Migrates 9 legacy task_* settings to task.*, updating Rust call sites accordingly.
  • Adds TOML-declared deprecation metadata (deprecated_warn_at / deprecated_remove_at) and emits version-gated warnings when deprecated keys are used.
  • Updates settings/schema/docs/usage/man/e2e configs to prefer the new task.* keys.

Reviewed changes

Copilot reviewed 21 out of 21 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/task/task_tool_installer.rs Switches auto-install behavior to read task.run_auto_install.
src/task/task_output_handler.rs Reads output mode from task.output instead of task_output.
src/task/task_output.rs Uses task.show_full_cmd for truncation behavior.
src/task/task_fetcher.rs Uses task.remote_no_cache for remote task caching.
src/task/task_executor.rs Uses task.timings and task.skip.
src/config/settings.rs Adds deprecation metadata + warning helper; migrates deprecated task_* keys into task.*.
src/config/mod.rs Uses task.disable_paths / task.remote_no_cache during task discovery/fetching.
src/cli/watch.rs Updates help text references to task.output.
src/cli/run.rs Updates help text and uses task.skip_depends.
settings.toml Defines new task.* settings and marks task_* keys as deprecated/hidden with version gates.
schema/mise.json Adds nested task properties and marks legacy task_* keys deprecated.
schema/mise-settings.json Extends schema to allow deprecation version fields.
mise.usage.kdl Updates CLI help text references to task.output.
man/man1/mise.1 Updates manpage references to task.output.
e2e/tasks/test_task_skip_deps Updates test config to task.skip_depends.
e2e/tasks/test_task_raw_output Updates test config to task.output.
e2e/tasks/test_task_file_auto_install Updates test config to task.run_auto_install.
e2e/config/test_auto_install_false Updates test config to task.run_auto_install.
docs/tasks/running-tasks.md Updates docs to reference task.output.
docs/configuration.md Updates example config to task.output.
build.rs Emits deprecation metadata into generated SETTINGS_META.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +224 to +241
fn warn_deprecated(key: &str) {
if let Some(meta) = SETTINGS_META.get(key)
&& let (Some(msg), Some(warn_at), Some(remove_at)) = (
meta.deprecated,
meta.deprecated_warn_at,
meta.deprecated_remove_at,
) {
use versions::Versioning;
let warn_version = Versioning::new(warn_at).unwrap();
let remove_version = Versioning::new(remove_at).unwrap();
debug_assert!(
*crate::cli::version::V < remove_version,
"Deprecated setting [{key}] should have been removed in {remove_at}. Please remove this deprecated setting.",
);
if *crate::cli::version::V >= warn_version {
let id = Box::leak(format!("setting.{key}").into_boxed_str());
if crate::output::DEPRECATED.lock().unwrap().insert(id) {
warn!(
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warn_deprecated leaks memory by Box::leak-ing a newly formatted string every time a deprecated key is processed (even when the warning has already been emitted). Since all current call sites pass string literals, consider making key an &'static str and using that directly as the deprecation id (or reuse the existing deprecated_at! macro) so the warning can still be deduped without allocating/leaking per call.

Copilot uses AI. Check for mistakes.
Comment on lines +364 to 404
if let Some(v) = self.task_disable_paths.take()
&& !v.is_empty() {
warn_deprecated("task_disable_paths");
self.task.disable_paths.extend(v);
}
if let Some(v) = self.task_output.take() {
warn_deprecated("task_output");
self.task.output = Some(v);
}
if let Some(v) = self.task_remote_no_cache {
warn_deprecated("task_remote_no_cache");
self.task.remote_no_cache = Some(v);
}
if let Some(v) = self.task_run_auto_install {
warn_deprecated("task_run_auto_install");
self.task.run_auto_install = v;
}
if let Some(v) = self.task_show_full_cmd {
warn_deprecated("task_show_full_cmd");
self.task.show_full_cmd = v;
}
if let Some(v) = self.task_skip.take()
&& !v.is_empty() {
warn_deprecated("task_skip");
self.task.skip.extend(v);
}
if let Some(v) = self.task_skip_depends {
warn_deprecated("task_skip_depends");
self.task.skip_depends = v;
}
if let Some(v) = self.task_timeout.take() {
warn_deprecated("task_timeout");
self.task.timeout = Some(v);
}
if let Some(v) = self.task_timings {
warn_deprecated("task_timings");
self.task.timings = Some(v);
}
if !self.auto_install {
self.exec_auto_install = false;
self.not_found_auto_install = false;
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR introduces backwards-compat behavior (migrating task_* to task.*) and version-gated deprecation warnings, but there are no automated checks asserting that: (1) old keys still apply correctly, and (2) MISE_TASK_OUTPUT/other env vars still map to the new keys. Adding an e2e (or unit) test that sets the deprecated keys/env and asserts the observed behavior would prevent regressions when these migrations are refactored later.

Copilot uses AI. Check for mistakes.
Comment on lines 1438 to +1446
"task_output": {
"description": "Change output style when executing tasks.",
"type": "string",
"enum": [
"prefix",
"interleave",
"keep-order",
"replacing",
"timed",
"quiet",
"silent"
]
"deprecated": true
},
"task_remote_no_cache": {
"description": "Mise will always fetch the latest tasks from the remote, by default the cache is used.",
"type": "boolean"
"type": "boolean",
"deprecated": true
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the JSON schema, task_output is still supported (deprecated) but its enum constraints were removed. This makes the schema accept values that the runtime parser will still reject, which is a validation/IDE-assistance regression. Consider keeping the original enum (and other constraints/defaults where applicable) while also marking the property as deprecated.

Copilot uses AI. Check for mistakes.
@jdx
Copy link
Owner Author

jdx commented Feb 18, 2026

bugbot run

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

@jdx jdx enabled auto-merge (squash) February 18, 2026 14:04
@jdx jdx merged commit bed5f16 into main Feb 18, 2026
36 checks passed
@jdx jdx deleted the chore/consolidate-task-settings branch February 18, 2026 14:04
@github-actions
Copy link

Hyperfine Performance

mise x -- echo

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.2.16 x -- echo 25.7 ± 0.6 24.2 30.2 1.00
mise x -- echo 25.7 ± 0.8 24.4 32.6 1.00 ± 0.04

mise env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.2.16 env 25.3 ± 0.8 23.6 28.9 1.00 ± 0.04
mise env 25.3 ± 0.5 23.7 27.7 1.00

mise hook-env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.2.16 hook-env 25.9 ± 0.6 24.2 28.4 1.00
mise hook-env 26.2 ± 0.5 24.7 27.6 1.01 ± 0.03

mise ls

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.2.16 ls 23.5 ± 0.4 21.8 24.9 1.01 ± 0.03
mise ls 23.2 ± 0.6 21.8 26.2 1.00

xtasks/test/perf

Command mise-2026.2.16 mise Variance
install (cached) 136ms 136ms +0%
ls (cached) 83ms 83ms +0%
bin-paths (cached) 89ms 88ms +1%
task-ls (cached) 848ms 835ms +1%

mise-en-dev added a commit that referenced this pull request Feb 19, 2026
### 🐛 Bug Fixes

- **(install)** use backend bin paths for per-tool postinstall hooks by
@jdx in [#8234](#8234)
- **(use)** write to config.toml instead of config.local.toml by @jdx in
[#8240](#8240)
- default legacy .mise.backend installs to non-explicit by @jean-humann
in [#8245](#8245)

### 🚜 Refactor

- **(config)** consolidate flat task_* settings into nested task.* by
@jdx in [#8239](#8239)
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request Feb 22, 2026
## [2026.2.18](https://github.com/jdx/mise/compare/v2026.2.17..v2026.2.18) - 2026-02-21

### 🚀 Features

- **(install)** auto-lock all platforms after tool installation by @jdx in [#8277](jdx/mise#8277)

### 🐛 Bug Fixes

- **(config)** respect --yes flag for config trust prompts by @jdx in [#8288](jdx/mise#8288)
- **(exec)** strip shims from PATH on Unix to prevent infinite recursion by @jdx in [#8276](jdx/mise#8276)
- **(install)** validate --locked before --dry-run short-circuit by @altendky in [#8290](jdx/mise#8290)
- **(release)** refresh PATH after mise up in release-plz by @jdx in [#8292](jdx/mise#8292)
- **(schema)** replace unevaluatedProperties with additionalProperties by @jdx in [#8285](jdx/mise#8285)
- **(task)** avoid duplicated stderr on task failure in replacing mode by @jdx in [#8275](jdx/mise#8275)
- **(task)** use process groups to kill child process trees on Unix by @jdx in [#8279](jdx/mise#8279)
- **(task)** run depends_post tasks even when parent task fails by @jdx in [#8274](jdx/mise#8274)
- **(task)** suggest similar commands when mistyping a CLI subcommand by @jdx in [#8286](jdx/mise#8286)
- **(task)** execute monorepo subdirectory prepare steps from root by @jdx in [#8291](jdx/mise#8291)
- **(upgrade)** don't force-reinstall already installed versions by @jdx in [#8282](jdx/mise#8282)
- **(watch)** restore terminal state after watchexec exits by @jdx in [#8273](jdx/mise#8273)

### 📚 Documentation

- clarify that MISE_CEILING_PATHS excludes the ceiling directory itself by @jdx in [#8283](jdx/mise#8283)

### Chore

- replace gen-release-notes script with communique by @jdx in [#8289](jdx/mise#8289)

### New Contributors

- @altendky made their first contribution in [#8290](jdx/mise#8290)

### 📦 Aqua Registry Updates

#### New Packages (4)

- [`Skarlso/crd-to-sample-yaml`](https://github.com/Skarlso/crd-to-sample-yaml)
- [`kunobi-ninja/kunobi-releases`](https://github.com/kunobi-ninja/kunobi-releases)
- [`swanysimon/markdownlint-rs`](https://github.com/swanysimon/markdownlint-rs)
- [`tmux/tmux-builds`](https://github.com/tmux/tmux-builds)

#### Updated Packages (2)

- [`firecow/gitlab-ci-local`](https://github.com/firecow/gitlab-ci-local)
- [`k1LoW/runn`](https://github.com/k1LoW/runn)

## [2026.2.17](https://github.com/jdx/mise/compare/v2026.2.16..v2026.2.17) - 2026-02-19

### 🚀 Features

- **(prepare)** update mtime of outputs after command is run by @halms in [#8243](jdx/mise#8243)

### 🐛 Bug Fixes

- **(install)** use backend bin paths for per-tool postinstall hooks by @jdx in [#8234](jdx/mise#8234)
- **(use)** write to config.toml instead of config.local.toml by @jdx in [#8240](jdx/mise#8240)
- default legacy .mise.backend installs to non-explicit by @jean-humann in [#8245](jdx/mise#8245)

### 🚜 Refactor

- **(config)** consolidate flat task_* settings into nested task.* by @jdx in [#8239](jdx/mise#8239)

### Chore

- **(prepare)** refactor common code into ProviderBase by @halms in [#8246](jdx/mise#8246)

### 📦 Aqua Registry Updates

#### Updated Packages (1)

- [`namespacelabs/foundation/nsc`](https://github.com/namespacelabs/foundation/nsc)
risu729 pushed a commit to risu729/mise that referenced this pull request Feb 27, 2026
…jdx#8239)

## Summary

- Moves 9 flat \`task_*\` settings to the \`task.*\` namespace (e.g.
\`task_output\` → \`task.output\`)
- Old names remain fully functional via migration in
\`set_hidden_configs()\` — no breaking changes
- Deprecation warnings will appear starting at mise \`2026.8.0\`;
\`debug_assert!\` fires at \`2027.2.0\` to remind devs to remove the old
names
- Extends \`settings.toml\` schema to support \`deprecated_warn_at\` /
\`deprecated_remove_at\` fields, enabling version-gated deprecation to
be declared in TOML rather than scattered in code

**Settings migrated:**
| Old | New |
|---|---|
| \`task_disable_paths\` | \`task.disable_paths\` |
| \`task_output\` | \`task.output\` |
| \`task_remote_no_cache\` | \`task.remote_no_cache\` |
| \`task_run_auto_install\` | \`task.run_auto_install\` |
| \`task_show_full_cmd\` | \`task.show_full_cmd\` |
| \`task_skip\` | \`task.skip\` |
| \`task_skip_depends\` | \`task.skip_depends\` |
| \`task_timeout\` | \`task.timeout\` |
| \`task_timings\` | \`task.timings\` |

## Test plan

- [x] \`mise run build\` — compiles cleanly
- [x] \`mise run test:unit\` — 481 tests pass
- [x] \`mise run test:e2e test_task_raw_output test_task_skip_deps
test_task_file_auto_install test_auto_install_false\` — all pass
- [ ] Old setting names still work (backwards compat via migration)
- [ ] \`MISE_TASK_OUTPUT=prefix\` env var routes to new \`task.output\`
setting

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Touches config parsing/migration and task execution behavior via
renamed settings, so mistakes could silently change task defaults or
deprecation timing; scope is contained and largely
refactor/migration-driven.
> 
> **Overview**
> **Consolidates task-related configuration under `task.*`** by adding a
new nested `task` settings namespace (e.g. `task.output`,
`task.run_auto_install`, `task.skip_depends`) and updating runtime/task
code paths to read from the nested struct.
> 
> Maintains backward compatibility by migrating legacy `task_*` keys in
`Settings::set_hidden_configs()` while introducing version-gated
deprecation metadata (`deprecated_warn_at`/`deprecated_remove_at`) and
warnings/assertions driven from `settings.toml`/generated
`SETTINGS_META`. Documentation, manpage/usage text, schemas, and E2E
tests are updated to use the new `task.*` keys, and legacy keys are
marked deprecated/hidden in the schema and settings definitions.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
95b5fc6. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
risu729 pushed a commit to risu729/mise that referenced this pull request Feb 27, 2026
### 🐛 Bug Fixes

- **(install)** use backend bin paths for per-tool postinstall hooks by
@jdx in [jdx#8234](jdx#8234)
- **(use)** write to config.toml instead of config.local.toml by @jdx in
[jdx#8240](jdx#8240)
- default legacy .mise.backend installs to non-explicit by @jean-humann
in [jdx#8245](jdx#8245)

### 🚜 Refactor

- **(config)** consolidate flat task_* settings into nested task.* by
@jdx in [jdx#8239](jdx#8239)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants