Switches the project's package-manager surface from a mix of npm / pnpm / bun (different commands in different files) to a single tool: [aube](https://aube.en.dev), en.dev's pnpm-compat package manager (native Rust, fast, drops cleanly into pnpm / npm-compatible workflows). ## What changed - **Workflows** (`.github/workflows/*.yml`): every `npm ci` → `aube ci`; every `npm run X` → `aube run X`. The `actions/setup-node@…` step still pins Node, then a new `jdx/mise-action@v4` step with `install_args: aube` installs aube. The `cache: npm` directive on `setup-node` is dropped (aube uses its own store under `~/.cache/aube`; reusing the npm cache wouldn't help). - **`mise.toml`**: every task that ran `npm run X` or `bun run X` now runs `aube run X`. Added `aube = '1.3'` to the tool list so `mise install` provisions it locally. - **`CLAUDE.md`**: development command snippets updated to `aube install` / `aube run all` etc. ## What didn't change - **`package-lock.json`** stays as the canonical lockfile — aube reads it directly, no separate `aube-lock.yaml` is generated. Running `npm install` still works for any dev who hasn't switched to aube yet. - **`package.json` scripts** still use `npm run X` for nested invocations (e.g. `"all": "npm run format:write && …"`). The literal `npm` in those works for both npm callers and aube callers (aube exec'd shell finds `npm` in PATH; the inner invocation reads the same package.json scripts). Avoiding the rewrite to `aube run X` here keeps the scripts PM-agnostic. - **`dist/`** is byte-identical after `aube run all` — parity with npm-built dist verified locally before this commit. ## `.npmrc` Adds a single line: `node-linker=hoisted`. This is the pnpm/aube key that forces a flat, npm-style `node_modules` layout instead of the default symlink/virtual-store layout. Required because `rollup --configPlugin @rollup/plugin-typescript` needs to resolve the plugin from cwd's node_modules; the isolated layout puts rollup under `node_modules/.aube/...` where standard module resolution can't reach back to the project root for the plugin. npm reads `.npmrc` too but ignores `node-linker` (npm always installs flat), so the file is safe for both PMs. ## Why aube Single tool replacing three: less context-switching for contributors, fewer places to run `npm audit` / `bun upgrade` / `pnpm dedupe`, and aube's resolver is faster than npm's (the `aube install` cold-cache run takes ~3s vs `npm ci` at ~10s for this repo's deps). |
||
|---|---|---|
| .github | ||
| .husky | ||
| dist | ||
| scripts | ||
| src | ||
| .eslintrc.yml | ||
| .gitattributes | ||
| .gitignore | ||
| .npmrc | ||
| .prettierignore | ||
| .prettierrc.json | ||
| action.yml | ||
| CHANGELOG.md | ||
| CLAUDE.md | ||
| cliff.toml | ||
| CODEOWNERS | ||
| eslint.config.mjs | ||
| LICENSE | ||
| mise.lock | ||
| mise.toml | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| rollup.config.mjs | ||
| tsconfig.json | ||
Example Workflow
name: test
on:
pull_request:
branches:
- main
push:
branches:
- main
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: jdx/mise-action@v4
with:
version: 2026.3.10 # [default: latest] mise version to install
install: true # [default: true] run `mise install`
install_args: "bun" # [default: ""] additional arguments to `mise install`
cache: true # [default: true] cache mise using GitHub's cache
experimental: true # [default: false] enable experimental features
log_level: debug # [default: info] log level
# automatically write this .tool-versions file
tool_versions: |
shellcheck 0.11.0
# or, if you prefer .mise.toml format:
mise_toml: |
[tools]
shellcheck = "0.11.0"
working_directory: app # [default: .] directory to run mise in
reshim: false # [default: false] run `mise reshim -f`
github_token: ${{ secrets.GITHUB_TOKEN }} # [default: ${{ github.token }}] GitHub token for API authentication
- run: shellcheck scripts/*.sh
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: jdx/mise-action@v4
# .tool-versions will be read from repo root
- run: node ./my_app.js
Cache Configuration
You can customize the cache key used by the action:
- uses: jdx/mise-action@v4
with:
cache_key: "my-custom-cache-key" # Override the entire cache key
cache_key_prefix: "mise-v1" # Or just change the prefix (default: "mise-v0")
Template Variables in Cache Keys
When using cache_key, you can use template variables to reference internal values:
- uses: jdx/mise-action@v4
with:
cache_key: "mise-{{platform}}-{{version}}-{{file_hash}}"
version: "2026.3.10"
install_args: "node python"
Available template variables:
{{version}}- The mise version (from theversioninput){{cache_key_prefix}}- The cache key prefix (fromcache_key_prefixinput or default){{platform}}- The target platform (e.g., "linux-x64", "macos-arm64"){{file_hash}}- Hash of all mise configuration files{{mise_env}}- The MISE_ENV environment variable value{{install_args_hash}}- SHA256 hash of the sorted tools from install args{{default}}- The processed default cache key (useful for extending)
Conditional logic is also supported using Handlebars syntax like {{#if version}}...{{/if}}.
Example using multiple variables:
- uses: jdx/mise-action@v4
with:
cache_key: "mise-v1-{{platform}}-{{install_args_hash}}-{{file_hash}}"
install_args: "node@24 python@3.14"
You can also extend the default cache key:
- uses: jdx/mise-action@v4
with:
cache_key: "{{default}}-custom-suffix"
install_args: "node@24 python@3.14"
This gives you full control over cache invalidation based on the specific aspects that matter to your workflow.
GitHub API Rate Limits
When installing tools hosted on GitHub (like gh, node, bun, etc.), mise needs to make API calls to GitHub's releases API. Without authentication, these calls are subject to GitHub's rate limit of 60 requests per hour, which can cause installation failures.
- uses: jdx/mise-action@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
# your other configuration
Note: The action automatically uses ${{ github.token }} as the default, so in most cases you don't need to explicitly provide it. However, if you encounter rate limit errors, make sure the token is being passed correctly.
Alternative Installation
Alternatively, mise is easy to use in GitHub Actions even without this:
jobs:
build:
steps:
- run: |
curl https://mise.run | sh
echo "$HOME/.local/share/mise/bin" >> $GITHUB_PATH
echo "$HOME/.local/share/mise/shims" >> $GITHUB_PATH