mise-en-place

jdx/mise last check 672 releases today
Notes

The front-end to your dev env Pronounced "MEEZ ahn plahs"

Release notes
view on github
2026.11.3 · v2026.11.3: Task history, saved task logs, and source-based --affected outside monorepos · today

This release adds three task features: mise tasks history shows how long past runs took, the opt-in task.logs setting saves each task's last output, and mise run --affected now works in any project by matching changed files against each task's sources. It also fixes problems with upgrade --bump, GitHub asset detection, locked lockfiles, Windows npm installs, prune and hung asdf plugins.

Added

  • mise run --affected outside a monorepo. Before, --affected worked only at a monorepo root and failed anywhere else. Outside a monorepo it now runs only the matching tasks affected by changed files. A task is affected when a changed file matches its sources, or when the config file or file script that defines it changed. Matching uses the same rules as the up-to-date check, including ! exclusions and paths relative to the task's directory.

    • Tasks with no sources, and tasks whose sources use {{usage.*}}, run whenever anything changed. When nothing changed, nothing runs.
    • Global tasks are left out. Dependencies of a selected task still run, subject to the up-to-date check.
    • The existing --affected-base, --affected-head, --affected-committed, --affected-uncommitted and --affected-untracked options decide which changes count. --affected-explain prints why each task was selected or skipped, and --affected-json reports the reasons (changed-source, task-config, task-file, no-sources, argument-sources).
    • Monorepo project selection is unchanged.

    #15407 (@jdx)

    [tasks."test:unit"]
    run = "cargo test"
    sources = ["src/**"]
    
    [tasks."test:docs"]
    run = "markdownlint docs"
    sources = ["docs/**"]
    
    mise run --affected --affected-explain 'test:*'
    
  • mise tasks history. mise now records when each task run started, how long it took, its redacted arguments, its exit code and its status (ok, failed, cached, skipped or cancelled). mise tasks history [TASK] lists past runs. --summary shows each task's run count, failure count, median duration of successful runs, and last duration and status. --json prints the records as JSON. Recording is on by default and keeps the last 20 runs per task. You can change the limit with task.history_limit, or turn recording off with task.history = false. Dry runs and tasks that only have depends are not recorded, and a recording error never fails a run. #15408 (@jdx)

    $ mise tasks history --summary
    hello      3  0  89.0ms  88.0ms  ok
    test:unit  3  0  -       1.0ms   skipped
    
  • Saved task output with mise tasks log. When the new task.logs setting (or MISE_TASK_LOGS=1) is on, mise keeps the full output of each task's last run. mise tasks log NAME prints it, and --path prints where the file is. This gets back output that the replacing, timed, silent and summary styles hide or shorten. When a task fails under one of those styles, mise prints a full output: <path> line. Logs are stored in $MISE_STATE_DIR/task-logs/ with owner-only permissions and are redacted the same way as terminal output. Each log keeps the newest 4 MiB. Output that mise doesn't pipe is not logged: raw and interactive tasks, and the default interleave mode when it has nothing to redact. The setting is off by default. #15409 (@jdx)

    [settings]
    task.logs = true
    

    The same PR changes every piped output style: lines longer than 1 MiB now arrive in pieces, so mise no longer holds a whole long line in memory. The pieces are split so that secrets and URL credentials are still fully redacted.

Fixed

  • mise upgrade --bump no longer rewrites a two-part prefix such as { prefix = "1.23" } to the unresolvable prefix:prefix:1.1. It now bumps to the correct version, for example prefix:1.26. #15426 (@jdx, @kjanat)
  • When choosing a release asset automatically, the github: backend now skips Python wheels (.whl) and Ruby gems (.gem), as it already does for .deb and .rpm. Before, a manylinux wheel could be picked over the native binary. An explicit asset_pattern can still select these files. If an asset_pattern looks like a regular expression and matches nothing, the GitHub, GitLab and Forgejo error now explains that asset_pattern is a glob and suggests matching_regex. #15423 (@jdx)
  • With tool_config.locked = true and lockfile_mode = "generate", installing or running one tool no longer writes another tool's unrecorded version into mise.lock. Before, this let the next run accept a pin nobody had reviewed. The lockfile now stays unchanged, and only mise lock records new versions. #15428 (@jdx, @mikomiel)
  • On Windows, npm: tools installed with aube are now reinstalled when a cache restore turned their dependency links into file symlinks. Before, mise install reported "already installed" while Node failed with ERR_MODULE_NOT_FOUND. #15425 (@jdx, @Diapolo10)
  • When run from outside a project, mise prune and mise upgrade no longer delete installs of task tools that the project names through its [tool_alias]. The "not found in mise tool registry" warning for these tools is also gone. #15427 (@jdx)
  • fetch_remote_versions_timeout now stops an asdf plugin's bin/list-all that hangs. mise kills the script's process group and fails with timed out after ... and a hint about the setting. Before, mise waited until the script exited and held the version lock the whole time. ruby-install --update now follows the same timeout. bin/list-all now runs with stdin closed, so a script that reads stdin gets EOF. #15424 (@jdx, @karngyan)

Full Changelog: https://github.com/jdx/mise/compare/v2026.11.2...v2026.11.3

💚 Sponsor mise

mise is built and maintained by @jdx, an open source developer at entire.io, the title sponsor of his open source work.

If mise saves you or your team time, please consider becoming an individual or company sponsor. Your support funds ongoing development and helps keep mise fast, free, and independent.