-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Comparing changes
Open a pull request
base repository: jdx/mise
base: 798ca8d
head repository: jdx/mise
compare: 9225550
- 14 commits
- 133 files changed
- 8 contributors
Commits on Apr 25, 2026
-
Configuration menu - View commit details
-
Copy full SHA for dbf496e - Browse repository at this point
Copy the full SHA dbf496eView commit details
Commits on Apr 26, 2026
-
Configuration menu - View commit details
-
Copy full SHA for ccd9cd9 - Browse repository at this point
Copy the full SHA ccd9cd9View commit details -
fix(schema): allow array values in tool additionalProperties (#9400)
Tool options like rust `components` accept arrays, e.g.: ```toml [tools] rust = { version = "1.77", components = ["rustfmt", "clippy"] } ``` The old schema though would say otherwise, and linters like tombi flag the above as invalid. Signed-off-by: JP-Ellis <[email protected]>Configuration menu - View commit details
-
Copy full SHA for aff9814 - Browse repository at this point
Copy the full SHA aff9814View commit details -
feat: opt-in to pre-release versions for github and aqua backends (#9329
) Implements the opt-in proposed in discussion #9323 (approved by @jdx). Also wires support into the `aqua:` backend as a small follow-up, as requested. ## What changed Adds a per-tool `prerelease = true` option to the `github:` and `aqua:` backends. When set: - Releases flagged `prerelease: true` on GitHub appear in `mise ls-remote` - `latest` resolves against the full list including pre-releases - Fuzzy version queries (e.g. `1.2`) match pre-release tags under that prefix ```toml [tools] "github:myorg/mytool" = { version = "latest", prerelease = true } "aqua:owner/tool" = { version = "latest", prerelease = true } ``` Default behavior is unchanged (`prerelease = false`). Draft releases are always excluded. ## Where the filters lived Two independent filters needed an escape hatch: 1. **GitHub API flag filter** in `src/github.rs::list_releases_` (`!r.prerelease`). Split so the cache holds unfiltered-except-drafts; `list_releases` preserves old behavior via read-time filter, new `list_releases_including_prereleases{,_from_url}` exposes the unfiltered view. Cache is shared — no extra API cost. 2. **`VERSION_REGEX` filter** in `fuzzy_match_filter` (trait default + `aqua` override). Extracted into a shared `fuzzy_match_versions(versions, query, filter_prereleases)` helper so both call paths can opt out. Also, the `github:` backend's `latest_stable_version` uses the `/releases/latest` endpoint (stable-only by design) — when `prerelease = true` it now falls through to `latest_version_for_query("latest", None)` to resolve against the full list. Uses the `_for_query` variant deliberately to avoid recursing back through `latest_stable_version`. ## Tests - `fuzzy_match_versions`: unit tests pinning both the default (filters prereleases) and opted-in (includes them) behavior across `latest` and partial queries - `UnifiedGitBackend::fuzzy_match_filter`: unit tests verifying the override reads `self.ba.opts()` and toggles correctly - `include_prereleases`: bool-parsing sanity check - All 750+ existing unit tests still pass (one pre-existing failure — `test_inline_install_before_wins_over_config_entry` — reproduces on clean `main`, unrelated) ## What isn't here **No e2e test yet** — `jdx/mise-test-fixtures` only has one stable release, so exercising the opt end-to-end needs a fixture with at least one release flagged `prerelease: true`. Happy to add that in a follow-up if you can flag an existing tag (or I can mock this differently if you'd prefer). **Not touching GitLab/Forgejo** — the opt is documented as a no-op for those backends. Can extend later if there's demand. --------- 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>
Configuration menu - View commit details
-
Copy full SHA for e54999c - Browse repository at this point
Copy the full SHA e54999cView commit details -
fix(backend): allow unresolved latest opt-in (#9401)
## Summary Fixes `latest` resolution for backends that can install an unresolved selector when their remote version list is empty. `minimum_release_age` cannot be evaluated when a backend has no version candidates, but falling back to literal `latest` for every empty-list backend is unsafe: some backends require concrete versions and must continue failing rather than creating literal `latest/` installs. This change keeps the fallback in the central resolver but makes it opt-in through `Backend::unresolved_latest_version()`. The resolver now only falls back when the backend’s unfiltered remote version list is empty and the backend explicitly provides an unresolved selector. If versions exist but are all filtered out by `minimum_release_age`, mise still reports no matching version, preserving the age gate. `pipx` opts in only for git-backed requests, where `latest` is an installable selector. Its remote version listing remains honest: GitHub repos with no releases return `[]` from `ls-remote` instead of reporting `latest` as a release. Tests also assert GitHub release timestamps are preserved for date filtering. ## Validation - `cargo fmt --check` - `cargo test backend::pipx::tests` - `cargo build` - `mise run test:e2e e2e/backend/test_fuzzy_versions_do_not_install_literal_dirs` - clean-cache config check: `pipx:a13xp0p0v/kernel-hardening-checker@latest` resolves to `latest` without `minimum_release_age` - clean-cache config check: `pipx:a13xp0p0v/kernel-hardening-checker@latest` with `minimum_release_age = "7d"` resolves to `latest` - clean-cache guard check: `pipx:psf/black@latest` with `minimum_release_age = "1970-01-01"` still reports no matching version instead of falling back to HEAD - clean-cache `ls-remote pipx:a13xp0p0v/kernel-hardening-checker --json` returns `[]` - pre-commit hook during amend, including `cargo check --all-features` *This PR description was generated by an AI coding assistant.* <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes central `@latest` resolution behavior by allowing an unresolved selector fallback for opted-in backends when remote version listing is empty, which could affect install outcomes for `latest` requests. Scope is limited via explicit backend opt-in and only triggers in non-offline mode with no remote versions returned. > > **Overview** > Fixes `@latest` resolution for backends that can *install an unresolved selector* when no remote versions are discoverable. > > Adds a new `Backend::unresolved_latest_version()` opt-in hook and updates `ToolVersion::resolve_version` to fall back to that value only when the backend’s unfiltered remote version list is empty (and only when not offline), preserving failure behavior when versions exist but don’t match date/age filters. > > Updates `pipx` to opt in for git-based requests by returning `latest` as an installable unresolved selector, while making its remote version listing for non-GitHub git sources return an empty list (instead of a synthetic `latest` version), and adds tests for GitHub release->version mapping and timestamp preservation. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 483868d. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
Configuration menu - View commit details
-
Copy full SHA for 580635a - Browse repository at this point
Copy the full SHA 580635aView commit details -
chore(deps): bump communique to 1.1.2 (#9402)
## Summary - update the communique mise lock entry to v1.1.2 - refresh release asset URLs and checksums, including musl assets ## Validation - monitored jdx/communique release workflow 24960017639 to success - `mise install --locked communique` - mise pre-commit lint hook ran during commit <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: only updates the `mise.lock` entry for the `communique` tool, changing pinned version plus release asset URLs/checksums with no runtime code changes. > > **Overview** > Bumps the pinned `communique` tool in `mise.lock` from `v1.0.4` to `v1.1.2`. > > Refreshes the per-platform release asset metadata (URLs, `url_api`, and checksums), including switching the Linux ARM64 *musl* entry to the correct musl artifact. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit c51648f. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
Configuration menu - View commit details
-
Copy full SHA for 47a71fd - Browse repository at this point
Copy the full SHA 47a71fdView commit details -
chore(ci): improve pr-closer workflow (#9403)
## Summary - Backports improvements made to the same workflow in jdx/hk#876. - Adds explicit `permissions: pull-requests: write` so the job can't 403 on read-only default tokens. - Replaces hardcoded `jdx/mise` with `${{ github.repository }}` (via `REPO` env). - Filters stale PRs server-side via `--search "updated:<CUTOFF -author:jdx -label:keep-open sort:updated-asc"` and bumps `--limit` to 500. Only stale candidates are fetched, sorted oldest-first, so anything beyond the limit rolls into the next daily run instead of being silently skipped. ## Test plan - [x] Verified the search query against jdx/mise — currently returns 0 stale candidates (workflow has been keeping things tidy) - [ ] Trigger via `workflow_dispatch` once merged to confirm a clean run 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: limited to a GitHub Actions workflow and only changes how stale PRs are queried/closed; main risk is mis-filtering PRs and closing the wrong ones. > > **Overview** > Improves the `pr-closer` GitHub Actions workflow by granting explicit `pull-requests: write` permissions and removing the hardcoded repository in favor of `${{ github.repository }}`. > > Changes stale-PR selection to be filtered server-side using a date cutoff search (sorted oldest-first) and increases the fetch limit to 500 before closing candidates, while keeping the “failing vs passing checks” close message behavior. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit ae0b5f8. 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]>
Configuration menu - View commit details
-
Copy full SHA for 41a8887 - Browse repository at this point
Copy the full SHA 41a8887View commit details -
feat(backend): add global libc preference (#9404)
## Summary Adds a global `libc` setting (`MISE_LIBC`) for selecting Linux precompiled binary variants across backends that can safely honor a libc preference. ## Details - Promotes libc preference into typed settings and schema generation, accepting `musl`, `glibc`, and `gnu`. - Threads libc through `Platform::current()` and `PlatformTarget` so generic GitHub asset matching can prefer musl or glibc variants consistently. - Adds aqua support in two layers: - switches aqua registry Linux replacements like `unknown-linux-gnu`/`unknown-linux-musl` according to the target/global libc preference; - keeps the fallback that prefers a very similar release asset with a standalone `musl` token when aqua cannot express the variant yet. - Applies the setting to Bun, Python precompiled builds, Node's common musl unofficial-build flavor, and vfox runtime `envType`. - Updates Docker and Node docs for the new global setting. ## Backend Audit Conda, Go, Zig, Deno, Ruby, Java, Erlang, and Rust do not currently expose a safe global libc selection path here because their upstream artifact naming is either not libc-specific, hard-coded by upstream, or already controlled by backend-specific settings. ## Validation - `cargo test libc` - `cargo test backend::aqua::lock_candidate_tests` - `cargo test -p vfox config::tests::test_env_type` - `cargo fmt --check` - `git diff --check` - commit hook: `cargo check --all-features`, schema validation, markdownlint, shellcheck, shfmt, taplo, prettier, actionlint, lua checks *This PR was generated by an AI coding assistant.* <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Adds a new global `libc` setting that changes how Linux artifacts are selected across multiple backends and influences cache keys, so mis-detection or incorrect preference could cause wrong binaries/lock entries to be chosen. > > **Overview** > Adds a global `libc` setting (schema + `settings.toml`, env `MISE_LIBC`, accepting `glibc`/`gnu`/`musl`) and uses it to influence Linux platform qualification and libc detection. > > Updates platform/target handling to expose libc (including compound qualifiers) and adjusts caching and GitHub asset matching so musl variants can be preferred when requested. > > Extends backend/tool integrations to honor the preference: `aqua` now rewrites Linux replacements and prefers musl release assets for musl lock targets, Node/Python/Bun select musl/glibc variants accordingly, and `vfox` passes an optional runtime `envType` into plugin hooks. Docs are updated to describe the new setting and Docker override behavior. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 16a6a2a. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
Configuration menu - View commit details
-
Copy full SHA for 09cff3d - Browse repository at this point
Copy the full SHA 09cff3dView commit details -
fix(prune): skip remote version resolution for tracked configs (#9406)
## Summary - `mise prune` was resolving every tracked config's tool versions against the network (npm registry, Go proxy, GitHub API), which could hang on slow or failing registries — see [#9405](#9405). - The remote calls were wasted work: prune only protects *installed* versions from deletion, and the resolver's early-return paths (`latest_installed_version`, `list_installed_versions_matching`) already match installed versions without hitting the network. If no installed version matches, the remote-resolved result can't appear in the deletion set anyway. - Adds an `offline` field to `ResolveOptions`, additive to `Settings::offline()`. Set to `true` in prune's path; left `false` for `mise upgrade` (which deliberately wants fresh remote data to decide what tracked configs would resolve to after an upgrade). - Fixes the `latest` resolver path: with offline + nothing installed, returns the unresolved `"latest"` string instead of erroring (safe — won't match any installed pathname). - Replaces the old workaround `MISE_OFFLINE=1 mise prune --yes` with default behavior. Closes [#9405](#9405). ## Test plan - [x] `cargo check` clean - [x] `mise run lint-fix` clean - [x] `mise run test:unit` (774 passed) - [x] `mise run test:e2e test_prune` passes - [ ] Reviewer: in a directory with multiple tracked configs containing prefix/latest/range versions (e.g. `node = "22"`, `npm = "^11"`, a `go:` tool), `MISE_DEBUG=1 mise prune --dry-run` should no longer show `DEBUG GET https://registry.npmjs.org/...`, `proxy.golang.org/...`, or `api.github.com/...` requests during resolution. - [ ] Reviewer: `MISE_DEBUG=1 mise upgrade --dry-run` should still show remote version queries (verifying upgrade's behavior is unchanged). 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Medium risk because it changes version resolution behavior in offline paths (including `latest`/prefix/sub semantics), which can affect which tool versions are considered safe to delete during `prune` and after `upgrade`. Scope is contained to resolution options and tracked-config protection logic. > > **Overview** > **`mise prune` no longer performs network lookups** when resolving tracked config requirements, by threading a new `ResolveOptions.offline` flag through tracked-config resolution. > > This updates `get_versions_needed_by_tracked_configs` to accept an `offline` parameter (used by prune, not upgrade) and adds conservative protection for `sub-N:latest` when offline by keeping all installed versions for that backend. > > Resolver behavior is adjusted so `offline` resolution can return unresolved specs for `latest`, prefix, and `sub-N:latest` instead of erroring or fetching remotes, while leaving normal `upgrade`/`use`/`install` paths explicitly `offline: false`. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 5316331. 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]>
Configuration menu - View commit details
-
Copy full SHA for b404138 - Browse repository at this point
Copy the full SHA b404138View commit details -
fix(node): route musl tarball URLs to unofficial-builds (#9409)
## Summary [PR #9404](#9404) (`feat(backend): add global libc preference`) taught Node's slug builder to append `-musl` for musl targets but kept routing through `nodejs.org/dist/`, which does not host musl tarballs (they live at `unofficial-builds.nodejs.org`). The visible symptom was in [PR #9396](#9396 `mise.lock` diff: the URL gained a `-musl` suffix while the checksum stayed pinned to the original glibc tarball. ```toml [tools.node."platforms.linux-x64-musl"] checksum = "sha256:dbf5b8665..." # ← still the glibc checksum url = ".../v24.14.0/node-v24.14.0-linux-x64-musl.tar.gz" # ← 404, wrong host ``` Mechanically: `resolve_lock_info` builds a 404'ing URL on `nodejs.org/dist`, fetches the wrong `SHASUMS256.txt` (which doesn't list `-musl.tar.gz`), gets `None` back, and the lockfile merge preserves the **stale glibc checksum** alongside the new URL. Anyone running `mise install` against that lockfile on a musl system would either 404 or hit a checksum mismatch. The aqua/github-backed tools in the same release diff updated cleanly because their checksum source rotates with the artifact. Node is unique in fetching checksums from a separate `SHASUMS256.txt`. ## Changes ### `src/plugins/core/node.rs` Add `mirror_url_for(&SettingsNode, filename)` that swaps to `https://unofficial-builds.nodejs.org/download/release/` when a filename references a musl artifact and the user has not set a custom `node.mirror_url`. Wire it into `resolve_lock_info`, `get_tarball_url`, `BuildOpts::new`, and `shasums_url` so the tarball URL and the matching `SHASUMS256.txt` always come from the same host. Three unit tests cover routing (default → glibc, musl → unofficial-builds, custom mirror passes through unchanged). ### `src/lockfile.rs` Defense in depth: when merging `PlatformInfo` (both in `set_platform_info` and `merge_with`), drop the other side's `checksum`/`size`/`url_api` if URLs disagree — those fields describe a specific artifact and become stale once the URL changes. The pre-existing `test_platform_info_merge_prefers_sha256` was asserting that sha256 should win even across mismatched URLs, which is exactly the latent bug; updated it to use a shared URL and added `test_platform_info_merge_drops_stale_checksum_on_url_change`. ### `mise.lock` Re-ran `mise lock node` to fix the three corrupted node musl entries. Checksums verified against upstream: ```sh $ curl -fsSL https://unofficial-builds.nodejs.org/download/release/v24.14.0/SHASUMS256.txt | grep -E "linux-(arm64|x64)-musl\.tar\.gz" 8f81d47b7f... node-v24.14.0-linux-arm64-musl.tar.gz bae0f23204... node-v24.14.0-linux-x64-musl.tar.gz ``` Both match what mise now writes. ## Test plan - [x] `cargo test` — 778 passed, 0 failed (includes 3 new node tests + 1 new lockfile test, plus an updated test that previously asserted the latent bug). - [x] `cargo clippy --all-features --tests` — clean. - [x] `cargo fmt` — clean. - [x] `mise lock node` against this branch produces correct URLs + checksums for all three node musl platform variants. - [ ] Install on Alpine / musl host: `MISE_LIBC=musl mise install [email protected]` should download from `unofficial-builds.nodejs.org` and run. - [ ] Glibc regression: same flow without `MISE_LIBC=musl` should still hit `nodejs.org/dist`. *This PR was generated by an AI coding assistant.* <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes Node.js download/checksum URL selection and lockfile merge behavior, which can affect installs and lockfile correctness across platforms; scope is contained with added tests. > > **Overview** > Fixes Node.js *musl* installs/lock resolution by routing musl tarball URLs (and their matching `SHASUMS256.txt`/signature URLs) to `unofficial-builds.nodejs.org` when using the default mirror, while still respecting user-configured `node.mirror_url`. > > Hardens lockfile merging so when a platform artifact `url` changes, stale artifact-bound fields (`checksum`, `size`, `url_api`) from the other side are dropped instead of preserved, preventing mismatched URL+checksum pairs. > > Regenerates `mise.lock` Node musl entries to use the unofficial-builds URLs with updated sha256 checksums, and adds/updates unit tests covering the new mirror routing and merge semantics. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit dd68707. 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]>
Configuration menu - View commit details
-
Copy full SHA for bec289e - Browse repository at this point
Copy the full SHA bec289eView commit details -
fix(install): stop rewriting healthy runtime symlinks (#9410)
## Summary Fixes the `mise install` regression where a non-root user gets `Permission denied` while rebuilding runtime symlinks against a read-only system installs dir (typical Docker pattern: root populates `/usr/local/share/mise/installs/` at build time, non-root user runs `mise install` at runtime). Reported in [#8596](#8596) and addressed by [#9408](#9408) — this PR is an alternative. ## Root cause `rebuild_symlinks_in_dir` always called `remove_all` + `make_symlink_or_file` on every existing runtime symlink, because the "stale runtime dir" branch fired for symlinks too: ```rust if from.exists() { if is_runtime_symlink(&from) && file::resolve_symlink(&from)?.unwrap_or_default() != to { // Branch 1 — only fires when the symlink target is wrong ... } else if from.file_name() != to.file_name() && !concrete_installs.contains(&from_name) { // Branch 2 — fires for ANY symlink because file_name("latest") != file_name("22.5.0") file::remove_all(&from)?; } ... } ``` For a perfectly healthy `latest -> ./22.5.0`: - Branch 1 fails (`target == to`). - Branch 2 enters because `from.file_name()` (`"latest"`) differs from `to.file_name()` (`"22.5.0"`) and `concrete_installs` doesn't include `"latest"`. - `remove_all` then runs on a healthy symlink — wasted I/O on every install in the common case, hard failure when the dir is read-only. ## Fix - Branch 1 now handles all runtime-symlink cases: rewrite if target differs, otherwise `continue`. - Branch 2 only fires for non-symlink stale dirs (its actual purpose — cleanup for the 2026.4 regression that created real `latest/` directories). - Drop the position-based permission tolerance added in #8722. With healthy symlinks taking the no-op path, read-only system dirs aren't touched at all. If a write IS genuinely required and can't happen, fail loudly so the user knows to fix permissions rather than silently ending up with a stale `latest` after `mise install --system`. ## Why not [#9408](#9408) That PR replaces position-based tolerance with category-based tolerance (any non-`Local` dir gets permission errors swallowed) and silently skips system/shared installs from user shims. Both: - Mask the real bug (the false-positive `remove_all` above) instead of fixing it. Even with category-based tolerance the install does I/O it shouldn't, just hidden under a `debug!`. - Trade one form of silent behavior for another. Reviewers (greptile, gemini) flagged the shims change as a regression for the "root installs once, all users get shims" pattern. - Don't match the maintainer's stated policy: if `mise install` doesn't touch system tools, it should work fine; if it does and the dir isn't writable, it should fail loudly. This PR achieves both via a delta-based no-op rather than tolerance. ## Tests - `e2e/cli/test_install_system_readonly` — sets up `[email protected]` in user dir, `[email protected]` in a fake system dir, `chmod -R a-w` the system dir, then runs `mise install --force [email protected]` and `mise install [email protected]`. Asserts both succeed AND that the `skipping symlink update` / `Permission denied` / `failed rm` warnings do NOT appear in output. Verified to fail before this fix (with `WARN skipping symlink update for ...: failed rm -rf ... Permission denied`) and pass after. ## Test plan - [x] `cargo test --bin mise` — 774 pass - [x] `mise run lint-fix` — clean - [x] `mise run test:e2e test_install_system_readonly` — pass - [x] `mise run test:e2e test_install_system test_shared_install_dirs test_install_before_ignores_stale_latest_dirs test_upgrade_latest_stale test_reshim_with_shims_on_path test_uninstall test_install_before test_install_short_ignores_full_backend_config test_install_dry_run test_install_concurrent_via_exec` — all pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes runtime symlink rebuild behavior across both user and shared/system install dirs, which could affect installs/reshims if edge cases exist. It also removes permission-error swallowing for shared dirs, so genuine mismatches in read-only system installs will now fail loudly. > > **Overview** > Prevents `mise install` from rewriting existing runtime symlinks when they already point at the desired target, avoiding unnecessary deletes/recreates that previously caused `Permission denied` failures on read-only system install directories. > > Refactors shared/system install-dir enumeration into `install_dirs_for` and removes the prior "skip on permission error" behavior; shared/system dirs are now treated like user dirs, but the rebuild path should be a no-op unless a change is actually needed. Adds an E2E regression test (`test_install_system_readonly`) that simulates a read-only system installs dir and asserts installs succeed without system-dir warnings. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit acf5798. 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]>
Configuration menu - View commit details
-
Copy full SHA for a0eff6d - Browse repository at this point
Copy the full SHA a0eff6dView commit details -
chore(docs): switch canonical domain to mise.en.dev (#9411)
## Summary - Swap every in-repo reference to `mise.jdx.dev` over to `mise.en.dev` (CLI help text, docs, schemas, install scripts, packaging metadata, e2e fixtures, generated files including the man page, `mise.usage.kdl`, and the lockfile header). - 86 files changed; both URLs serve the same content (symlinked), so the old URL keeps working — no coordinated cutover required. - `scripts/update-redirect.sh`: `ZONE_ID` swapped to the en.dev Cloudflare zone. ## Intentionally not changed - `[email protected]` / `[email protected]` email addresses (mailbox routing only exists on the old domain). - Historical `CHANGELOG.md` entry. ## Reviewer note `scripts/update-redirect.sh` still has the old `RULESET_ID`/`RULE_ID` — those are scoped to the jdx.dev zone and need to be re-derived against the en.dev zone before the script is run again. Flagging here so it isn't forgotten. ## Test plan - [x] `mise run build` - [x] `mise run lint` - [ ] Spot-check `man/man1/mise.1` and a couple of `docs/cli/*.md` URLs render correctly - [ ] Run one HTTP-fixture e2e (`mise run test:e2e test_http`) to confirm `mise.en.dev/test-fixtures/...` resolves 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Mostly mechanical URL/hostname rewrites, but it touches distribution-critical paths (install script URLs, version check, packaging repos, Cloudflare worker/test fixtures) where a missed/incorrect domain could break installs or CI/e2e downloads. > > **Overview** > Switches the project’s canonical hostname from `mise.jdx.dev` to `mise.en.dev` across the repo, updating docs, CLI help/manpage text, JSON schema `$id`s, lockfile header generation, and test/fixture URLs. > > Updates release/install and packaging metadata to fetch assets/keys/repos from `mise.en.dev` (including bootstrap/tool-stub generation and `mise version` checks), and adjusts the Cloudflare worker proxy targets accordingly. > > Removes the Cloudflare deploy workflow’s redirect-update step and deletes `scripts/update-redirect.sh`. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 57cde68. 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]>
Configuration menu - View commit details
-
Copy full SHA for 8029ff0 - Browse repository at this point
Copy the full SHA 8029ff0View commit details -
Signed-off-by: jylenhof <[email protected]>
Configuration menu - View commit details
-
Copy full SHA for 1963735 - Browse repository at this point
Copy the full SHA 1963735View commit details -
chore: release 2026.4.23 (#9396)
### 🚀 Features - **(backend)** add global libc preference by @jdx in [#9404](#9404) - opt-in to pre-release versions for github and aqua backends by @jakedgy in [#9329](#9329) ### 🐛 Bug Fixes - **(backend)** allow unresolved latest opt-in by @jdx in [#9401](#9401) - **(install)** stop rewriting healthy runtime symlinks by @jdx in [#9410](#9410) - **(node)** route musl tarball URLs to unofficial-builds by @jdx in [#9409](#9409) - **(prune)** skip remote version resolution for tracked configs by @jdx in [#9406](#9406) - **(schema)** allow array values in tool additionalProperties by @JP-Ellis in [#9400](#9400) ### 📦️ Dependency Updates - bump communique to 1.1.2 by @jdx in [#9402](#9402) ### 📦 Registry - use aqua for rumdl by @scop in [#9397](#9397) ### Chore - **(ci)** improve pr-closer workflow by @jdx in [#9403](#9403) - **(release)** stop appending sponsor blurb when communique succeeds by @jdx in [#9395](#9395) ### New Contributors - @JP-Ellis made their first contribution in [#9400](#9400)
Configuration menu - View commit details
-
Copy full SHA for 9225550 - Browse repository at this point
Copy the full SHA 9225550View commit details
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff 798ca8d...9225550