fix(npm): respect install_before when resolving dist-tag versions#9145
fix(npm): respect install_before when resolving dist-tag versions#9145
Conversation
NPMBackend's latest_stable_version used the `npm view dist-tags` shortcut which returns the absolute latest version without considering install_before. When install_before is active, fall back to the full version list with created_at timestamps for proper date-based filtering. Fixes jdx#9136 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Address code review feedback: - Clarify comment: this fix catches callers that bypass effective_before_date (mise latest, mise edit), not the primary install path - Add warn! on install_before parse failure instead of silent .ok() - Add debug! when all versions are filtered out by the cutoff Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace inlined filter pipeline with `latest_version_with_opts` which already handles date filtering via `list_versions_matching_with_opts` - Revert `find_match_in_list` to private (no longer needed cross-module) - Remove unit test that only exercised the generic `filter_by_date` fn - Make E2E test version extraction consistent between test cases Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The second test case could pass vacuously if mise install fails silently and installed_ver is empty, since assert_not_contains "" "2.8.8" is true. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
Code Review
This pull request fixes a bug in the NPM backend where the install_before setting was ignored during version resolution because the dist-tags fast path always returned the absolute latest version. The fix involves bypassing this fast path when a date cutoff is configured. Feedback suggests updating the new E2E tests to use the mise latest command directly to ensure the specific code path is exercised, and considering a more generalized fix across other backends that might share this behavior.
There was a problem hiding this comment.
Pull request overview
This PR updates the npm backend’s “latest stable” resolution so global install_before is respected even in code paths that call latest_stable_version directly (notably mise latest / mise edit), avoiding the dist-tags.latest shortcut which ignores date filtering.
Changes:
- In
NPMBackend::latest_stable_version, detect globalSettings::install_beforeand delegate tolatest_version_with_optswith abefore_datecutoff. - Add a new E2E test intended to cover
install_beforebehavior for the npm backend.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/backend/npm.rs |
Bypasses dist-tags when global install_before is set, routing through date-filtered version resolution. |
e2e/backend/test_npm_install_before |
Adds an E2E regression test around install_before + npm:prettier resolution. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
The bug is in NPMBackend::latest_stable_version which is reached by mise latest / mise edit, not by mise install (which already handles install_before via effective_before_date). Use mise latest with MISE_INSTALL_BEFORE env var to test the actual broken code path. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Greptile SummaryThis PR fixes a bug where Confidence Score: 5/5This PR is safe to merge; the fix is targeted and correct with no regressions on the unfiltered path. The change is a focused guard in a single method. The date-filtered path ( No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["latest_stable_version(config)"] --> B{install_before set?}
B -- "global Settings or\nper-tool opts" --> C["latest_version_with_opts\n(query=None, before=Some(ts))"]
B -- "not set" --> D["latest_version_cache (locked)"]
C --> E["list_versions_matching_with_opts\n(query='latest', before=Some(ts))"]
E --> F["_list_remote_versions\nnpm view versions time --json"]
F --> G["VersionInfo::filter_by_date"]
G --> H["fuzzy_match_filter\nexclude pre-releases via VERSION_REGEX"]
H --> I["find_match_in_list → last()"]
D --> J["npm view dist-tags --json\n→ dist_tags['latest']"]
I --> K["Date-filtered stable version"]
J --> L["Absolute latest version"]
Reviews (2): Last reviewed commit: "fix(npm): also check per-tool install_be..." | Re-trigger Greptile |
Look up per-tool install_before option from config via get_tool_opts before falling back to the global setting. This ensures `mise latest` respects per-tool install_before when set in mise.toml. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Head branch was pushed to by a user without write access
The `mise latest` command did not accept a `--before` override, so the CLI flag could not affect version resolution for stable versions. Per-tool `install_before` options and the global `install_before` setting were the only inputs for commands like `mise latest`. Plumb a `--before` flag through to `latest_version_with_opts`, ensuring the CLI flag takes precedence and the existing npm `install_before` handling from jdx#9145 continues to work when the flag is omitted. Made-with: Cursor
### 🚀 Features - **(registry)** add .perl-version support for perl by @ergofriend in [#9102](#9102) - **(task)** add Tera template support for inline table run tasks by @iamkroot in [#9079](#9079) ### 🐛 Bug Fixes - **(env)** use runtime symlink paths for fuzzy versions by @jdx in [#9143](#9143) - **(github)** use full token resolution chain for attestation verification by @jdx in [#9154](#9154) - **(go)** Remove install-time version override for subpath packages by @c22 in [#9135](#9135) - **(npm)** respect install_before when resolving dist-tag versions by @webkaz in [#9145](#9145) - **(self-update)** ensure subcommand exists by @salim-b in [#9144](#9144) - **(task)** show available tasks when run target missing by @jdx in [#9141](#9141) - **(task)** forward task help args and add raw_args by @jdx in [#9118](#9118) - **(task)** remove red/yellow from task prefix colors by @lechuckcaptain in [#8782](#8782) - **(task)** merge TOML task block into same-named file task and surface resolved dir by @jdx in [#9147](#9147) - **(toolset)** round-trip serialized tool options by @atharvasingh7007 in [#9124](#9124) - **(vfox)** fallback to absolute bin path if env_keys not set by @80avin in [#9151](#9151) ### 📚 Documentation - make agent guide wording generic by @jdx in [#9142](#9142) ### 📦️ Dependency Updates - update ghcr.io/jdx/mise:deb docker digest to e019cb9 by @renovate[bot] in [#9160](#9160) - update ghcr.io/jdx/mise:copr docker digest to 8d25608 by @renovate[bot] in [#9159](#9159) - update ghcr.io/jdx/mise:rpm docker digest to 22e52da by @renovate[bot] in [#9161](#9161) - update ghcr.io/jdx/mise:alpine docker digest to a3da97c by @renovate[bot] in [#9158](#9158) - update rust docker digest to 4a2ef38 by @renovate[bot] in [#9162](#9162) - update ubuntu:24.04 docker digest to c4a8d55 by @renovate[bot] in [#9164](#9164) - update rust crate aws-lc-rs to v1.16.3 by @renovate[bot] in [#9165](#9165) - update ubuntu docker tag to resolute-20260413 by @renovate[bot] in [#9169](#9169) - update rust crate clap to v4.6.1 by @renovate[bot] in [#9166](#9166) - update taiki-e/install-action digest to a2352fc by @renovate[bot] in [#9163](#9163) - update rust crate ctor to 0.10 by @renovate[bot] in [#9170](#9170) - update rust crate tokio to v1.52.1 by @renovate[bot] in [#9167](#9167) - update rust crate rmcp-macros to 0.17 by @renovate[bot] in [#9173](#9173) - update rust crate signal-hook to 0.4 by @renovate[bot] in [#9177](#9177) - update rust crate zipsign-api to 0.2 by @renovate[bot] in [#9180](#9180) - update rust crate toml_edit to 0.25 by @renovate[bot] in [#9179](#9179) - update rust crate strum to 0.28 by @renovate[bot] in [#9178](#9178) ### 📦 Registry - add ibmcloud by @dnwe in [#9139](#9139) - add rush by @jdx in [#9146](#9146) ### New Contributors - @80avin made their first contribution in [#9151](#9151) - @atharvasingh7007 made their first contribution in [#9124](#9124) - @lechuckcaptain made their first contribution in [#8782](#8782) - @ergofriend made their first contribution in [#9102](#9102) - @dnwe made their first contribution in [#9139](#9139) ## 📦 Aqua Registry Updates #### New Packages (3) - [`controlplaneio-fluxcd/flux-operator`](https://github.com/controlplaneio-fluxcd/flux-operator) - [`dependency-check/DependencyCheck`](https://github.com/dependency-check/DependencyCheck) - [`kiro.dev/kiro-cli`](https://github.com/kiro.dev/kiro-cli) #### Updated Packages (2) - [`jreleaser/jreleaser/standalone`](https://github.com/jreleaser/jreleaser/standalone) - [`sigstore/cosign`](https://github.com/sigstore/cosign)
Summary
install_beforeis set (per-tool or global),NPMBackend::latest_stable_versionnow delegates tolatest_version_with_opts(which filters bycreated_attimestamps) instead of using thedist-tagsshortcut that returns the absolute latest versionVERSION_REGEXinfuzzy_match_filter, so the resolved version is always a stable release — same asdist-tags.latestFixes #9136
Details
NPMBackend::latest_stable_versionoverrides the default trait implementation to usenpm view <pkg> dist-tags --json. This shortcut ignoresinstall_beforedate filtering.The primary install path (
mise install) is unaffected becauseeffective_before_datesetsResolveOptions.before_date, andlatest_version_with_optsroutes throughlist_versions_matching_with_opts— bypassinglatest_stable_versionentirely.However, callers that don't go through
effective_before_date— such asmise latestandmise edit— reachlatest_stable_versiondirectly. The fix adds a guard that checks per-toolinstall_before(viaconfig.get_tool_opts) and the global setting, then delegates to the existing date-filtered resolution path.Note on pre-release versions
The fallback path uses
fuzzy_match_filterwhich excludes pre-release versions (-alpha,-beta,-rc, etc.) viaVERSION_REGEX. In the rare case where a package tags a pre-release aslatestin dist-tags, the fallback would resolve to the newest stable version instead. This only affects theinstall_beforecode path and matches how all other backends handlelatest.Test plan
e2e/backend/test_npm_install_before: usesmise latestwithMISE_INSTALL_BEFOREto verifylatest_stable_versionrespects the date cutoffcargo test --bin mise backend::npm::tests— 8/8)cargo checkpassesGenerated with Claude Code