rules_mise 1.0.1Latest published <1h ago
MODULE.bazel
bazel_dep(name = "rules_mise", version = "1.0.1")
README

Bazel rules for mise

A Bazel module that exposes tools installed via mise as Bazel dependencies. It is an alternative to rules_multitool that reuses your existing mise.lock instead of maintaining a separate lockfile. The same mise.toml / mise.lock drives both your local developer environment (mise install) and your Bazel toolchains, so tools don't have to run through Bazel to stay pinned to the same version — handy for linters and other dev tools you also run outside Bazel (see e2e/smoke, which uses ruff both ways).

Usage

First, define the tools you want in mise.toml:

[tools]
ruff = "latest"

Generate the lockfile with mise:

mise lock

In your MODULE.bazel, add the bazel_dep from the release you wish to use (see https://github.com/amartani/rules_mise/releases for available versions):

bazel_dep(name = "rules_mise", version = "0.6.2")

Then set up the extension and register the toolchains:

mise = use_extension("@rules_mise//mise:extensions.bzl", "mise")
mise.hub(lockfile = "//:mise.lock")
use_repo(mise, "mise")

register_toolchains("@mise//toolchains:all")

Then depend on tools through the toolchain-resolved targets:

@mise//tools/ruff                 -> ruff for the current platform
@mise//tools/ruff:cwd             -> wrapper running ruff from the current directory
@mise//tools/ruff:workspace_root  -> wrapper running ruff from $BUILD_WORKSPACE_DIRECTORY

Only lockfile entries with a downloadable url on a supported platform (linux-x64, linux-arm64, macos-x64, macos-arm64, windows-x64) are exposed; anything else is skipped with a warning. linux-*-musl entries are ignored (folded into the non-musl entry). A checksum is used when the lockfile records one; entries without a checksum (e.g. http: backends) are still exposed, but the download cannot be verified and the tool repo is marked non-reproducible.

Supported mise backends

rules_mise exposes tools whose lockfile entries contain direct download URLs. That covers these backends (all exercised in e2e/backends, except conda which is exercised in e2e/conda):

Backend Supported Notes
aqua yes includes registry shorthand entries such as ruff = "latest"
conda yes (experimental) needs a conda-forge package, see e2e/conda
core yes e.g. bun, node
forgejo yes self-hosted instances via the api_url tool option
github yes
gitlab yes
http yes records no checksums: downloads are unverified and non-reproducible
packslip yes

These backends record no usable URLs in mise.lock (they install via a language runtime, plugin scripts, or install-time API resolution), so supporting them would require significant additional work and they are skipped with a warning: asdf, cargo, dotnet, gem, go, npm, pipx, s3, spm, ubi, vfox. Single-file-compressed assets such as taplo's .gz files (as opposed to .tar.gz archives) are also skipped.

Conda environments

Tools that don't ship easily usable statically compiled binaries — e.g. PostgreSQL (conda:postgresql, see e2e/conda) — can come from mise's conda: backend instead.

Each conda: tool gets its own conda prefix, which is not enough for PostgreSQL extensions: pgvector installs lib/vector.so and share/extension/vector.control, and a server can only load them from its own prefix. Adding both conda:postgresql and conda:pgvector to a lockfile leaves them in separate prefixes, so CREATE EXTENSION vector fails.

mise.conda_env installs several conda packages into a single prefix instead:

mise = use_extension("@rules_mise//mise:extensions.bzl", "mise")
mise.hub(lockfile = "//:mise.lock")
mise.conda_env(
    name = "pg",
    lockfile = "//:mise.lock",
    tools = [
        "conda:postgresql@18.4",
        "conda:pgvector@0.8.1",
    ],
)
use_repo(mise, "mise")

Each environment is exposed as a tool of its own, keyed conda_env_<name>, with the same targets as any other tool:

@mise//tools/conda_env_pg  -> runs any binary in the merged prefix

tools entries are mise tool names with an optional @version, resolved against the same mise.lock. An environment holds one build of each conda package, so members whose closures disagree (here libpq 18.4 vs 18.6) are merged by package name with the highest version winning, and each dropped build is reported. A platform is only offered when every member has a build for it. See e2e/conda-env.

Installation

From the release you wish to use: https://github.com/amartani/rules_mise/releases copy the Bzlmod snippet into your MODULE.bazel file (see Usage).

To use a commit rather than a release, you can point at any SHA of the repo with an archive_override in MODULE.bazel.

For example to use commit abc123:

archive_override(
    module_name = "rules_mise",
    url = "https://github.com/amartani/rules_mise/archive/abc123.tar.gz",
    strip_prefix = "rules_mise-abc123",
    # The easiest way to set this is to comment out this line, then Bazel will print
    # a message with the correct value. Note that GitHub archives lack a strong
    # guarantee on the sha256 stability, see <https://github.blog/2023-02-21-update-on-the-future-stability-of-source-code-archives-and-hashes/>
    integrity = "...",
)

About

Use mise-en-place tools from bazel

@amartani/rules_mise@amartani

Languages

Python29.7%
Perl3.3%
Pkl1.5%
Shell1%
Batchfile0.2%

Maintainers

@amartani

Versions

1.0.1 +18d2026-11-15
1.0.0 +4d2026-10-27
0.7.0 +19d2026-10-23
0.6.1 +7d2026-10-03
0.5.0 +1d2026-09-26
0.4.0 +9d2026-09-25
0.3.42026-09-15