From 9057309528f7a95e4d16d17cb6e00aa73fd977df Mon Sep 17 00:00:00 2001 From: jdx <216188+jdx@users.noreply.github.com> Date: Mon, 27 Apr 2026 20:38:28 +0000 Subject: [PATCH 1/5] fix(lockfile): update global lockfile on upgrade --- e2e/cli/test_upgrade | 15 ++++++ src/lockfile.rs | 106 ++++++++++++++++++++++++++++++------------- 2 files changed, 89 insertions(+), 32 deletions(-) diff --git a/e2e/cli/test_upgrade b/e2e/cli/test_upgrade index aaa87b5752..32f7bb8a95 100644 --- a/e2e/cli/test_upgrade +++ b/e2e/cli/test_upgrade @@ -191,4 +191,19 @@ assert_contains "cat mise.toml" '"3"' assert_contains "cat mise.lock" "3.0.1" assert_not_contains "cat mise.lock" "2.0.0" rm -f mise.toml mise.lock + +# Test: upgrading a global fuzzy version should update the global lockfile +cat <<'EOF' >"$MISE_CONFIG_DIR/config.toml" +[tools] +dummy = "latest" +EOF +mise uninstall dummy --all +mise install dummy@1.0.0 +touch "$MISE_CONFIG_DIR/mise.lock" +mise lock --global --platform linux-x64 +assert_contains "cat $MISE_CONFIG_DIR/mise.lock" "1.0.0" +mise upgrade dummy@2.0.0 +assert_contains "cat $MISE_CONFIG_DIR/mise.lock" "2.0.0" +assert_not_contains "cat $MISE_CONFIG_DIR/mise.lock" "1.0.0" +rm -f "$MISE_CONFIG_DIR/config.toml" "$MISE_CONFIG_DIR/mise.lock" unset MISE_LOCKFILE diff --git a/src/lockfile.rs b/src/lockfile.rs index fe50af0ee2..b0e61c627a 100644 --- a/src/lockfile.rs +++ b/src/lockfile.rs @@ -921,9 +921,6 @@ pub fn update_lockfiles(config: &Config, ts: &Toolset, new_versions: &[ToolVersi if !cf.source().is_mise_toml() { continue; } - if crate::config::is_global_config(config_path) { - continue; - } let (lockfile_path, _is_local) = lockfile_path_for_config(config_path); lockfile_configs .entry(lockfile_path) @@ -951,21 +948,66 @@ pub fn update_lockfiles(config: &Config, ts: &Toolset, new_versions: &[ToolVersi let mut existing_lockfile = Lockfile::read(&lockfile_path) .unwrap_or_else(|err| handle_lockfile_read_error(err, &lockfile_path)); - // Collect all tools from all contributing configs - let mut tools_by_short: HashMap> = HashMap::new(); + // Collect all tools from all contributing configs. This starts from the + // resolved toolset, then overlays newly installed versions because a + // fuzzy request may still resolve through the old lockfile entry until + // this update is written. + let mut tool_versions_by_short: HashMap> = HashMap::new(); for config_path in &configs { let tool_source = ToolSource::MiseToml(config_path.clone()); if let Some(tools) = tools_by_source.get(&tool_source) { for (short, tvl) in tools { - let lockfile_tools: Vec = tvl.clone().into(); - for tool in lockfile_tools { - tools_by_short.entry(short.clone()).or_default().push(tool); - } + tool_versions_by_short + .entry(short.clone()) + .or_default() + .extend(tvl.versions.clone()); } } } + for new_version in new_versions { + let versions = tool_versions_by_short + .entry(new_version.short().to_string()) + .or_default(); + if let Some(source_path) = new_version.request.source().path() { + if !configs.iter().any(|config| config == source_path) { + continue; + } + + versions.retain(|tv| { + tv.ba() != new_version.ba() + || tv.request.version() != new_version.request.version() + || tv.request.source() != new_version.request.source() + }); + versions.push(new_version.clone()); + } else if let Some((idx, request)) = versions + .iter() + .enumerate() + .exactly_one() + .ok() + .map(|(idx, tv)| (idx, tv.request.clone())) + { + let mut new_version = new_version.clone(); + new_version.request = request; + versions.remove(idx); + versions.push(new_version); + } + } + + let tools_by_short: HashMap> = tool_versions_by_short + .into_iter() + .map(|(short, versions)| { + ( + short, + versions + .iter() + .map(lockfile_tool_from_tool_version) + .collect(), + ) + }) + .collect(); + // Check for provenance regression before merging (which drops old version entries). // For github backend tools, error if the highest prior version had provenance but // the new version does not — this could indicate a supply chain attack. @@ -1755,34 +1797,34 @@ impl LockfileTool { impl From for Vec { fn from(tvl: ToolVersionList) -> Self { - use crate::backend::platform_target::PlatformTarget; - tvl.versions .iter() - .map(|tv| { - let mut platforms = BTreeMap::new(); + .map(lockfile_tool_from_tool_version) + .collect() + } +} - // Convert tool version lock_platforms to lockfile platforms - for (platform, platform_info) in &tv.lock_platforms { - platforms.insert(platform.clone(), platform_info.clone()); - } +fn lockfile_tool_from_tool_version(tv: &ToolVersion) -> LockfileTool { + let mut platforms = BTreeMap::new(); - // Resolve lockfile options from the backend - let options = if let Ok(backend) = tv.request.backend() { - let target = PlatformTarget::from_current(); - backend.resolve_lockfile_options(&tv.request, &target) - } else { - BTreeMap::new() - }; + // Convert tool version lock_platforms to lockfile platforms + for (platform, platform_info) in &tv.lock_platforms { + platforms.insert(platform.clone(), platform_info.clone()); + } - LockfileTool { - version: tv.version.clone(), - backend: Some(tv.ba().stored_full()), - options, - platforms, - } - }) - .collect() + // Resolve lockfile options from the backend + let options = if let Ok(backend) = tv.request.backend() { + let target = PlatformTarget::from_current(); + backend.resolve_lockfile_options(&tv.request, &target) + } else { + BTreeMap::new() + }; + + LockfileTool { + version: tv.version.clone(), + backend: Some(tv.ba().stored_full()), + options, + platforms, } } From 2d949b820d0dfccccd7981220d77c87053c517ac Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Mon, 27 Apr 2026 20:47:36 +0000 Subject: [PATCH 2/5] [autofix.ci] apply automated fixes --- mise.lock | 46 +++------------------------------------------- 1 file changed, 3 insertions(+), 43 deletions(-) diff --git a/mise.lock b/mise.lock index b07a4a1045..ea1c7b8185 100644 --- a/mise.lock +++ b/mise.lock @@ -581,52 +581,12 @@ checksum = "sha256:795670a80d35b23e7ecf932ede742609f2267314f2df64054b020698fcc8a url = "https://github.com/LuaLS/lua-language-server/releases/download/3.17.1/lua-language-server-3.17.1-win32-x64.zip" [[tools.node]] -version = "24.14.0" +version = "25.9.0" backend = "core:node" -[tools.node."platforms.linux-arm64"] -checksum = "sha256:f44740cd218de8127f1c44c41510a3a740fa5c9c8d1cdce1c3bedada79f3cde7" -url = "https://nodejs.org/dist/v24.14.0/node-v24.14.0-linux-arm64.tar.gz" - -[tools.node."platforms.linux-arm64-musl"] -checksum = "sha256:8f81d47b7f443455709d44eae8669591de2e58b37d3c2cb0aec667b6e6f826c1" -url = "https://unofficial-builds.nodejs.org/download/release/v24.14.0/node-v24.14.0-linux-arm64-musl.tar.gz" - [tools.node."platforms.linux-x64"] -checksum = "sha256:dbf5b8665dec15e59e6359a517fefb47b23fdb9152d8def975b9bca3dfc6d355" -url = "https://nodejs.org/dist/v24.14.0/node-v24.14.0-linux-x64.tar.gz" - -[tools.node."platforms.linux-x64-baseline"] -checksum = "sha256:dbf5b8665dec15e59e6359a517fefb47b23fdb9152d8def975b9bca3dfc6d355" -url = "https://nodejs.org/dist/v24.14.0/node-v24.14.0-linux-x64.tar.gz" - -[tools.node."platforms.linux-x64-musl"] -checksum = "sha256:bae0f2320448d5c744bcd4878081b483194d8b0f0eaab2b37d7f81df739c5a95" -url = "https://unofficial-builds.nodejs.org/download/release/v24.14.0/node-v24.14.0-linux-x64-musl.tar.gz" - -[tools.node."platforms.linux-x64-musl-baseline"] -checksum = "sha256:bae0f2320448d5c744bcd4878081b483194d8b0f0eaab2b37d7f81df739c5a95" -url = "https://unofficial-builds.nodejs.org/download/release/v24.14.0/node-v24.14.0-linux-x64-musl.tar.gz" - -[tools.node."platforms.macos-arm64"] -checksum = "sha256:a1a54f46a750d2523d628d924aab61758a51c9dad3e0238beb14141be9615dd3" -url = "https://nodejs.org/dist/v24.14.0/node-v24.14.0-darwin-arm64.tar.gz" - -[tools.node."platforms.macos-x64"] -checksum = "sha256:f2879eb810e25993a0578e5d878930266fd2eafcffe9f2839b3d8db354d4879e" -url = "https://nodejs.org/dist/v24.14.0/node-v24.14.0-darwin-x64.tar.gz" - -[tools.node."platforms.macos-x64-baseline"] -checksum = "sha256:f2879eb810e25993a0578e5d878930266fd2eafcffe9f2839b3d8db354d4879e" -url = "https://nodejs.org/dist/v24.14.0/node-v24.14.0-darwin-x64.tar.gz" - -[tools.node."platforms.windows-x64"] -checksum = "sha256:313fa40c0d7b18575821de8cb17483031fe07d95de5994f6f435f3b345f85c66" -url = "https://nodejs.org/dist/v24.14.0/node-v24.14.0-win-x64.zip" - -[tools.node."platforms.windows-x64-baseline"] -checksum = "sha256:313fa40c0d7b18575821de8cb17483031fe07d95de5994f6f435f3b345f85c66" -url = "https://nodejs.org/dist/v24.14.0/node-v24.14.0-win-x64.zip" +checksum = "sha256:134e55b2408448a219760fe04dc44d6851f9de8a79549021ffd870e9082d9e7b" +url = "https://nodejs.org/dist/v25.9.0/node-v25.9.0-linux-x64.tar.gz" [[tools."npm:ajv-cli"]] version = "5.0.0" From b9de3f5d2ca537a6560023669bed76b69d174ec7 Mon Sep 17 00:00:00 2001 From: jdx <216188+jdx@users.noreply.github.com> Date: Mon, 27 Apr 2026 20:49:34 +0000 Subject: [PATCH 3/5] fix(lockfile): avoid stale overlay entries --- e2e/cli/test_upgrade | 1 + src/lockfile.rs | 38 +++++++++++++++++++++++--------------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/e2e/cli/test_upgrade b/e2e/cli/test_upgrade index 32f7bb8a95..6f50775d53 100644 --- a/e2e/cli/test_upgrade +++ b/e2e/cli/test_upgrade @@ -203,6 +203,7 @@ touch "$MISE_CONFIG_DIR/mise.lock" mise lock --global --platform linux-x64 assert_contains "cat $MISE_CONFIG_DIR/mise.lock" "1.0.0" mise upgrade dummy@2.0.0 +assert_contains "cat $MISE_CONFIG_DIR/config.toml" '"latest"' assert_contains "cat $MISE_CONFIG_DIR/mise.lock" "2.0.0" assert_not_contains "cat $MISE_CONFIG_DIR/mise.lock" "1.0.0" rm -f "$MISE_CONFIG_DIR/config.toml" "$MISE_CONFIG_DIR/mise.lock" diff --git a/src/lockfile.rs b/src/lockfile.rs index b0e61c627a..0073bdfed0 100644 --- a/src/lockfile.rs +++ b/src/lockfile.rs @@ -967,31 +967,39 @@ pub fn update_lockfiles(config: &Config, ts: &Toolset, new_versions: &[ToolVersi } for new_version in new_versions { - let versions = tool_versions_by_short - .entry(new_version.short().to_string()) - .or_default(); if let Some(source_path) = new_version.request.source().path() { if !configs.iter().any(|config| config == source_path) { continue; } + let versions = tool_versions_by_short + .entry(new_version.short().to_string()) + .or_default(); versions.retain(|tv| { tv.ba() != new_version.ba() - || tv.request.version() != new_version.request.version() || tv.request.source() != new_version.request.source() }); versions.push(new_version.clone()); - } else if let Some((idx, request)) = versions - .iter() - .enumerate() - .exactly_one() - .ok() - .map(|(idx, tv)| (idx, tv.request.clone())) - { - let mut new_version = new_version.clone(); - new_version.request = request; - versions.remove(idx); - versions.push(new_version); + } else if let Some(versions) = tool_versions_by_short.get_mut(new_version.short()) { + if let Some((idx, request)) = versions + .iter() + .enumerate() + .exactly_one() + .ok() + .map(|(idx, tv)| (idx, tv.request.clone())) + { + let mut new_version = new_version.clone(); + new_version.request = request; + versions.remove(idx); + versions.push(new_version); + } else { + trace!( + "skipping lockfile update for {}@{} in {}: ambiguous config entries", + new_version.short(), + new_version.version, + display_path(&lockfile_path) + ); + } } } From 71b1e21814f225a0220fed99d9dcf230d0a23269 Mon Sep 17 00:00:00 2001 From: jdx <216188+jdx@users.noreply.github.com> Date: Mon, 27 Apr 2026 17:05:11 -0500 Subject: [PATCH 4/5] fix(lockfile): preserve multi-version constraints and align global lockfile auto-lock - Restore request.version() in retain criterion so each fuzzy variant (e.g. tiny = ['latest', 'prefix:1.0', 'prefix:1.1']) keeps its own lockfile entry. Without this, all entries from the same source were removed and only the last new_version survived. - Remove the is_global_config guard in auto_lock_new_versions so it matches update_lockfiles and resolves checksums for global lockfiles on additional platforms. - Revert unrelated mise.lock change for node (the 25.9.0 entry doesn't satisfy the node = "24" constraint and dropped non-linux-x64 platforms). Co-Authored-By: Claude Opus 4.7 (1M context) --- mise.lock | 46 +++++++++++++++++++++++++++++++++++++++++++--- src/lockfile.rs | 4 +--- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/mise.lock b/mise.lock index ea1c7b8185..b07a4a1045 100644 --- a/mise.lock +++ b/mise.lock @@ -581,12 +581,52 @@ checksum = "sha256:795670a80d35b23e7ecf932ede742609f2267314f2df64054b020698fcc8a url = "https://github.com/LuaLS/lua-language-server/releases/download/3.17.1/lua-language-server-3.17.1-win32-x64.zip" [[tools.node]] -version = "25.9.0" +version = "24.14.0" backend = "core:node" +[tools.node."platforms.linux-arm64"] +checksum = "sha256:f44740cd218de8127f1c44c41510a3a740fa5c9c8d1cdce1c3bedada79f3cde7" +url = "https://nodejs.org/dist/v24.14.0/node-v24.14.0-linux-arm64.tar.gz" + +[tools.node."platforms.linux-arm64-musl"] +checksum = "sha256:8f81d47b7f443455709d44eae8669591de2e58b37d3c2cb0aec667b6e6f826c1" +url = "https://unofficial-builds.nodejs.org/download/release/v24.14.0/node-v24.14.0-linux-arm64-musl.tar.gz" + [tools.node."platforms.linux-x64"] -checksum = "sha256:134e55b2408448a219760fe04dc44d6851f9de8a79549021ffd870e9082d9e7b" -url = "https://nodejs.org/dist/v25.9.0/node-v25.9.0-linux-x64.tar.gz" +checksum = "sha256:dbf5b8665dec15e59e6359a517fefb47b23fdb9152d8def975b9bca3dfc6d355" +url = "https://nodejs.org/dist/v24.14.0/node-v24.14.0-linux-x64.tar.gz" + +[tools.node."platforms.linux-x64-baseline"] +checksum = "sha256:dbf5b8665dec15e59e6359a517fefb47b23fdb9152d8def975b9bca3dfc6d355" +url = "https://nodejs.org/dist/v24.14.0/node-v24.14.0-linux-x64.tar.gz" + +[tools.node."platforms.linux-x64-musl"] +checksum = "sha256:bae0f2320448d5c744bcd4878081b483194d8b0f0eaab2b37d7f81df739c5a95" +url = "https://unofficial-builds.nodejs.org/download/release/v24.14.0/node-v24.14.0-linux-x64-musl.tar.gz" + +[tools.node."platforms.linux-x64-musl-baseline"] +checksum = "sha256:bae0f2320448d5c744bcd4878081b483194d8b0f0eaab2b37d7f81df739c5a95" +url = "https://unofficial-builds.nodejs.org/download/release/v24.14.0/node-v24.14.0-linux-x64-musl.tar.gz" + +[tools.node."platforms.macos-arm64"] +checksum = "sha256:a1a54f46a750d2523d628d924aab61758a51c9dad3e0238beb14141be9615dd3" +url = "https://nodejs.org/dist/v24.14.0/node-v24.14.0-darwin-arm64.tar.gz" + +[tools.node."platforms.macos-x64"] +checksum = "sha256:f2879eb810e25993a0578e5d878930266fd2eafcffe9f2839b3d8db354d4879e" +url = "https://nodejs.org/dist/v24.14.0/node-v24.14.0-darwin-x64.tar.gz" + +[tools.node."platforms.macos-x64-baseline"] +checksum = "sha256:f2879eb810e25993a0578e5d878930266fd2eafcffe9f2839b3d8db354d4879e" +url = "https://nodejs.org/dist/v24.14.0/node-v24.14.0-darwin-x64.tar.gz" + +[tools.node."platforms.windows-x64"] +checksum = "sha256:313fa40c0d7b18575821de8cb17483031fe07d95de5994f6f435f3b345f85c66" +url = "https://nodejs.org/dist/v24.14.0/node-v24.14.0-win-x64.zip" + +[tools.node."platforms.windows-x64-baseline"] +checksum = "sha256:313fa40c0d7b18575821de8cb17483031fe07d95de5994f6f435f3b345f85c66" +url = "https://nodejs.org/dist/v24.14.0/node-v24.14.0-win-x64.zip" [[tools."npm:ajv-cli"]] version = "5.0.0" diff --git a/src/lockfile.rs b/src/lockfile.rs index 0073bdfed0..84e9c038d3 100644 --- a/src/lockfile.rs +++ b/src/lockfile.rs @@ -977,6 +977,7 @@ pub fn update_lockfiles(config: &Config, ts: &Toolset, new_versions: &[ToolVersi .or_default(); versions.retain(|tv| { tv.ba() != new_version.ba() + || tv.request.version() != new_version.request.version() || tv.request.source() != new_version.request.source() }); versions.push(new_version.clone()); @@ -1215,9 +1216,6 @@ pub async fn auto_lock_new_versions(_config: &Config, new_versions: &[ToolVersio continue; } if let Some(source_path) = tv.request.source().path() { - if crate::config::is_global_config(source_path) { - continue; - } let (lockfile_path, _) = lockfile_path_for_config(source_path); versions_by_lockfile .entry(lockfile_path) From b944a3c901d3b61e58e2220980dd853a40784249 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Mon, 27 Apr 2026 22:14:03 +0000 Subject: [PATCH 5/5] [autofix.ci] apply automated fixes --- mise.lock | 46 +++------------------------------------------- 1 file changed, 3 insertions(+), 43 deletions(-) diff --git a/mise.lock b/mise.lock index b07a4a1045..ea1c7b8185 100644 --- a/mise.lock +++ b/mise.lock @@ -581,52 +581,12 @@ checksum = "sha256:795670a80d35b23e7ecf932ede742609f2267314f2df64054b020698fcc8a url = "https://github.com/LuaLS/lua-language-server/releases/download/3.17.1/lua-language-server-3.17.1-win32-x64.zip" [[tools.node]] -version = "24.14.0" +version = "25.9.0" backend = "core:node" -[tools.node."platforms.linux-arm64"] -checksum = "sha256:f44740cd218de8127f1c44c41510a3a740fa5c9c8d1cdce1c3bedada79f3cde7" -url = "https://nodejs.org/dist/v24.14.0/node-v24.14.0-linux-arm64.tar.gz" - -[tools.node."platforms.linux-arm64-musl"] -checksum = "sha256:8f81d47b7f443455709d44eae8669591de2e58b37d3c2cb0aec667b6e6f826c1" -url = "https://unofficial-builds.nodejs.org/download/release/v24.14.0/node-v24.14.0-linux-arm64-musl.tar.gz" - [tools.node."platforms.linux-x64"] -checksum = "sha256:dbf5b8665dec15e59e6359a517fefb47b23fdb9152d8def975b9bca3dfc6d355" -url = "https://nodejs.org/dist/v24.14.0/node-v24.14.0-linux-x64.tar.gz" - -[tools.node."platforms.linux-x64-baseline"] -checksum = "sha256:dbf5b8665dec15e59e6359a517fefb47b23fdb9152d8def975b9bca3dfc6d355" -url = "https://nodejs.org/dist/v24.14.0/node-v24.14.0-linux-x64.tar.gz" - -[tools.node."platforms.linux-x64-musl"] -checksum = "sha256:bae0f2320448d5c744bcd4878081b483194d8b0f0eaab2b37d7f81df739c5a95" -url = "https://unofficial-builds.nodejs.org/download/release/v24.14.0/node-v24.14.0-linux-x64-musl.tar.gz" - -[tools.node."platforms.linux-x64-musl-baseline"] -checksum = "sha256:bae0f2320448d5c744bcd4878081b483194d8b0f0eaab2b37d7f81df739c5a95" -url = "https://unofficial-builds.nodejs.org/download/release/v24.14.0/node-v24.14.0-linux-x64-musl.tar.gz" - -[tools.node."platforms.macos-arm64"] -checksum = "sha256:a1a54f46a750d2523d628d924aab61758a51c9dad3e0238beb14141be9615dd3" -url = "https://nodejs.org/dist/v24.14.0/node-v24.14.0-darwin-arm64.tar.gz" - -[tools.node."platforms.macos-x64"] -checksum = "sha256:f2879eb810e25993a0578e5d878930266fd2eafcffe9f2839b3d8db354d4879e" -url = "https://nodejs.org/dist/v24.14.0/node-v24.14.0-darwin-x64.tar.gz" - -[tools.node."platforms.macos-x64-baseline"] -checksum = "sha256:f2879eb810e25993a0578e5d878930266fd2eafcffe9f2839b3d8db354d4879e" -url = "https://nodejs.org/dist/v24.14.0/node-v24.14.0-darwin-x64.tar.gz" - -[tools.node."platforms.windows-x64"] -checksum = "sha256:313fa40c0d7b18575821de8cb17483031fe07d95de5994f6f435f3b345f85c66" -url = "https://nodejs.org/dist/v24.14.0/node-v24.14.0-win-x64.zip" - -[tools.node."platforms.windows-x64-baseline"] -checksum = "sha256:313fa40c0d7b18575821de8cb17483031fe07d95de5994f6f435f3b345f85c66" -url = "https://nodejs.org/dist/v24.14.0/node-v24.14.0-win-x64.zip" +checksum = "sha256:134e55b2408448a219760fe04dc44d6851f9de8a79549021ffd870e9082d9e7b" +url = "https://nodejs.org/dist/v25.9.0/node-v25.9.0-linux-x64.tar.gz" [[tools."npm:ajv-cli"]] version = "5.0.0"