Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 42 additions & 11 deletions docs/dev-tools/backends/github.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,37 @@ Specifies the pattern to match against release asset names. This is useful when
"github:cli/cli" = { version = "latest", asset_pattern = "gh_*_linux_x64.tar.gz" }
```

### `additional_asset_patterns`

Downloads additional archives from the same release and extracts them into the primary
asset's install directory, in the order listed. Use this when an upstream distributes one
installation across a base archive and one or more supplemental archives.

For example, Ollama publishes its Linux AMD64 ROCm support as an archive that must be
overlaid on the normal Ollama archive:

```toml
[tools."github:ollama/ollama"]
version = "latest"

[tools."github:ollama/ollama".platforms]
linux-x64 = {
additional_asset_patterns = ["ollama-linux-amd64-rocm.tar.zst"],
}
```

Each pattern must select exactly one archive. Patterns support the same templating as
[`asset_pattern`](#asset_pattern). Supplemental assets must be archives; bare binaries
are not supported. They are extracted without applying the primary asset's
`strip_components`, `bin`, or `rename_exe` options. If a supplemental archive contains
the same path as an earlier archive, the later archive's file wins.

When lockfiles are enabled, mise records the URL and checksum for each supplemental
artifact, plus any available provenance metadata. Provenance is cryptographically
verified for the current platform; cross-platform lock entries record detected
provenance for verification when installed. `--locked` installations use only the
recorded artifact list and fail if it is incomplete.

### `matching`

Narrows asset selection to names containing the given substring, **while keeping platform autodetection**. Unlike [`asset_pattern`](#asset_pattern) (which replaces autodetection entirely), `matching` only refines the candidate set — autodetection still chooses the correct OS/arch from the narrowed list, so a single config stays portable across platforms.
Expand Down Expand Up @@ -134,10 +165,14 @@ macos-arm64 = { asset_pattern = "gh_*_macOS_arm64.tar.gz" }

### Multiple Assets from the Same Release

The GitHub backend installs one release asset for each tool. If a repository publishes
multiple binaries as separate assets in the same release, define one tool alias per
binary and point each alias at the same `github:owner/repo` backend, then narrow each
alias to its binary.
There are two distinct cases:

- If the assets are parts of one installation, use
[`additional_asset_patterns`](#additional_asset_patterns). The supplemental archives
are overlaid into the same install directory.
- If the assets are independent tools that should have separate install directories,
define one tool alias per binary and point each alias at the same
`github:owner/repo` backend.

Prefer [`matching`](#matching) (or [`matching_regex`](#matching_regex)): it narrows the
candidate set while **keeping platform autodetection**, so one config works on every
Expand Down Expand Up @@ -167,13 +202,9 @@ rename_exe = "oxfmt"
```

::: warning
A distinct alias per binary is **required**, not just tidy. `matching`/`matching_regex` are
**not** part of the install path — it is keyed by the tool name (the alias, or `owner/repo`
when unaliased) and version. Installing the same `github:owner/repo` backend string twice
with different `matching` values (for example `mise use "github:owner/repo[matching=tool-a]"`
followed by `mise use "github:owner/repo[matching=tool-b]"`) resolves to the **same**
directory, so the second install overwrites the first. Giving each binary its own alias gives
each its own install directory, so they coexist.
Aliases are not an overlay mechanism. Each alias creates a separate install directory.
Use them for independent binaries such as `oxlint` and `oxfmt`; use
`additional_asset_patterns` when both archives must compose one runnable tool.
:::

If the binary isn't named the way you want to invoke it, add
Expand Down
52 changes: 52 additions & 0 deletions e2e/backend/test_github_additional_assets
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/usr/bin/env bash

export MISE_EXPERIMENTAL=1
export MISE_LOCKFILE=1

cat <<EOF >mise.toml
[tools."github:jdx/mise-test-fixtures"]
version = "1.0.0"
asset_pattern = "hello-world-1.0.0.tar.gz"
additional_asset_patterns = ["fd-8.7.0.tar.gz"]
EOF

touch mise.lock
mise install

# Both archives are extracted into one installation.
install_path=$(mise where github:jdx/mise-test-fixtures)
assert_contains "$install_path/hello-world-1.0.0/bin/hello-world" "hello world"
assert_contains "$install_path/fd-8.7.0/bin/fd" "alternative to 'find'"

# The supplemental artifact is independently pinned and checksummed.
assert_contains "cat mise.lock" 'additional_asset_patterns = "fd-8.7.0.tar.gz"'
assert_contains "cat mise.lock" 'url = "https://github.com/jdx/mise-test-fixtures/releases/download/v1.0.0/fd-8.7.0.tar.gz"'
assert_contains "cat mise.lock" 'checksum = "sha256:230cf587de59730a1d7f9c49004f301292927621a336578723518fc9d03f4824"'

# Locked mode must reject an incomplete supplemental artifact list.
cp mise.lock mise.lock.complete
mise uninstall github:jdx/mise-test-fixtures
awk '
/^\[\[tools\."github:jdx\/mise-test-fixtures"\."platforms\..*"\.additional_artifacts\]\]$/ {
skip_artifact = 1
next
}
skip_artifact && /^$/ {
skip_artifact = 0
next
}
!skip_artifact { print }
' mise.lock.complete >mise.lock
assert_fail "mise install --locked"

# Locked mode must also reject removing the supplemental pattern from config.
cp mise.lock.complete mise.lock
cp mise.toml mise.toml.complete
sed '/additional_asset_patterns/d' mise.toml.complete >mise.toml
assert_fail "mise install --locked"

# Restoring the complete config and lock permits the reinstall.
cp mise.toml.complete mise.toml
mise install --locked
install_path=$(mise where github:jdx/mise-test-fixtures)
assert_contains "$install_path/fd-8.7.0/bin/fd" "alternative to 'find'"
Loading
Loading