Skip to content

fix(install): support aliased installs sharing a backend#9093

Merged
jdx merged 1 commit intomainfrom
codex/alias-github-install-dedup
Apr 15, 2026
Merged

fix(install): support aliased installs sharing a backend#9093
jdx merged 1 commit intomainfrom
codex/alias-github-install-dedup

Conversation

@jdx
Copy link
Copy Markdown
Owner

@jdx jdx commented Apr 15, 2026

Summary

  • Key install dependency graph nodes by configured tool short name plus version, so aliases that resolve to the same backend/version are scheduled independently.
  • Use the same alias-aware key when preserving install result order.
  • Extend the GitHub tool_alias asset-pattern e2e test to cover two aliases sharing one GitHub backend/version with different assets.

Root Cause

ToolDeps previously keyed scheduler nodes as <backend full>@<version>. Distinct aliases like iii and iii-console can both resolve to github:iii-hq/iii@latest, so the dependency graph collapsed the second request as a duplicate and skipped its install job.

Impact

Aliases that point at the same backend release can now install separately while keeping alias-specific options such as asset_pattern, bin_path, and postinstall. Duplicate requests for the same configured tool/version remain deduplicated.

Fixes #9074

Validation

  • cargo fmt
  • cargo test toolset::tool_deps::tests::test_aliases_to_same_backend_are_distinct
  • ./e2e/run_test e2e/backend/test_github_tool_alias_asset_pattern
  • commit hook suite via hk, including cargo check --all-features, cargo fmt --all -- --check, shellcheck, shfmt, schema validation, and related linters

Note

Medium Risk
Changes install scheduling keys from backend+version to tool short-name+version, which affects dependency graph deduplication and install ordering and could impact parallel install behavior for tools with shared backends.

Overview
Fixes an install scheduler edge case where multiple configured aliases resolving to the same backend/version were incorrectly deduplicated into a single install job.

ToolDeps now keys dependency-graph nodes by tool short name@version (via shared tool_key), and toolset_install uses the same key to preserve original request ordering. Adds coverage via a new unit test for distinct aliases and extends the GitHub e2e tool_alias asset_pattern test to assert both aliases install into their own directories with their own assets.

Reviewed by Cursor Bugbot for commit 7d8b14f. Bugbot is set up for automated code reviews on this repo. Configure here.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the tool dependency logic to use the tool's short name instead of the full backend name when generating unique keys for tool requests. This change ensures that distinct aliases pointing to the same backend are treated as separate installation jobs, allowing them to maintain unique configurations such as asset patterns and installation directories. The PR includes a new E2E regression test, a unit test for the dependency graph, and refactors existing code to use the centralized tool_key function. I have no feedback to provide.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 15, 2026

Greptile Summary

This PR fixes a bug where multiple tool aliases pointing to the same backend/version (e.g., iii and iii-console both mapping to github:iii-hq/iii@latest) were incorrectly deduplicated by the install scheduler, causing only one of them to be installed. The fix changes the dependency-graph node key from <backend_full>@<version> to <tool_short_name>@<version>, so distinct aliases get distinct scheduler slots and each installs with its own options (e.g., asset_pattern, bin_path). True duplicates (same short name and same version) are still deduplicated as intended.

Confidence Score: 5/5

Safe to merge — the fix is narrow, well-tested with both a new unit test and an extended e2e, and the key-scheme change is internally consistent across all usage sites.

All findings are P2 or lower. The logic change correctly distinguishes alias-keyed nodes from backend-keyed ones, deduplication of true duplicates (same short name + version) is preserved, and the dependency-edge computation via all_fulls() is unaffected by the key change. Unit test exercises the exact failure scenario; e2e validates end-to-end directory isolation per alias.

No files require special attention.

Important Files Changed

Filename Overview
src/toolset/tool_deps.rs Core fix: tool_key now uses ba().short (alias-aware) instead of ba().full() (resolved backend), preventing two aliases to the same backend from being deduplicated; new async unit test validates the fix correctly using try_recv() on a pre-populated unbounded channel.
src/toolset/toolset_install.rs Aligned request_order map construction and installed.sort_by_key to use the shared tool_key() helper, ensuring request-order preservation is consistent with the new alias-aware key scheme.
e2e/backend/test_github_tool_alias_asset_pattern Extended the GitHub tool-alias e2e to use two distinct aliases (hw1, hw2) both pointing to the same backend/version with different asset_patterns, and added a directory-existence assertion for each alias's separate install path.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["ToolRequest list\n(hw1@1.0.0, hw2@1.0.0)"] --> B["tool_key(tr)\n= ba().short + '@' + version"]

    B --> C1["hw1@1.0.0"]
    B --> C2["hw2@1.0.0"]

    subgraph OLD ["Before PR (full backend key)"]
        D["github:jdx/mise-test-fixtures@1.0.0\n(SAME KEY — deduplicated!)"]
        D2["Only 1 install scheduled"]
    end

    subgraph NEW ["After PR (short alias key)"]
        E1["hw1@1.0.0 → distinct node"]
        E2["hw2@1.0.0 → distinct node"]
        E1 --> F1["Installs to installs/hw1/1.0.0\nwith asset_pattern hello-world-1.0.0.tar.gz"]
        E2 --> F2["Installs to installs/hw2/1.0.0\nwith asset_pattern hello-world-2.0.0.tar.gz"]
    end

    C1 -.->|was| D
    C2 -.->|was| D
    C1 --> E1
    C2 --> E2
Loading

Reviews (2): Last reviewed commit: "fix(install): support aliased installs s..." | Re-trigger Greptile

@jdx jdx marked this pull request as ready for review April 15, 2026 00:22
@jdx jdx force-pushed the codex/alias-github-install-dedup branch from 05115c0 to 7d8b14f Compare April 15, 2026 00:26
@jdx jdx changed the title [codex] Support aliased installs sharing a backend fix(install): support aliased installs sharing a backend Apr 15, 2026
@jdx jdx merged commit 88d8c7b into main Apr 15, 2026
38 checks passed
@jdx jdx deleted the codex/alias-github-install-dedup branch April 15, 2026 00:45
@github-actions
Copy link
Copy Markdown

Hyperfine Performance

mise x -- echo

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.4.11 x -- echo 23.7 ± 0.7 22.1 27.1 1.00
mise x -- echo 24.5 ± 0.7 22.7 27.6 1.03 ± 0.04

mise env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.4.11 env 23.6 ± 0.9 21.7 30.2 1.00
mise env 24.0 ± 0.7 22.4 26.1 1.02 ± 0.05

mise hook-env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.4.11 hook-env 24.1 ± 1.0 22.5 32.9 1.00
mise hook-env 24.7 ± 1.0 22.6 32.7 1.03 ± 0.06

mise ls

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.4.11 ls 22.0 ± 0.6 20.5 26.9 1.00
mise ls 22.4 ± 0.8 20.6 27.4 1.02 ± 0.05

xtasks/test/perf

Command mise-2026.4.11 mise Variance
install (cached) 155ms 153ms +1%
ls (cached) 80ms 79ms +1%
bin-paths (cached) 84ms 85ms -1%
task-ls (cached) 832ms 808ms +2%

mise-en-dev added a commit that referenced this pull request Apr 15, 2026
### 🚀 Features

- **(npm)** use --min-release-age for npm 11.10.0+ supply chain
protection by @webkaz in [#9072](#9072)
- **(registry)** add openfga by @mnm364 in
[#9084](#9084)
- **(task)** allow to set confirmation default by @roele in
[#9089](#9089)
- support os/arch compound syntax in tool os filtering by @RobertDeRose
in [#9088](#9088)

### 🐛 Bug Fixes

- **(activate)** export __MISE_EXE and resolve bare ARGV0 to absolute
path by @fru1tworld in [#9081](#9081)
- **(install)** support aliased installs sharing a backend by @jdx in
[#9093](#9093)
- **(shim)** use which_no_shims when resolving mise binary in reshim and
doctor by @kevinswiber in [#9071](#9071)
- filter empty segments in colon-separated env var parsing by @baby-joel
in [#9076](#9076)

### 📚 Documentation

- fix wrong file reference to forgejo backend implemenation by @roele in
[#9090](#9090)
- fix cli token command for token resolution by @roele in
[#9077](#9077)

### 📦 Registry

- add trzsz-go
([aqua:trzsz/trzsz-go](https://github.com/trzsz/trzsz-go)) by
@ZeroAurora in [#9083](#9083)
- add copilot
([aqua:github/copilot-cli](https://github.com/github/copilot-cli)) by
@risu729 in [#9082](#9082)

### Chore

- add AGENTS.md symlink by @jdx in
[#9094](#9094)

### New Contributors

- @kevinswiber made their first contribution in
[#9071](#9071)
- @webkaz made their first contribution in
[#9072](#9072)
- @RobertDeRose made their first contribution in
[#9088](#9088)

## 📦 Aqua Registry Updates

#### New Packages (7)

-
[`IBM-Cloud/ibm-cloud-cli-release`](https://github.com/IBM-Cloud/ibm-cloud-cli-release)
- [`max-sixty/worktrunk`](https://github.com/max-sixty/worktrunk)
- [`micelio.dev/hif`](https://github.com/micelio.dev/hif)
- [`pgplex/pgschema`](https://github.com/pgplex/pgschema)
-
[`rose-pine/rose-pine-bloom`](https://github.com/rose-pine/rose-pine-bloom)
- [`santosr2/TerraTidy`](https://github.com/santosr2/TerraTidy)
- [`trzsz/trzsz-go`](https://github.com/trzsz/trzsz-go)

#### Updated Packages (3)

- [`mvdan/sh`](https://github.com/mvdan/sh)
- [`rvben/rumdl`](https://github.com/rvben/rumdl)
- [`temporalio/temporal`](https://github.com/temporalio/temporal)
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request Apr 16, 2026
## [2026.4.14](https://github.com/jdx/mise/compare/v2026.4.13..v2026.4.14) - 2026-04-15

### Chore

- bump sigstore-verification by @jdx in [#9128](jdx/mise#9128)

## [2026.4.13](https://github.com/jdx/mise/compare/v2026.4.12..v2026.4.13) - 2026-04-15

### 🐛 Bug Fixes

- **(go)** honor install_before for module versions by @mariusvniekerk in [#9097](jdx/mise#9097)
- **(vfox-plugin)** support Git URL with commit hash for mise.toml by @Oyami-Srk in [#9099](jdx/mise#9099)
- `MISE_FETCH_REMOTE_VERSIONS_CACHE` not respected by @mcncl in [#9096](jdx/mise#9096)

### 📦️ Dependency Updates

- unblock cargo-deny advisories check by @jdx in [#9112](jdx/mise#9112)

### New Contributors

- @mariusvniekerk made their first contribution in [#9097](jdx/mise#9097)
- @mcncl made their first contribution in [#9096](jdx/mise#9096)
- @Oyami-Srk made their first contribution in [#9099](jdx/mise#9099)

## [2026.4.12](https://github.com/jdx/mise/compare/v2026.4.11..v2026.4.12) - 2026-04-15

### 🚀 Features

- **(npm)** use --min-release-age for npm 11.10.0+ supply chain protection by @webkaz in [#9072](jdx/mise#9072)
- **(registry)** add openfga by @mnm364 in [#9084](jdx/mise#9084)
- **(task)** allow to set confirmation default by @roele in [#9089](jdx/mise#9089)
- support os/arch compound syntax in tool os filtering by @RobertDeRose in [#9088](jdx/mise#9088)

### 🐛 Bug Fixes

- **(activate)** export __MISE_EXE and resolve bare ARGV0 to absolute path by @fru1tworld in [#9081](jdx/mise#9081)
- **(install)** support aliased installs sharing a backend by @jdx in [#9093](jdx/mise#9093)
- **(shim)** use which_no_shims when resolving mise binary in reshim and doctor by @kevinswiber in [#9071](jdx/mise#9071)
- filter empty segments in colon-separated env var parsing by @baby-joel in [#9076](jdx/mise#9076)

### 📚 Documentation

- fix wrong file reference to forgejo backend implemenation by @roele in [#9090](jdx/mise#9090)
- fix cli token command for token resolution by @roele in [#9077](jdx/mise#9077)
jdx pushed a commit that referenced this pull request Apr 18, 2026
## Summary
- document the #9093 workaround syntax for installing multiple separate
assets from one GitHub release
- use generic `owner/repo` placeholders instead of discussion-specific
binaries

## Testing
- `./xtasks/lint-fix.sh`
- locally verified with `target/debug/mise` `2026.4.16-DEBUG` that two
aliases pointing at the same GitHub backend with different
`[tools.<alias>]` `asset_pattern` values install distinct assets
- confirmed #9093 uses the same `[tool_alias]` plus
`[tools.<alias>]` syntax

Context: #8266
Related fix: #9093

*This pull request was generated by an AI coding assistant.*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant