chore: release 2026.5.0#9485
Conversation
Greptile SummaryThis is a standard automated release PR bumping mise from Confidence Score: 5/5Safe to merge — this is a clean, automated release PR with only version bumps and changelog updates. All changes are mechanical version-string updates generated by the release automation. No logic changes, no new code paths, and no P1/P0 findings were identified. No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[mise-en-dev bot triggers release] --> B[Bump version: 2026.4.28 → 2026.5.0]
B --> C[Update Cargo.toml]
B --> D[Update default.nix]
B --> E[Update snapcraft.yaml]
B --> F[Update packaging/rpm/mise.spec]
B --> G[Update README.md example output]
B --> H[Update completion spec-file names]
H --> H1[completions/_mise]
H --> H2[completions/mise.bash]
H --> H3[completions/mise.fish]
H --> H4[completions/mise.ps1]
B --> I[Prepend CHANGELOG.md entry]
B --> J[Add Node 24.15.0 platform checksums to mise.lock]
B --> K[Update stars count in docs]
Reviews (98): Last reviewed commit: "chore: release 2026.5.0" | Re-trigger Greptile |
There was a problem hiding this comment.
Code Review
This pull request updates the version of mise to 2026.4.29 and aqua-registry to 2026.4.12 across various configuration files, lock files, and shell completions. It also updates the changelog to reflect recent bug fixes and registry updates, and downgrades the node version in mise.lock while adding comprehensive platform-specific support. I have no feedback to provide.
Hyperfine Performance
|
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.4.28 x -- echo |
42.1 ± 4.1 | 35.5 | 71.8 | 1.00 |
mise x -- echo |
45.3 ± 8.1 | 37.3 | 77.8 | 1.08 ± 0.22 |
mise env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.4.28 env |
40.7 ± 2.3 | 35.1 | 49.1 | 1.00 |
mise env |
40.7 ± 2.6 | 35.3 | 51.0 | 1.00 ± 0.08 |
mise hook-env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.4.28 hook-env |
41.4 ± 2.4 | 36.3 | 50.8 | 1.00 |
mise hook-env |
41.9 ± 2.5 | 37.0 | 52.8 | 1.01 ± 0.08 |
mise ls
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.4.28 ls |
74.0 ± 2.9 | 67.1 | 88.1 | 1.00 |
mise ls |
76.4 ± 3.1 | 69.7 | 86.9 | 1.03 ± 0.06 |
xtasks/test/perf
| Command | mise-2026.4.28 | mise | Variance |
|---|---|---|---|
| install (cached) | 133ms | 134ms | +0% |
| ls (cached) | 67ms | 65ms | +3% |
| bin-paths (cached) | 70ms | 70ms | +0% |
| task-ls (cached) | 586ms | 591ms | +0% |
945ca93 to
0a71e4d
Compare
2eb9e67 to
899610a
Compare
fb21cd8 to
552e751
Compare
## Summary The `tera_template_task_args` deprecation has `warn_at = 2026.5.0`, which is the version being released in [#9485](#9485). Once the warning starts firing, `tasks/test_task_help` fails: ``` $ mise run atask --help 2>&1 || true mise WARN deprecated [tera_template_task_args]: Task 'atask' uses deprecated Tera template functions... Usage: atask <myarg> ... ``` The first assertion in the test is an exact equality check, so the prepended warning breaks it ([CI run](https://github.com/jdx/mise/actions/runs/25257720207/job/74060047308)). This migrates the test's `atask` from the deprecated `{{arg(...)}}` Tera form to the `usage` field. Both produce identical help output, and using the non-deprecated form is the future-correct shape anyway. ## Test plan - [x] `mise run test:e2e tasks/test_task_help` passes locally (all 13 assertions) 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: this only updates an e2e test fixture to avoid deprecated arg templating and resulting warning output that breaks an exact help assertion. > > **Overview** > Updates the `e2e/tasks/test_task_help` fixture to stop using deprecated Tera `{{arg(...)}}` templating for task args. > > The `atask` definition now declares args via the `usage` field and references the parsed value (`$usage_myarg`) in `run`, keeping `mise run atask --help` output stable and preventing warning-prefixed output from failing the exact-match assertion. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit c7b259f. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
99f965b to
b0f1cd8
Compare
96990ec to
5bc0149
Compare
…9558) ## Summary Two regressions visible in the release PR (#9485): - `mise install go:.../@latest` returns "no versions found" when the latest is a Go pseudo-version (e.g. `go:github.com/go-kratos/kratos/cmd/kratos/v2`) — the e2e-0 / `backend/test_go_install_slow` failure. - (After narrowing the rule too aggressively in earlier revs of this PR: `mise latest python` returned `3.15.0a8` instead of a stable. Fixed below.) ## Cause The `([abc])[0-9]+` alternative in the shared `VERSION_REGEX` was unanchored, so it false-positived on any `a`/`b`/`c` followed by a digit anywhere in a string — including the random hex hash inside Go pseudo-versions (e.g. `c1` inside `f149714c1d54`). #9500 enabled `mark_prereleases_from_version_pattern: true` for the `go` backend on May 1, which is what made it user-visible — the regex was already over-permissive but no Go-flavored input had been feeding it before. ## Fix The rule is PEP 440-specific (Python's separator-less alpha/beta/rc shorthand). Move it out of the general regex into `PEP440_PRERELEASE_REGEX` and consult it only from Python-flavored backends. - `VERSION_REGEX` (in `src/plugins/mod.rs`): drop the `([abc])[0-9]+` alternative. - `PEP440_PRERELEASE_REGEX` (new): `(?i)[0-9](?:a|b|c|rc)[0-9]+(?:\$|[^a-z0-9])` — grounded in PEP 440's canonical grammar `[N!]N(.N)*[{a|b|rc}N][.postN][.devN]`. The leading digit anchors the prerelease segment to follow the release segment (so it can't trigger inside arbitrary identifiers); `c` is included as PEP 440's recognized alternate spelling for `rc`; the trailing boundary stops it from matching inside hex hashes even when those start with a digit. - `pipx`: - Stamps PEP 440 prereleases on `VersionInfo` in `_list_remote_versions` so the cache reflects it. - Overrides `fuzzy_match_filter` to drop them from match results. - `python` core plugin: same `fuzzy_match_filter` override (`python-build` returns `3.15.0a8`-style alphas). - Both share a new `fuzzy_match_versions_pep440` helper in `src/backend/mod.rs` so the override is one line each. ## Test plan - [x] `cargo test test_pep440_prerelease_regex` (new) — Python suffixes match, Go pseudo-versions and bare-`b` identifiers don't, `.post` doesn't. - [x] `cargo test test_version_regex_filters_prerelease` — confirms PEP 440 cases now negative on the general regex. - [x] `cargo test test_mark_prerelease_flags_regex_matches` — added a Go pseudo-version case and a PEP 440 case (both should *not* be flagged by the general path). - [x] `cargo test test_fuzzy_match_versions_*`, `test_filter_cached_prereleases_*`, `pipx::tests::*`. - [x] Local repro: `mise ls-remote 'go:github.com/go-kratos/kratos/cmd/kratos/v2'` returns `2.0.0-20260404020628-f149714c1d54`. - [x] Local repro: `mise latest python` returns `3.14.4` (was `3.15.0a8` after the earlier rev of this PR). - [ ] Wait on CI for `e2e-0 / test_go_install_slow` and `e2e-6 / test_latest`. 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Adjusts prerelease detection and fuzzy version resolution logic, which can change what versions are considered installable/latest across multiple backends; mistakes could hide valid versions or surface prereleases unexpectedly. > > **Overview** > Fixes prerelease filtering regressions by removing the unanchored `([abc])[0-9]+` clause from the shared `VERSION_REGEX` (which was incorrectly flagging strings like Go pseudo-versions) and introducing a new Python-scoped `PEP440_PRERELEASE_REGEX`. > > Python-flavored backends (`pipx` and the core `python` plugin) now apply PEP 440 prerelease handling explicitly: `pipx` stamps PEP 440 alphas/betas/rcs onto cached `VersionInfo.prerelease`, and both backends override fuzzy matching via a new shared helper `fuzzy_match_versions_pep440` so `latest`/prefix queries skip `3.15.0a8`-style versions unless explicitly requested. > > Adds focused tests to ensure Go pseudo-versions are not filtered by the general regex and that PEP 440 prerelease detection works only where intended. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 287f01d. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
7ce98dd to
a0c7deb
Compare
…ckfile `mise x node@latest -- ...` (and `mise run`-spawned exec) installs an ephemeral, CLI-supplied tool version. With `MISE_LOCKFILE=1`, that install was being merged into the project's `mise.lock` under the config's existing request — e.g. mise.toml `node = "24"` paired with a freshly-installed `25.9.0`. The lockfile entry then claimed the "24" request resolved to 25.x, which is nonsensical and breaks subsequent `mise install` resolutions. Concretely: this is what was producing the recurring autofix commit on each `release-plz` PR (e.g. #9485 / ea7affd). `mise run render` calls `mise x node@latest -- npx markdown-magic`; on the autofix runner with `MISE_LOCKFILE=1` set, that bumped `mise.lock`'s node entry every cycle. `update_lockfiles`'s else-if branch was added in #9442 specifically to support `mise upgrade`, but `upgrade.rs` already remaps `ToolSource::Argument` → `ToolSource::MiseToml` before calling `update_lockfiles`, so its tools go through the path-source if-branch. The else-if branch only fires for tools that *kept* `ToolSource::Argument` — i.e. exactly the ad-hoc CLI overrides that shouldn't be persisted. Skip the propagation when the new version's request source is `ToolSource::Argument`. `mise upgrade` keeps working (its remap still hits the if-branch); `mise install <tool>` for a configured tool keeps working (`get_requested_tool_versions` pulls the config's request, so the source is `MiseToml`, not `Argument`). Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
…ckfile `mise x node@latest -- ...` (and `mise run`-spawned exec) installs an ephemeral, CLI-supplied tool version. With `MISE_LOCKFILE=1`, that install was being merged into the project's `mise.lock` under the config's existing request — e.g. mise.toml `node = "24"` paired with a freshly-installed `25.9.0`. The lockfile entry then claimed the "24" request resolved to 25.x, which is nonsensical and breaks subsequent `mise install` resolutions. This is what was producing the recurring autofix commit on each `release-plz` PR (e.g. #9485 / ea7affd). `mise run render` calls `mise x node@latest -- npx markdown-magic`; on the autofix runner with `MISE_LOCKFILE=1` set, that bumped `mise.lock`'s node entry every cycle. `update_lockfiles`'s else-if branch was added in #9442 to support `mise upgrade`, but `upgrade.rs` already remaps `ToolSource::Argument` → `ToolSource::MiseToml` before calling `update_lockfiles`, so its tools go through the path-source if-branch. The else-if branch only fires for tools that *kept* `ToolSource::Argument` — exactly the ad-hoc CLI overrides that shouldn't be persisted. Skip the propagation only when the new install's request specifier doesn't match the config's. `mise x node` (no version) is rewritten by `with_default_to_latest` to carry the config's version string, so the specifiers match and a legitimate fuzzy refresh still updates the lockfile. `mise x node@latest` carries a "latest" specifier that doesn't match `node = "24"`, so the override is correctly skipped. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
…ckfile `mise x node@latest -- ...` (and `mise run`-spawned exec) installs an ephemeral, CLI-supplied tool version. With `MISE_LOCKFILE=1`, that install was being merged into the project's `mise.lock` under the config's existing request — e.g. mise.toml `node = "24"` paired with a freshly-installed `25.9.0`. The lockfile entry then claimed the "24" request resolved to 25.x, which is nonsensical and breaks subsequent `mise install` resolutions. This is what was producing the recurring autofix commit on each `release-plz` PR (e.g. #9485 / ea7affd). `mise run render` calls `mise x node@latest -- npx markdown-magic`; on the autofix runner with `MISE_LOCKFILE=1` set, that bumped `mise.lock`'s node entry every cycle. `update_lockfiles`'s else-if branch was added in #9442 to support `mise upgrade`, but `upgrade.rs` already remaps `ToolSource::Argument` → `ToolSource::MiseToml` before calling `update_lockfiles`, so its tools go through the path-source if-branch. The else-if branch only fires for tools that *kept* `ToolSource::Argument` — exactly the ad-hoc CLI overrides that shouldn't be persisted. Skip the propagation only when the new install's request specifier doesn't match the config's. `mise x node` (no version) is rewritten by `with_default_to_latest` to carry the config's version string, so the specifiers match and a legitimate fuzzy refresh still updates the lockfile. `mise x node@latest` carries a "latest" specifier that doesn't match `node = "24"`, so the override is correctly skipped. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
…lockfile (#9562) ## Summary `mise x node@latest -- ...` (and `mise run`-spawned `mise x` calls) is an ephemeral CLI override. With `MISE_LOCKFILE=1`, that install was being merged into the project's `mise.lock` *under the config's existing request* — e.g. `mise.toml` `node = "24"` paired with a freshly-installed `25.9.0`. The lockfile entry then claimed the `"24"` request resolved to a 25.x version, which is nonsensical and breaks subsequent resolutions. ## Why this matters This is what was producing the recurring `[autofix.ci] apply automated fixes` commit on every `release-plz` PR (e.g. [PR #9485 / ea7affd](ea7affd): node 24.15.0 → 25.9.0, platforms 11 → 1). `mise run render` calls `mise x node@latest -- npx markdown-magic`; on the autofix runner with `MISE_LOCKFILE=1` set, that install bumped `mise.lock`'s node entry every release cycle. If autofix is ever blocked or fails on the release branch, the release would ship with a stale/wrong lockfile. ## Root cause `update_lockfiles`'s else-if branch (added in #9442 to support `mise upgrade` propagating to the lockfile) overwrites a config tool's lockfile entry with any newly installed `ToolSource::Argument` version that shares the short name. But `upgrade.rs` already remaps `Argument` → `MiseToml(...)` *before* calling `update_lockfiles` (`src/cli/upgrade.rs:383-396`), so its tools go through the path-source `if` branch. The else-if branch only fires for tools that *kept* `ToolSource::Argument` — exactly the ad-hoc CLI overrides that shouldn't be persisted. ## Fix Compare the new install's request specifier to the config's. Only propagate if they match. - ✅ `mise x node` (no version) — `with_default_to_latest` rewrites the request to carry the config's version string, so the specifiers match and a legitimate fuzzy refresh still populates `mise.lock` (e.g. against an empty lockfile) - ✅ `mise x node@24` when `mise.toml` says `node = "24"` — same specifier, propagates - ❌ `mise x node@latest` when `mise.toml` says `node = "24"` — `"latest" != "24"`, skipped - ❌ `mise x node@25` when `mise.toml` says `node = "24"` — `"25" != "24"`, skipped - ✅ `mise upgrade` keeps working — its remap → `MiseToml` hits the if-branch, never the else-if - ✅ `mise install` (no args) keeps working — sources are `MiseToml` - ✅ `mise install <tool>` for a configured tool keeps working — `get_requested_tool_versions` (`src/cli/install.rs:264-298`) pulls the config's request when no version is given, so the source is `MiseToml` ## Test plan - New e2e: `e2e/cli/test_exec_lockfile` — covers both directions: - `mise x [email protected]` and `mise x dummy@latest` must NOT mutate `mise.lock` when `mise.toml` says `dummy = "1"` - `mise x dummy` (no version) MUST populate an empty lockfile from the config-derived install - `mise upgrade [email protected]` MUST update the lockfile (regression check) - `mise run test:e2e e2e/cli/test_upgrade e2e/cli/test_upgrade_latest_stale` — green (regression check for #9442) - `mise run test:e2e e2e/cli/test_lock e2e/cli/test_lock_global e2e/cli/test_lock_latest e2e/cli/test_lock_creation e2e/cli/test_lock_local_config e2e/cli/test_lock_version e2e/cli/test_exec_latest` — green - `cargo test --all-features lockfile` — 29 lockfile unit tests pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches `update_lockfiles` behavior so some installs triggered by `mise x`/env overrides will no longer update `mise.lock`; this could affect workflows that relied on the previous (incorrect) propagation but is guarded by an e2e regression test. > > **Overview** > Prevents `mise.lock` from being updated by *ad-hoc version overrides* (e.g. `mise x tool@latest` or `MISE_<TOOL>_VERSION=...`) when the override’s version specifier doesn’t match the project config’s requested specifier. > > `update_lockfiles` now compares the new install’s request string against the config-derived request before propagating into the lockfile, skipping mismatches and logging a trace message. Adds an e2e test (`e2e/cli/test_exec_lockfile`) covering override non-propagation, expected propagation for `mise x tool` without a version, and `mise upgrade` still updating the lockfile. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 3b7233a. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
c09e833 to
c38cb51
Compare
🚀 Features
🐛 Bug Fixes
📚 Documentation
🧪 Testing
📦️ Dependency Updates
📦 Registry
git-filter-repoby @garysassano in #9550Chore
New Contributors