Compare commits

..

No commits in common. "main" and "v4.0.0" have entirely different histories.
main ... v4.0.0

31 changed files with 119955 additions and 87049 deletions

33
.github/workflows/autofix.yml vendored Normal file
View file

@ -0,0 +1,33 @@
name: autofix.ci
on:
pull_request:
push:
branches:
- main
permissions:
contents: read
jobs:
autofix:
runs-on: ubuntu-latest
steps:
- name: Checkout PR branch
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Setup Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
with:
node-version: '24'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build and package
run: npm run all
- name: autofix.ci
uses: autofix-ci/action@7a166d7532b277f34e16238930461bf77f9d7ed8 # v1

View file

@ -32,18 +32,20 @@ jobs:
- name: Checkout - name: Checkout
id: checkout id: checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
- uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # v4 - name: Setup Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
with:
node-version: 24
cache: npm
- name: Install Dependencies - name: Install Dependencies
id: install id: install
run: aube ci run: npm ci
- name: Build dist/ Directory - name: Build dist/ Directory
id: build id: build
run: aubr bundle run: npm run bundle
- name: Compare Expected and Actual Directories - name: Compare Expected and Actual Directories
id: diff id: diff
@ -56,7 +58,7 @@ jobs:
# If index.js was different than expected, upload the expected version as # If index.js was different than expected, upload the expected version as
# a workflow artifact. # a workflow artifact.
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
if: ${{ failure() && steps.diff.conclusion == 'failure' }} if: ${{ failure() && steps.diff.conclusion == 'failure' }}
with: with:
name: dist name: dist

View file

@ -7,9 +7,6 @@ on:
- main - main
- 'releases/*' - 'releases/*'
permissions:
contents: read
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }} group: ${{ github.workflow }}-${{ github.ref_name }}
cancel-in-progress: true cancel-in-progress: true
@ -23,30 +20,25 @@ jobs:
- name: Checkout - name: Checkout
id: checkout id: checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
# `mise.toml` pins both Node and aube; mise-action installs - name: Setup Node.js
# whatever's listed there. Reads `package-lock.json` id: setup-node
# directly — no separate `aube-lock.yaml` to maintain. uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
# `.npmrc` pins `node-linker=hoisted` so the layout is
# npm-flat (rollup's `--configPlugin` resolution
# requires this).
- uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # v4
with: with:
cache: false node-version: 24
cache: npm
- name: Install Dependencies - name: Install Dependencies
id: aube-ci id: npm-ci
run: aube ci run: npm ci
- name: Check Format - name: Check Format
id: aube-format-check id: npm-format-check
run: aubr format:check run: npm run format:check
- name: Lint - name: Lint
id: aube-lint id: npm-lint
run: aubr lint run: npm run lint
# - name: Test # - name: Test
# id: npm-ci-test # id: npm-ci-test

View file

@ -35,20 +35,18 @@ jobs:
- name: Checkout - name: Checkout
id: checkout id: checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
- name: Initialize CodeQL - name: Initialize CodeQL
id: initialize id: initialize
uses: github/codeql-action/init@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4 uses: github/codeql-action/init@820e3160e279568db735cee8ed8f8e77a6da7818 # v3
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
source-root: src source-root: src
- name: Autobuild - name: Autobuild
id: autobuild id: autobuild
uses: github/codeql-action/autobuild@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4 uses: github/codeql-action/autobuild@820e3160e279568db735cee8ed8f8e77a6da7818 # v3
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
id: analyze id: analyze
uses: github/codeql-action/analyze@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4 uses: github/codeql-action/analyze@820e3160e279568db735cee8ed8f8e77a6da7818 # v3

View file

@ -1,31 +0,0 @@
name: pr-closer
on:
schedule:
- cron: "0 0 * * *" # daily at midnight
workflow_dispatch:
jobs:
close-stale-prs:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- name: Close stale PRs
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh pr list -R "${{ github.repository }}" --state open --json number,author,labels,updatedAt,statusCheckRollup --limit 100 | \
jq -r '.[] | select(
(.updatedAt | fromdateiso8601) < (now - 30*24*60*60) and
.author.login != "jdx" and
([.labels[].name] | index("keep-open") | not)
) | [.number, (if (.statusCheckRollup | length > 0) and (.statusCheckRollup | any(.conclusion == "FAILURE" or .conclusion == "failure")) then "failing" else "passing" end)] | @tsv' | \
while read -r pr status; do
echo "Closing PR #$pr (checks: $status)"
if [ "$status" = "failing" ]; then
gh pr close "$pr" -R "${{ github.repository }}" -c "This PR has been open for more than 30 days without activity. Note: CI checks were failing, which may be why it wasn't reviewed. Feel free to reopen or create a new PR if you'd like to continue working on this."
else
gh pr close "$pr" -R "${{ github.repository }}" -c "This PR has been open for more than 30 days without activity. Feel free to reopen or create a new PR if you'd like to continue working on this."
fi
done

View file

@ -26,8 +26,7 @@ jobs:
fetch-depth: 0 fetch-depth: 0
submodules: recursive submodules: recursive
token: ${{ secrets.RELEASE_PLZ_GITHUB_TOKEN }} token: ${{ secrets.RELEASE_PLZ_GITHUB_TOKEN }}
persist-credentials: false - uses: jdx/mise-action@c37c93293d6b742fc901e1406b8f764f6fb19dac # v2
- uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # v4
- run: mise run release-plz - run: mise run release-plz
env: env:
DRY_RUN: 0 DRY_RUN: 0

View file

@ -5,45 +5,24 @@ on:
types: [closed] types: [closed]
branches: [main] branches: [main]
permissions: {} permissions:
contents: write
jobs: jobs:
release: release:
if: github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'release') if: github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'release')
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions:
contents: write
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with: with:
fetch-depth: 0 fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
persist-credentials: false
- name: Setup mise - name: Setup mise
uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # v4 uses: jdx/mise-action@c37c93293d6b742fc901e1406b8f764f6fb19dac # v2
- name: Release - name: Release
run: ./scripts/postversion.sh run: ./scripts/postversion.sh
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
enhance-release:
needs: [release]
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 0
persist-credentials: false
- uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # v4
- name: Enhance release notes with communique
run: |
TAG_NAME="v$(jq -r .version package.json)"
communique generate "$TAG_NAME" --github-release
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GITHUB_TOKEN: ${{ secrets.RELEASE_PLZ_GITHUB_TOKEN }}

19
.github/workflows/semantic-pr-lint.yml vendored Normal file
View file

@ -0,0 +1,19 @@
name: semantic-pr-lint
on:
pull_request_target:
types:
- opened
- edited
- reopened
jobs:
main:
name: Validate PR title
runs-on: ubuntu-latest
permissions:
pull-requests: read
steps:
- uses: amannn/action-semantic-pull-request@e32d7e603df1aa1ba07e981f2a23455dee596825 # v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View file

@ -7,17 +7,12 @@ on:
branches: [main] branches: [main]
workflow_dispatch: workflow_dispatch:
permissions:
contents: read
jobs: jobs:
test-redacted-env: test-redacted-env:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
- name: Create test mise config with sensitive values - name: Create test mise config with sensitive values
run: | run: |

View file

@ -8,9 +8,6 @@ on: # rebuild any PRs and main branch changes
- main - main
workflow_dispatch: workflow_dispatch:
permissions:
contents: read
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }} group: ${{ github.workflow }}-${{ github.ref_name }}
cancel-in-progress: true cancel-in-progress: true
@ -20,11 +17,10 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with: - run: |
persist-credentials: false npm install
- uses: jdx/mise-action@1648a7812b9aeae629881980618f079932869151 # v4 - run: |
- run: aube install npm run all
- run: aubr all
test: # make sure the action works on a clean machine without building test: # make sure the action works on a clean machine without building
strategy: strategy:
fail-fast: false fail-fast: false
@ -48,8 +44,6 @@ jobs:
if: ${{ matrix.requirements }} if: ${{ matrix.requirements }}
run: ${{ matrix.requirements }} run: ${{ matrix.requirements }}
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
- name: Setup mise - name: Setup mise
uses: ./ uses: ./
with: with:
@ -65,15 +59,6 @@ jobs:
- run: mise x jq -- jq --version - run: mise x jq -- jq --version
- run: which jq - run: which jq
- run: jq --version - run: jq --version
- name: Check Windows shim binary
if: runner.os == 'Windows'
shell: pwsh
run: |
$miseBinDir = Split-Path -Parent (Get-Command mise).Source
$miseShim = Join-Path $miseBinDir "mise-shim.exe"
if (!(Test-Path -LiteralPath $miseShim)) {
throw "mise-shim.exe was not installed next to mise.exe"
}
- run: . scripts/test.sh - run: . scripts/test.sh
shell: bash shell: bash
@ -81,8 +66,6 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
- name: Setup mise - name: Setup mise
uses: ./ uses: ./
with: with:
@ -108,8 +91,6 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
- name: Setup mise - name: Setup mise
id: bad id: bad
uses: ./ uses: ./
@ -127,18 +108,14 @@ jobs:
if: ${{ steps.bad.outcome == 'failure' }} if: ${{ steps.bad.outcome == 'failure' }}
- name: not failed as expected - name: not failed as expected
run: | run: |
echo "Expected failure but the job was ${STEPS_BAD_OUTCOME}" echo "Expected failure but the job was ${{ steps.bad.outcome }}"
exit 1 exit 1
if: ${{ steps.bad.outcome != 'failure' }} if: ${{ steps.bad.outcome != 'failure' }}
env:
STEPS_BAD_OUTCOME: ${{ steps.bad.outcome }}
custom_cache_key: custom_cache_key:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
- name: Setup mise with custom cache key - name: Setup mise with custom cache key
uses: ./ uses: ./
with: with:
@ -156,8 +133,6 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
- name: Setup mise from mise.jdx.dev - name: Setup mise from mise.jdx.dev
uses: ./ uses: ./
with: with:
@ -171,21 +146,3 @@ jobs:
- run: mise x jq -- jq --version - run: mise x jq -- jq --version
- run: which jq - run: which jq
- run: jq --version - run: jq --version
final:
needs:
- build
- test
- specific_version
- checksum_failure
- custom_cache_key
- fetch_from_github
runs-on: ubuntu-latest
timeout-minutes: 1
# Run on success or upstream failure but skip when the workflow is cancelled
# — `always()` would override `cancel-in-progress` and waste a runner.
if: ${{ !cancelled() }}
steps:
- name: Check CI job results
if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'skipped')
run: exit 1

View file

@ -1,22 +0,0 @@
name: zizmor
on:
push:
branches: [main]
paths: ['.github/workflows/**']
pull_request:
paths: ['.github/workflows/**']
permissions: {}
jobs:
zizmor:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
- uses: zizmorcore/zizmor-action@b1d7e1fb5de872772f31590499237e7cce841e8e # v0.5.3
with:
advanced-security: false

7
.gitignore vendored
View file

@ -101,10 +101,3 @@ __tests__/runner/*
.idea .idea
.vscode .vscode
*.code-workspace *.code-workspace
# Generated by `aube install` to record build-script approvals.
# We've chosen not to commit our approval state — the build doesn't
# need any package's install scripts to run, and the file gets
# regenerated each install anyway. The harmless "ignored build
# scripts" warning in `aube install` output is the cost.
pnpm-workspace.yaml

View file

@ -1,5 +1,4 @@
# shellcheck disable=SC1091 # shellcheck disable=SC1091
npm ci
npm run all npm run all
git add dist git add dist

11
.npmrc
View file

@ -1,11 +0,0 @@
# Forces a flat npm-style `node_modules/` layout instead of
# aube's default symlink/virtual-store. Required for
# deterministic `dist/index.js.map` source-map paths in CI:
# without flat layout, rollup embeds absolute paths into
# aube's per-user cache dir (`/home/runner/.cache/aube/...`),
# which differ across machines and break the `check-dist`
# workflow's byte-equality check.
#
# npm reads `.npmrc` too but ignores `node-linker` (npm
# always installs flat), so the file is safe for both PMs.
node-linker=hoisted

View file

@ -1,29 +1,5 @@
# Changelog # Changelog
---
## [4.0.1](https://github.com/jdx/mise-action/compare/v4.0.0..v4.0.1) - 2026-03-22
### 🐛 Bug Fixes
- run npm install in pre-commit hook before build (#410) by [@jdx](https://github.com/jdx) in [#410](https://github.com/jdx/mise-action/pull/410)
### 🚜 Refactor
- extract getCwd() helper to deduplicate working directory resolution (#403) by [@altendky](https://github.com/altendky) in [#403](https://github.com/jdx/mise-action/pull/403)
### 📚 Documentation
- bump versions listed im README.md (#407) by [@deining](https://github.com/deining) in [#407](https://github.com/jdx/mise-action/pull/407)
- bump more versions listed in README.md (#408) by [@deining](https://github.com/deining) in [#408](https://github.com/jdx/mise-action/pull/408)
### ⚙️ Miscellaneous Tasks
- add workflow to auto-close stale PRs (#409) by [@jdx](https://github.com/jdx) in [#409](https://github.com/jdx/mise-action/pull/409)
### New Contributors
* @deining made their first contribution in [#408](https://github.com/jdx/mise-action/pull/408)
--- ---
## [4.0.0](https://github.com/jdx/mise-action/compare/v3.6.3..v4.0.0) - 2026-03-13 ## [4.0.0](https://github.com/jdx/mise-action/compare/v3.6.3..v4.0.0) - 2026-03-13

View file

@ -8,29 +8,21 @@ This is a GitHub Action that installs and configures mise, a polyglot runtime ma
## Development Commands ## Development Commands
This project uses [aube](https://aube.en.dev) as its package
manager (en.dev's pnpm-compat PM, native Rust). It reads
`package-lock.json` directly — no separate `aube-lock.yaml`.
`mise install` will install the pinned aube version
automatically; you can also use `npm` if you prefer (the
`.npmrc`'s `node-linker=hoisted` pin is aube-specific and
ignored by npm).
```bash ```bash
# Install dependencies # Install dependencies
aube install npm install
# Build, format, lint, and package # Build, format, lint, and package
aubr all npm run all
# Individual commands # Individual commands
aubr format:write # Format code with Prettier npm run format:write # Format code with Prettier
aubr lint # Run ESLint and format check npm run lint # Run ESLint and format check
aubr package # Bundle with rollup for distribution npm run package # Bundle with ncc for distribution
# Testing # Testing
aubr all # Run full build pipeline npm run all # Run full build pipeline
./scripts/test.sh # Integration test script ./scripts/test.sh # Integration test script
``` ```
## Architecture ## Architecture
@ -58,6 +50,6 @@ The action follows GitHub's standard TypeScript action structure:
## Important Notes ## Important Notes
- Always run `aubr all` before committing to ensure dist/ is updated - Always run `npm run all` before committing to ensure dist/ is updated
- The dist/ folder must be committed as GitHub Actions runs the compiled code - The dist/ folder must be committed as GitHub Actions runs the compiled code
- Test changes using the action itself (uses: ./) in test workflows - Test changes using the action itself (uses: ./) in test workflows

View file

@ -13,10 +13,10 @@ jobs:
lint: lint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v4
- uses: jdx/mise-action@v4 - uses: jdx/mise-action@v3
with: with:
version: 2026.3.10 # [default: latest] mise version to install version: 2024.10.0 # [default: latest] mise version to install
install: true # [default: true] run `mise install` install: true # [default: true] run `mise install`
install_args: "bun" # [default: ""] additional arguments to `mise install` install_args: "bun" # [default: ""] additional arguments to `mise install`
cache: true # [default: true] cache mise using GitHub's cache cache: true # [default: true] cache mise using GitHub's cache
@ -24,11 +24,11 @@ jobs:
log_level: debug # [default: info] log level log_level: debug # [default: info] log level
# automatically write this .tool-versions file # automatically write this .tool-versions file
tool_versions: | tool_versions: |
shellcheck 0.11.0 shellcheck 0.9.0
# or, if you prefer .mise.toml format: # or, if you prefer .mise.toml format:
mise_toml: | mise_toml: |
[tools] [tools]
shellcheck = "0.11.0" shellcheck = "0.9.0"
working_directory: app # [default: .] directory to run mise in working_directory: app # [default: .] directory to run mise in
reshim: false # [default: false] run `mise reshim -f` reshim: false # [default: false] run `mise reshim -f`
github_token: ${{ secrets.GITHUB_TOKEN }} # [default: ${{ github.token }}] GitHub token for API authentication github_token: ${{ secrets.GITHUB_TOKEN }} # [default: ${{ github.token }}] GitHub token for API authentication
@ -36,8 +36,8 @@ jobs:
test: test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v4
- uses: jdx/mise-action@v4 - uses: jdx/mise-action@v3
# .tool-versions will be read from repo root # .tool-versions will be read from repo root
- run: node ./my_app.js - run: node ./my_app.js
``` ```
@ -47,7 +47,7 @@ jobs:
You can customize the cache key used by the action: You can customize the cache key used by the action:
```yaml ```yaml
- uses: jdx/mise-action@v4 - uses: jdx/mise-action@v3
with: with:
cache_key: "my-custom-cache-key" # Override the entire cache key cache_key: "my-custom-cache-key" # Override the entire cache key
cache_key_prefix: "mise-v1" # Or just change the prefix (default: "mise-v0") cache_key_prefix: "mise-v1" # Or just change the prefix (default: "mise-v0")
@ -58,17 +58,17 @@ You can customize the cache key used by the action:
When using `cache_key`, you can use template variables to reference internal values: When using `cache_key`, you can use template variables to reference internal values:
```yaml ```yaml
- uses: jdx/mise-action@v4 - uses: jdx/mise-action@v3
with: with:
cache_key: "mise-{{platform}}-{{version}}-{{file_hash}}" cache_key: "mise-{{platform}}-{{version}}-{{file_hash}}"
version: "2026.3.10" version: "2024.10.0"
install_args: "node python" install_args: "node python"
``` ```
Available template variables: Available template variables:
- `{{version}}` - The mise version (from the `version` input) - `{{version}}` - The mise version (from the `version` input)
- `{{cache_key_prefix}}` - The cache key prefix (from `cache_key_prefix` input or default) - `{{cache_key_prefix}}` - The cache key prefix (from `cache_key_prefix` input or default)
- `{{platform}}` - The target platform, including the runner image (e.g., "linux-x64-ubuntu24", "macos-arm64-macos15", "linux-x64-self-hosted"). The trailing segment is `process.env.ImageOS` on github-hosted runners and falls back to `"self-hosted"` elsewhere — preventing cache collisions when the same repo runs on different runner providers (github-hosted, namespace.so, self-hosted). - `{{platform}}` - The target platform (e.g., "linux-x64", "macos-arm64")
- `{{file_hash}}` - Hash of all mise configuration files - `{{file_hash}}` - Hash of all mise configuration files
- `{{mise_env}}` - The MISE_ENV environment variable value - `{{mise_env}}` - The MISE_ENV environment variable value
- `{{install_args_hash}}` - SHA256 hash of the sorted tools from install args - `{{install_args_hash}}` - SHA256 hash of the sorted tools from install args
@ -78,18 +78,18 @@ Conditional logic is also supported using Handlebars syntax like `{{#if version}
Example using multiple variables: Example using multiple variables:
```yaml ```yaml
- uses: jdx/mise-action@v4 - uses: jdx/mise-action@v3
with: with:
cache_key: "mise-v1-{{platform}}-{{install_args_hash}}-{{file_hash}}" cache_key: "mise-v1-{{platform}}-{{install_args_hash}}-{{file_hash}}"
install_args: "node@24 python@3.14" install_args: "node@20 python@3.12"
``` ```
You can also extend the default cache key: You can also extend the default cache key:
```yaml ```yaml
- uses: jdx/mise-action@v4 - uses: jdx/mise-action@v3
with: with:
cache_key: "{{default}}-custom-suffix" cache_key: "{{default}}-custom-suffix"
install_args: "node@24 python@3.14" install_args: "node@20 python@3.12"
``` ```
This gives you full control over cache invalidation based on the specific aspects that matter to your workflow. This gives you full control over cache invalidation based on the specific aspects that matter to your workflow.
@ -99,7 +99,7 @@ This gives you full control over cache invalidation based on the specific aspect
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. 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.
```yaml ```yaml
- uses: jdx/mise-action@v4 - uses: jdx/mise-action@v3
with: with:
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}
# your other configuration # your other configuration

View file

@ -85,36 +85,6 @@ inputs:
description: "Automatically load mise env vars into GITHUB_ENV. Note that PATH modifications are not part of this." description: "Automatically load mise env vars into GITHUB_ENV. Note that PATH modifications are not part of this."
required: false required: false
default: "true" default: "true"
wings_enabled:
description: |
[experimental] Opt in to the mise-wings asset cache
(https://mise-wings.en.dev) for this action invocation.
When `true`, the action exports `MISE_WINGS_ENABLED=1` so
the installed mise binary routes tool-install URLs (npm
tarballs, GitHub release artifacts) through the per-org
wings cache subdomains.
Authentication is automatic via the runner's GitHub OIDC
identity — no `mise wings login` step, no long-lived
secret to rotate. The workflow must declare
`permissions: id-token: write` so the OIDC token-issuer
env vars are populated; without that, mise falls through
to direct-origin fetches transparently.
Default `false` is the conservative posture: a workflow
with `id-token: write` (used for SLSA / AWS-OIDC /
Sigstore / etc.) should not have its OIDC token sent to
a third-party cache without explicit opt-in. Older mise
binaries that don't speak wings ignore the env var
entirely, so this is forward-compatible.
Requires an active mise-wings subscription on the Clerk
org linked to the GitHub org running the workflow;
without one, the proxy 402s and mise leaves the cache
off without affecting the workflow's success.
required: false
default: "false"
outputs: outputs:
cache-hit: cache-hit:
description: A boolean value to indicate if a cache was hit. description: A boolean value to indicate if a cache was hit.

200738
dist/index.js generated vendored

File diff suppressed because one or more lines are too long

2
dist/index.js.map generated vendored

File diff suppressed because one or more lines are too long

2248
dist/licenses.txt generated vendored

File diff suppressed because it is too large Load diff

1
dist/sourcemap-register.js generated vendored Normal file

File diff suppressed because one or more lines are too long

166
mise.lock
View file

@ -1,166 +0,0 @@
# @generated - this file is auto-generated by `mise lock` https://mise.en.dev/dev-tools/mise-lock.html
[[tools.aube]]
version = "1.6.2"
backend = "github:endevco/aube"
[tools.aube."platforms.linux-arm64"]
checksum = "sha256:1c47d2c0a50cf80f49aedcc2f58ce8abcbdf763092e772c8961c6e5b18916e8b"
url = "https://github.com/endevco/aube/releases/download/v1.6.2/aube-v1.6.2-aarch64-unknown-linux-gnu.tar.gz"
url_api = "https://api.github.com/repos/endevco/aube/releases/assets/410164231"
provenance = "github-attestations"
[tools.aube."platforms.linux-arm64-musl"]
checksum = "sha256:9780776921db3a54fc3237f50b9686489d93115e26584c7a85d54ce96a8e9b39"
url = "https://github.com/endevco/aube/releases/download/v1.6.2/aube-v1.6.2-aarch64-unknown-linux-musl.tar.gz"
url_api = "https://api.github.com/repos/endevco/aube/releases/assets/410164229"
provenance = "github-attestations"
[tools.aube."platforms.linux-x64"]
checksum = "sha256:16fcc40dfbaac110ce8f4e88728a440f2366094a45fd6c189bcbcc2b3ea31f06"
url = "https://github.com/endevco/aube/releases/download/v1.6.2/aube-v1.6.2-x86_64-unknown-linux-gnu.tar.gz"
url_api = "https://api.github.com/repos/endevco/aube/releases/assets/410164107"
provenance = "github-attestations"
[tools.aube."platforms.linux-x64-musl"]
checksum = "sha256:2ee3821fd62b56bb39cb2ceffe6ad38975e35f82311ca7f9ec6ee28bc6d284b8"
url = "https://github.com/endevco/aube/releases/download/v1.6.2/aube-v1.6.2-x86_64-unknown-linux-musl.tar.gz"
url_api = "https://api.github.com/repos/endevco/aube/releases/assets/410164199"
provenance = "github-attestations"
[tools.aube."platforms.macos-arm64"]
checksum = "sha256:4ce92482500f77f0779f288328cb7411f7ae2441b8618eae36a2ab5ea7591a32"
url = "https://github.com/endevco/aube/releases/download/v1.6.2/aube-v1.6.2-aarch64-apple-darwin.tar.gz"
url_api = "https://api.github.com/repos/endevco/aube/releases/assets/410166750"
provenance = "github-attestations"
[tools.aube."platforms.windows-x64"]
checksum = "sha256:916594efae8f8b59fc898913f96d199a21d212c7037043853ee04df7264611d0"
url = "https://github.com/endevco/aube/releases/download/v1.6.2/aube-v1.6.2-x86_64-pc-windows-msvc.zip"
url_api = "https://api.github.com/repos/endevco/aube/releases/assets/410174742"
provenance = "github-attestations"
[[tools.communique]]
version = "1.1.2"
backend = "github:jdx/communique"
[tools.communique."platforms.linux-arm64"]
checksum = "sha256:7bb0843207fc3d7b5df2a5c0198bb10539cf13a6b247b4adfbf6b302a68f03de"
url = "https://github.com/jdx/communique/releases/download/v1.1.2/communique-aarch64-unknown-linux-gnu.tar.gz"
url_api = "https://api.github.com/repos/jdx/communique/releases/assets/405964161"
[tools.communique."platforms.linux-arm64-musl"]
checksum = "sha256:b663407be77a370c209df40307b82e436f56a6bc23d4e423510d62ac6e1fedf4"
url = "https://github.com/jdx/communique/releases/download/v1.1.2/communique-aarch64-unknown-linux-musl.tar.gz"
url_api = "https://api.github.com/repos/jdx/communique/releases/assets/405964743"
[tools.communique."platforms.linux-x64"]
checksum = "sha256:5e74ead7037f42940c7dba4f6aa4ed968920cbb55a047aa0d291b0c675c65676"
url = "https://github.com/jdx/communique/releases/download/v1.1.2/communique-x86_64-unknown-linux-gnu.tar.gz"
url_api = "https://api.github.com/repos/jdx/communique/releases/assets/405963914"
provenance = "github-attestations"
[tools.communique."platforms.linux-x64-musl"]
checksum = "sha256:01a6a8b49e635a5a209fdaf6c7b2e976374debc2db1c846c033f567fdba0d86c"
url = "https://github.com/jdx/communique/releases/download/v1.1.2/communique-x86_64-unknown-linux-musl.tar.gz"
url_api = "https://api.github.com/repos/jdx/communique/releases/assets/405964691"
[tools.communique."platforms.macos-arm64"]
checksum = "sha256:459993e31a6c4ccbd09882f5679a2bc1ea5d9068701ecefc411a00fb69ce82e6"
url = "https://github.com/jdx/communique/releases/download/v1.1.2/communique-aarch64-apple-darwin.tar.gz"
url_api = "https://api.github.com/repos/jdx/communique/releases/assets/405964098"
[tools.communique."platforms.windows-x64"]
checksum = "sha256:3cc0e880ac2168aed3163223627bbd1eee62e07a9901cb85cb507c6c8927bc93"
url = "https://github.com/jdx/communique/releases/download/v1.1.2/communique-x86_64-pc-windows-msvc.zip"
url_api = "https://api.github.com/repos/jdx/communique/releases/assets/405964430"
[[tools.gh]]
version = "2.92.0"
backend = "aqua:cli/cli"
[tools.gh."platforms.linux-arm64"]
checksum = "sha256:c2248526dd0160c08d3fccca2332c3c1a07c15a78b23978e77735f1b5a18cfee"
url = "https://github.com/cli/cli/releases/download/v2.92.0/gh_2.92.0_linux_arm64.tar.gz"
provenance = "github-attestations"
[tools.gh."platforms.linux-arm64-musl"]
checksum = "sha256:c2248526dd0160c08d3fccca2332c3c1a07c15a78b23978e77735f1b5a18cfee"
url = "https://github.com/cli/cli/releases/download/v2.92.0/gh_2.92.0_linux_arm64.tar.gz"
provenance = "github-attestations"
[tools.gh."platforms.linux-x64"]
checksum = "sha256:b57848131bdf0c229cd35e1f2a51aa718199858b2e728410b37e89a428943ec4"
url = "https://github.com/cli/cli/releases/download/v2.92.0/gh_2.92.0_linux_amd64.tar.gz"
provenance = "github-attestations"
[tools.gh."platforms.linux-x64-musl"]
checksum = "sha256:b57848131bdf0c229cd35e1f2a51aa718199858b2e728410b37e89a428943ec4"
url = "https://github.com/cli/cli/releases/download/v2.92.0/gh_2.92.0_linux_amd64.tar.gz"
provenance = "github-attestations"
[tools.gh."platforms.macos-arm64"]
checksum = "sha256:b11c54f6bd7d15ed6590475079e5b2fcf36f45d3991a80041b29c9d0cc1f1d07"
url = "https://github.com/cli/cli/releases/download/v2.92.0/gh_2.92.0_macOS_arm64.zip"
provenance = "github-attestations"
[tools.gh."platforms.windows-x64"]
checksum = "sha256:b6a8df3c8c6b9c80f290906387673bc4d272840f3789c5650e0e4e6e75522785"
url = "https://github.com/cli/cli/releases/download/v2.92.0/gh_2.92.0_windows_amd64.zip"
provenance = "github-attestations"
[[tools.git-cliff]]
version = "2.13.1"
backend = "aqua:orhun/git-cliff"
[tools.git-cliff."platforms.linux-arm64"]
checksum = "sha256:4054c124b926c117f3fa048939bc8be0a954f29f3b6f367627e8cb22c1971882"
url = "https://github.com/orhun/git-cliff/releases/download/v2.13.1/git-cliff-2.13.1-aarch64-unknown-linux-musl.tar.gz"
[tools.git-cliff."platforms.linux-arm64-musl"]
checksum = "sha256:4054c124b926c117f3fa048939bc8be0a954f29f3b6f367627e8cb22c1971882"
url = "https://github.com/orhun/git-cliff/releases/download/v2.13.1/git-cliff-2.13.1-aarch64-unknown-linux-musl.tar.gz"
[tools.git-cliff."platforms.linux-x64"]
checksum = "sha256:200d2535da6d9703f3bcc8a4d159c3b55eacdb01cf2148c55b3eee9dd04d5249"
url = "https://github.com/orhun/git-cliff/releases/download/v2.13.1/git-cliff-2.13.1-x86_64-unknown-linux-musl.tar.gz"
[tools.git-cliff."platforms.linux-x64-musl"]
checksum = "sha256:200d2535da6d9703f3bcc8a4d159c3b55eacdb01cf2148c55b3eee9dd04d5249"
url = "https://github.com/orhun/git-cliff/releases/download/v2.13.1/git-cliff-2.13.1-x86_64-unknown-linux-musl.tar.gz"
[tools.git-cliff."platforms.macos-arm64"]
checksum = "sha256:21547ae4a0421164070ab75c2522864ea5565858a011fabc5f583061b20f1226"
url = "https://github.com/orhun/git-cliff/releases/download/v2.13.1/git-cliff-2.13.1-aarch64-apple-darwin.tar.gz"
[tools.git-cliff."platforms.windows-x64"]
checksum = "sha256:3ae3a5549e85c7ad5b20192ebcfee4371269deca51255f6f2f2e051c6541f5ca"
url = "https://github.com/orhun/git-cliff/releases/download/v2.13.1/git-cliff-2.13.1-x86_64-pc-windows-msvc.zip"
[[tools.node]]
version = "24.15.0"
backend = "core:node"
[tools.node."platforms.linux-arm64"]
checksum = "sha256:73afc234d558c24919875f51c2d1ea002a2ada4ea6f83601a383869fefa64eed"
url = "https://nodejs.org/dist/v24.15.0/node-v24.15.0-linux-arm64.tar.gz"
[tools.node."platforms.linux-arm64-musl"]
checksum = "sha256:31e98aa960a067da91edffd5d93bc46657b5d2a8029612c359f5f2ac0060152a"
url = "https://unofficial-builds.nodejs.org/download/release/v24.15.0/node-v24.15.0-linux-arm64-musl.tar.gz"
[tools.node."platforms.linux-x64"]
checksum = "sha256:44836872d9aec49f1e6b52a9a922872db9a2b02d235a616a5681b6a85fec8d89"
url = "https://nodejs.org/dist/v24.15.0/node-v24.15.0-linux-x64.tar.gz"
[tools.node."platforms.linux-x64-musl"]
checksum = "sha256:f55af5bd489c5347b113ca6594cae00a54b30ba57ac5875324311bfc6f4762e3"
url = "https://unofficial-builds.nodejs.org/download/release/v24.15.0/node-v24.15.0-linux-x64-musl.tar.gz"
[tools.node."platforms.macos-arm64"]
checksum = "sha256:372331b969779ab5d15b949884fc6eaf88d5afe87bde8ba881d6400b9100ffc4"
url = "https://nodejs.org/dist/v24.15.0/node-v24.15.0-darwin-arm64.tar.gz"
[tools.node."platforms.windows-x64"]
checksum = "sha256:cc5149eabd53779ce1e7bdc5401643622d0c7e6800ade18928a767e940bb0e62"
url = "https://nodejs.org/dist/v24.15.0/node-v24.15.0-win-x64.zip"

View file

@ -1,14 +1,12 @@
tasks.pre-commit = ["aubr all", "git add dist"] tasks.pre-commit = ["npm run all", "git add dist"]
tasks.test.alias = ["t"] tasks.test.alias = ["t"]
tasks.test.run = ["aubr all"] tasks.test.run = ["npm run all"]
tasks.lint = "aubr lint" tasks.lint = "bun run lint"
tasks."lint:fix" = "aubr format:write" tasks."lint:fix" = "bun run format:write"
tasks.version = "aube version" tasks.version = "npm version"
tasks.release-plz = "./scripts/release-plz.sh" tasks.release-plz = "./scripts/release-plz.sh"
[tools] [tools]
node = '24' node = '24'
aube = 'v1.9.1'
git-cliff = 'latest' git-cliff = 'latest'
gh = 'latest' gh = 'latest'
communique = 'latest'

3170
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,8 @@
{ {
"name": "mise-action", "name": "mise-action",
"description": "mise tool setup action", "description": "mise tool setup action",
"version": "4.0.1", "version": "4.0.0",
"author": "jdx", "author": "jdx",
"type": "module",
"private": true, "private": true,
"repository": { "repository": {
"type": "git", "type": "git",
@ -22,46 +21,34 @@
"bundle": "npm run format:write && npm run package", "bundle": "npm run format:write && npm run package",
"format:check": "prettier --check **/*.ts", "format:check": "prettier --check **/*.ts",
"format:write": "prettier --write **/*.ts", "format:write": "prettier --write **/*.ts",
"lint": "eslint . && npm run format:check", "lint": "npx eslint . && npm run format:check",
"package": "rimraf ./dist && rollup --config rollup.config.mjs", "package": "ncc build -s src/index.ts --license licenses.txt",
"package:watch": "npm run package -- --watch", "package:watch": "npm run package -- --watch",
"version": "./scripts/version.sh", "version": "./scripts/version.sh",
"prepare": "husky" "prepare": "husky"
}, },
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/cache": "^6.0.0", "@actions/cache": "^4.0.0",
"@actions/core": "^3.0.0", "@actions/core": "^1.11.1",
"@actions/exec": "^3.0.0", "@actions/exec": "^1.1.1",
"@actions/glob": "^0.7.0", "@actions/glob": "^0.5.0",
"@actions/io": "^3.0.0",
"@types/handlebars": "^4.0.40", "@types/handlebars": "^4.0.40",
"handlebars": "^4.7.8" "handlebars": "^4.7.8"
}, },
"devDependencies": { "devDependencies": {
"@eslint/eslintrc": "^3.2.0", "@eslint/eslintrc": "^3.2.0",
"@eslint/js": "^10.0.0", "@eslint/js": "^9.15.0",
"@rollup/plugin-commonjs": "^29.0.0",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^16.0.0",
"@rollup/plugin-typescript": "^12.0.0",
"@types/eslint__js": "^8.42.3", "@types/eslint__js": "^8.42.3",
"@types/node": "^24", "@types/node": "^24",
"eslint": "^10.0.0", "@vercel/ncc": "^0.38.3",
"globals": "^17.0.0", "eslint": "^9.15.0",
"globals": "^16.0.0",
"husky": "^9.1.7", "husky": "^9.1.7",
"jest": "^30", "jest": "^30",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"prettier": "^3.4.1", "prettier": "^3.4.1",
"rimraf": "^6.0.0", "typescript": "^5.7.2",
"rollup": "^4.0.0",
"rollup-plugin-license": "^3.7.1",
"typescript": "^6.0.0",
"typescript-eslint": "^8.16.0" "typescript-eslint": "^8.16.0"
},
"aube": {
"allowBuilds": {
"unrs-resolver": false
}
} }
} }

View file

@ -1,29 +0,0 @@
import commonjs from '@rollup/plugin-commonjs'
import json from '@rollup/plugin-json'
import nodeResolve from '@rollup/plugin-node-resolve'
import typescript from '@rollup/plugin-typescript'
import license from 'rollup-plugin-license'
import path from 'path'
const config = {
input: 'src/index.ts',
output: {
esModule: true,
file: 'dist/index.js',
format: 'es',
sourcemap: true
},
plugins: [
typescript(),
nodeResolve({ preferBuiltins: true }),
commonjs({ ignoreTryCatch: false }),
json(),
license({
thirdParty: {
output: path.resolve('dist', 'licenses.txt')
}
})
]
}
export default config

View file

@ -4,11 +4,6 @@ set -euxo pipefail
VERSION=$(jq -r .version package.json) VERSION=$(jq -r .version package.json)
MAJOR_VERSION=$(echo "$VERSION" | cut -d. -f1) MAJOR_VERSION=$(echo "$VERSION" | cut -d. -f1)
# Configure git to use gh's credential helper. The checkout step uses
# persist-credentials: false (per zizmor's artipacked audit), so the
# token isn't written to .git/config and raw `git push` would 403.
gh auth setup-git
# create the version tag (allow it to fail if it already exists) # create the version tag (allow it to fail if it already exists)
git tag "v$VERSION" || echo "Tag v$VERSION already exists locally" git tag "v$VERSION" || echo "Tag v$VERSION already exists locally"

View file

@ -47,11 +47,6 @@ if [ -n "$latest_release_version" ] && [ "$cur_pkg_version" = "$latest_release_v
git config user.name mise-en-dev git config user.name mise-en-dev
git config user.email 123107610+mise-en-dev@users.noreply.github.com git config user.email 123107610+mise-en-dev@users.noreply.github.com
# Configure git to use gh's credential helper. The checkout step uses
# persist-credentials: false (per zizmor's artipacked audit), so the
# token isn't written to .git/config and raw `git push` would 403.
gh auth setup-git
# Create a PR with the version bump # Create a PR with the version bump
npm version "${version#v}" --no-git-tag-version npm version "${version#v}" --no-git-tag-version

View file

@ -54,25 +54,6 @@ async function run(): Promise<void> {
core.setOutput('cache-hit', false) core.setOutput('cache-hit', false)
} }
// Wings opt-in hook (experimental). When
// `wings_enabled: true` is set, this exports
// `MISE_WINGS_ENABLED=1` so subsequent `mise install`
// commands in this workflow route through the wings
// cache. Default `false` so workflows with
// `id-token: write` (used for SLSA / AWS-OIDC / Sigstore /
// etc.) don't silently send the runner's OIDC token to
// a third-party cache without explicit consent.
//
// Note: `setupMise` fetches the mise binary itself with
// `curl`, which doesn't go through mise's HTTP layer —
// the wings rewriter only kicks in once the resulting
// mise binary runs `mise install` and friends. Ordering
// here is irrelevant for binary acceleration; we just
// want the env var set before any `mise` subcommand
// runs. Greptile + Gemini both flagged the previous
// comment as overstating what the early call accelerates.
setupWings()
const version = core.getInput('version') const version = core.getInput('version')
const fetchFromGitHub = core.getBooleanInput('fetch_from_github') const fetchFromGitHub = core.getBooleanInput('fetch_from_github')
await setupMise(version, fetchFromGitHub) await setupMise(version, fetchFromGitHub)
@ -98,53 +79,13 @@ async function run(): Promise<void> {
} }
} }
/**
* Opt in to mise-wings caching for this workflow run. When
* `wings_enabled: true`, exports `MISE_WINGS_ENABLED=1` so
* subsequent `mise install` commands route through the
* cache.
*
* Mise itself owns the OIDC wings session exchange when
* it sees `MISE_WINGS_ENABLED=1` and the GHA OIDC env vars
* (`ACTIONS_ID_TOKEN_REQUEST_URL` +
* `ACTIONS_ID_TOKEN_REQUEST_TOKEN`), it fetches the runner's
* OIDC token, exchanges it at the proxy's `POST /auth`
* route, and caches the resulting session JWT for the rest
* of the process.
*
* Pre-flight check: `id-token: write` permission must be
* declared at the workflow or job level for the OIDC env
* vars to be present. We log a warning when wings is
* enabled but the env vars are absent without this hint,
* the user sees a transparent "wings configured but doing
* nothing" which is hard to debug.
*/
function setupWings(): void {
if (!core.getBooleanInput('wings_enabled')) {
return
}
core.exportVariable('MISE_WINGS_ENABLED', '1')
core.info(
"mise-wings: enabled. mise will exchange the runner's OIDC token for a wings session on first use."
)
const oidcUrl = process.env.ACTIONS_ID_TOKEN_REQUEST_URL
const oidcToken = process.env.ACTIONS_ID_TOKEN_REQUEST_TOKEN
if (!oidcUrl || !oidcToken) {
core.warning(
'mise-wings: GHA OIDC env vars are missing. Add ' +
'`permissions: id-token: write` at the workflow or job ' +
'level so the runner can mint OIDC tokens. Without this, ' +
'mise falls through to direct-origin fetches and the cache ' +
'is bypassed.'
)
}
}
async function exportMiseEnv(): Promise<void> { async function exportMiseEnv(): Promise<void> {
core.startGroup('Exporting mise environment variables') core.startGroup('Exporting mise environment variables')
const cwd = getCwd() const cwd =
core.getInput('working_directory') ||
core.getInput('install_dir') ||
process.cwd()
// Check if mise supports --redacted flags based on version input // Check if mise supports --redacted flags based on version input
const supportsRedacted = checkMiseSupportsRedacted() const supportsRedacted = checkMiseSupportsRedacted()
@ -296,8 +237,6 @@ async function setupMise(
miseBinDir, miseBinDir,
process.platform === 'win32' ? 'mise.exe' : 'mise' process.platform === 'win32' ? 'mise.exe' : 'mise'
) )
const miseShimPath = path.join(miseBinDir, 'mise-shim.exe')
let installedVersion: string | undefined
if (!fs.existsSync(path.join(miseBinPath))) { if (!fs.existsSync(path.join(miseBinPath))) {
core.startGroup(version ? `Download mise@${version}` : 'Setup mise') core.startGroup(version ? `Download mise@${version}` : 'Setup mise')
await fs.promises.mkdir(miseBinDir, { recursive: true }) await fs.promises.mkdir(miseBinDir, { recursive: true })
@ -318,16 +257,13 @@ async function setupMise(
} else { } else {
url = `https://github.com/jdx/mise/releases/download/v${resolvedVersion}/mise-v${resolvedVersion}-${await getTarget()}${ext}` url = `https://github.com/jdx/mise/releases/download/v${resolvedVersion}/mise-v${resolvedVersion}-${await getTarget()}${ext}`
} }
installedVersion = resolvedVersion const archivePath = path.join(os.tmpdir(), `mise${ext}`)
switch (ext) { switch (ext) {
case '.zip': { case '.zip':
await withExtractedZip(url, 'mise.zip', async extractDir => { await exec.exec('curl', ['-fsSL', url, '--output', archivePath])
const extractedMiseBinDir = path.join(extractDir, 'mise', 'bin') await exec.exec('unzip', [archivePath, '-d', os.tmpdir()])
await io.mv(path.join(extractedMiseBinDir, 'mise.exe'), miseBinPath) await io.mv(path.join(os.tmpdir(), 'mise/bin/mise.exe'), miseBinPath)
await installWindowsMiseShim(extractedMiseBinDir, miseShimPath)
})
break break
}
case '.tar.zst': case '.tar.zst':
await exec.exec('sh', [ await exec.exec('sh', [
'-c', '-c',
@ -348,20 +284,24 @@ async function setupMise(
} else { } else {
const requestedVersion = cleanVersion(core.getInput('version')) const requestedVersion = cleanVersion(core.getInput('version'))
if (requestedVersion !== '') { if (requestedVersion !== '') {
installedVersion = await getInstalledMiseVersion(miseBinPath) const versionOutput = await exec.getExecOutput(
if (requestedVersion === installedVersion) { miseBinPath,
['version', '--json'],
{ silent: true }
)
const versionJson = JSON.parse(versionOutput.stdout)
const version = cleanVersion(versionJson.version.split(' ')[0])
if (requestedVersion === version) {
core.info(`mise already installed`) core.info(`mise already installed`)
} else { } else {
core.info( core.info(
`mise already installed (${installedVersion}), but different version requested (${requestedVersion})` `mise already installed (${version}), but different version requested (${requestedVersion})`
) )
await exec.exec(miseBinPath, ['self-update', requestedVersion, '-y']) await exec.exec(miseBinPath, ['self-update', requestedVersion, '-y'])
core.info(`mise updated to version ${requestedVersion}`) core.info(`mise updated to version ${requestedVersion}`)
installedVersion = requestedVersion
} }
} }
} }
await ensureWindowsMiseShim(miseBinPath, miseShimPath, installedVersion)
// compare with provided hash // compare with provided hash
const want = core.getInput('sha256') const want = core.getInput('sha256')
if (want) { if (want) {
@ -378,86 +318,6 @@ async function setupMise(
core.addPath(miseBinDir) core.addPath(miseBinDir)
} }
async function withExtractedZip(
url: string,
archiveName: string,
fn: (extractDir: string) => Promise<void>
): Promise<void> {
const tempDir = await fs.promises.mkdtemp(
path.join(os.tmpdir(), 'mise-action-')
)
try {
const archivePath = path.join(tempDir, archiveName)
const extractDir = path.join(tempDir, 'extract')
await exec.exec('curl', ['-fsSL', url, '--output', archivePath])
await exec.exec('unzip', [archivePath, '-d', extractDir])
await fn(extractDir)
} finally {
await io.rmRF(tempDir)
}
}
async function installWindowsMiseShim(
extractedMiseBinDir: string,
miseShimPath: string
): Promise<void> {
if (process.platform !== 'win32') return
const extractedMiseShimPath = path.join(extractedMiseBinDir, 'mise-shim.exe')
if (!fs.existsSync(extractedMiseShimPath)) {
core.info('mise-shim.exe not found in the mise archive; skipping')
return
}
await io.mv(extractedMiseShimPath, miseShimPath)
}
async function ensureWindowsMiseShim(
miseBinPath: string,
miseShimPath: string,
version?: string
): Promise<void> {
if (process.platform !== 'win32') return
if (fs.existsSync(miseShimPath)) return
core.info(
'mise-shim.exe not found next to mise.exe; installing it from the matching release archive'
)
try {
const installedVersion =
version || (await getInstalledMiseVersion(miseBinPath))
const archiveName = `mise-v${installedVersion}-${await getTarget()}.zip`
const url = `https://github.com/jdx/mise/releases/download/v${installedVersion}/${archiveName}`
await withExtractedZip(url, archiveName, async extractDir => {
await installWindowsMiseShim(
path.join(extractDir, 'mise', 'bin'),
miseShimPath
)
})
} catch (err) {
core.warning(
`Failed to install mise-shim.exe: ${errorMessage(err)}. Continuing because mise can fall back to file shim mode on Windows.`
)
}
}
async function getInstalledMiseVersion(miseBinPath: string): Promise<string> {
const versionOutput = await exec.getExecOutput(
miseBinPath,
['version', '--json'],
{ silent: true }
)
const versionJson = JSON.parse(versionOutput.stdout) as { version: string }
return cleanVersion(versionJson.version.split(' ')[0])
}
function errorMessage(err: unknown): string {
return err instanceof Error ? err.message : String(err)
}
async function zstdInstalled(): Promise<boolean> { async function zstdInstalled(): Promise<boolean> {
try { try {
await exec.exec('zstd', ['--version']) await exec.exec('zstd', ['--version'])
@ -496,7 +356,10 @@ const miseLs = async (): Promise<number> => mise([`ls`])
const miseReshim = async (): Promise<number> => mise([`reshim`, `-f`]) const miseReshim = async (): Promise<number> => mise([`reshim`, `-f`])
const mise = async (args: string[]): Promise<number> => const mise = async (args: string[]): Promise<number> =>
await core.group(`Running mise ${args.join(' ')}`, async () => { await core.group(`Running mise ${args.join(' ')}`, async () => {
const cwd = getCwd() const cwd =
core.getInput('working_directory') ||
core.getInput('install_dir') ||
process.cwd()
const baseEnv = Object.fromEntries( const baseEnv = Object.fromEntries(
Object.entries(process.env).filter( Object.entries(process.env).filter(
(entry): entry is [string, string] => entry[1] !== undefined (entry): entry is [string, string] => entry[1] !== undefined
@ -524,14 +387,6 @@ const writeFile = async (p: fs.PathLike, body: string): Promise<void> =>
run() run()
function getCwd(): string {
return (
core.getInput('working_directory') ||
core.getInput('install_dir') ||
process.cwd()
)
}
function miseDir(): string { function miseDir(): string {
const dir = core.getState('MISE_DIR') const dir = core.getState('MISE_DIR')
if (dir) return dir if (dir) return dir
@ -564,7 +419,11 @@ async function saveCache(cacheKey: string): Promise<void> {
} }
async function getTarget(): Promise<string> { async function getTarget(): Promise<string> {
const arch = process.arch === 'arm' ? 'armv7' : process.arch let { arch } = process
// quick overwrite to abide by release format
if (arch === 'arm') arch = 'armv7' as NodeJS.Architecture
switch (process.platform) { switch (process.platform) {
case 'darwin': case 'darwin':
return `macos-${arch}` return `macos-${arch}`
@ -577,25 +436,13 @@ async function getTarget(): Promise<string> {
} }
} }
/**
* Identifies the runner image so cached binaries from one provider
* (github-hosted, namespace.so, BuildJet, self-hosted) aren't restored
* onto another provider's image where their compiled-in paths and libc
* versions don't match. GitHub-hosted images export `ImageOS`
* (e.g. "macos15", "ubuntu24"); other runners leave it unset and pool
* under "self-hosted".
*/
function getRunnerImageId(): string {
return process.env.ImageOS || 'self-hosted'
}
async function processCacheKeyTemplate(template: string): Promise<string> { async function processCacheKeyTemplate(template: string): Promise<string> {
// Get all available variables // Get all available variables
const version = core.getInput('version') const version = core.getInput('version')
const installArgs = core.getInput('install_args') const installArgs = core.getInput('install_args')
const cacheKeyPrefix = core.getInput('cache_key_prefix') || 'mise-v1' const cacheKeyPrefix = core.getInput('cache_key_prefix') || 'mise-v1'
const miseEnv = process.env.MISE_ENV?.replace(/,/g, '-') const miseEnv = process.env.MISE_ENV?.replace(/,/g, '-')
const platform = `${await getTarget()}-${getRunnerImageId()}` const platform = await getTarget()
// Calculate file hash // Calculate file hash
const fileHash = await glob.hashFiles(MISE_CONFIG_FILE_PATTERNS.join('\n')) const fileHash = await glob.hashFiles(MISE_CONFIG_FILE_PATTERNS.join('\n'))

View file

@ -13,9 +13,7 @@
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"strict": true, "strict": true,
"skipLibCheck": true, "skipLibCheck": true,
"newLine": "lf", "newLine": "lf"
"isolatedModules": true,
"allowSyntheticDefaultImports": true
}, },
"exclude": ["./dist", "./node_modules", "./__tests__", "./coverage"] "exclude": ["./dist", "./node_modules", "./__tests__", "./coverage"]
} }