mirror of
https://github.com/jdx/mise-action.git
synced 2026-05-14 22:00:34 +00:00
feat: output active tool versions after installation
Add outputs for active tool versions to eliminate the need for wrapper steps to extract version information for cache keys. New outputs: - Individual tool outputs (e.g., steps.mise.outputs.bun = "1.0.0") - versions: JSON object with all active tools and full metadata Closes #448
This commit is contained in:
parent
db69447ab3
commit
3ae98ac76a
6 changed files with 197 additions and 1 deletions
45
.github/workflows/test.yml
vendored
45
.github/workflows/test.yml
vendored
|
|
@ -147,6 +147,50 @@ jobs:
|
|||
- run: which jq
|
||||
- run: jq --version
|
||||
|
||||
version_outputs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: Setup mise
|
||||
id: mise
|
||||
uses: ./
|
||||
with:
|
||||
cache: false
|
||||
mise_toml: |
|
||||
[tools]
|
||||
jq = "1.7.1"
|
||||
bun = "1.2.0"
|
||||
- name: Verify individual tool outputs
|
||||
run: |
|
||||
echo "jq version: ${{ steps.mise.outputs.jq }}"
|
||||
echo "bun version: ${{ steps.mise.outputs.bun }}"
|
||||
if [ -z "${{ steps.mise.outputs.jq }}" ]; then
|
||||
echo "ERROR: jq output is empty"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${{ steps.mise.outputs.bun }}" ]; then
|
||||
echo "ERROR: bun output is empty"
|
||||
exit 1
|
||||
fi
|
||||
echo "Individual tool outputs verified successfully"
|
||||
- name: Verify versions JSON output
|
||||
run: |
|
||||
echo "versions JSON: ${{ steps.mise.outputs.versions }}"
|
||||
# Parse and validate JSON structure
|
||||
echo '${{ steps.mise.outputs.versions }}' | jq -e '.jq.version' > /dev/null
|
||||
echo '${{ steps.mise.outputs.versions }}' | jq -e '.bun.version' > /dev/null
|
||||
echo "versions JSON output verified successfully"
|
||||
- name: Use version output in cache key (simulation)
|
||||
run: |
|
||||
# Simulate using the version output in a cache key
|
||||
CACHE_KEY="bun-cache-linux-${{ steps.mise.outputs.bun }}"
|
||||
echo "Generated cache key: $CACHE_KEY"
|
||||
if [[ "$CACHE_KEY" != *"1.2.0"* ]]; then
|
||||
echo "ERROR: Cache key does not contain expected version"
|
||||
exit 1
|
||||
fi
|
||||
echo "Cache key simulation successful"
|
||||
|
||||
final:
|
||||
needs:
|
||||
- build
|
||||
|
|
@ -155,6 +199,7 @@ jobs:
|
|||
- checksum_failure
|
||||
- custom_cache_key
|
||||
- fetch_from_github
|
||||
- version_outputs
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 1
|
||||
if: always()
|
||||
|
|
|
|||
52
README.md
52
README.md
|
|
@ -94,6 +94,58 @@ You can also extend the default cache key:
|
|||
|
||||
This gives you full control over cache invalidation based on the specific aspects that matter to your workflow.
|
||||
|
||||
## Outputs
|
||||
|
||||
The action provides the following outputs:
|
||||
|
||||
| Output | Description |
|
||||
|--------|-------------|
|
||||
| `cache-hit` | Boolean indicating if the cache was restored |
|
||||
| `versions` | JSON object with all active tool versions and metadata |
|
||||
| `<tool-name>` | Version string for each active tool (e.g., `bun`, `node`, `python`) |
|
||||
|
||||
### Using Tool Version Outputs
|
||||
|
||||
After mise installs tools, you can access the resolved versions directly without needing a separate step:
|
||||
|
||||
```yaml
|
||||
- name: Setup tools with Mise
|
||||
id: mise
|
||||
uses: jdx/mise-action@v4
|
||||
|
||||
# Access individual tool versions directly
|
||||
- name: Cache bun
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ~/.bun/install/cache
|
||||
key: bun-cache-${{ runner.os }}-${{ steps.mise.outputs.bun }}-${{ hashFiles('**/bun.lock') }}
|
||||
|
||||
# Or use the full versions JSON for complex scenarios
|
||||
- name: Show all versions
|
||||
run: echo '${{ steps.mise.outputs.versions }}'
|
||||
```
|
||||
|
||||
The `versions` output contains full metadata for each active tool:
|
||||
|
||||
```json
|
||||
{
|
||||
"bun": {
|
||||
"version": "1.0.0",
|
||||
"requested_version": "latest",
|
||||
"install_path": "/home/runner/.local/share/mise/installs/bun/1.0.0",
|
||||
"source": {
|
||||
"type": "mise.toml",
|
||||
"path": "/home/runner/work/repo/mise.toml"
|
||||
}
|
||||
},
|
||||
"node": {
|
||||
"version": "20.10.0",
|
||||
"requested_version": "20",
|
||||
"install_path": "/home/runner/.local/share/mise/installs/node/20.10.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 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.
|
||||
|
|
|
|||
|
|
@ -88,6 +88,8 @@ inputs:
|
|||
outputs:
|
||||
cache-hit:
|
||||
description: A boolean value to indicate if a cache was hit.
|
||||
versions:
|
||||
description: JSON object containing all active tool versions with metadata (version, requested_version, install_path, source).
|
||||
runs:
|
||||
using: node24
|
||||
main: dist/index.js
|
||||
|
|
|
|||
34
dist/index.js
generated
vendored
34
dist/index.js
generated
vendored
|
|
@ -84859,6 +84859,7 @@ async function run() {
|
|||
await testMise();
|
||||
if (getBooleanInput('install')) {
|
||||
await miseInstall();
|
||||
await outputToolVersions();
|
||||
if (cacheKey && getBooleanInput('cache_save')) {
|
||||
await saveCache(cacheKey);
|
||||
}
|
||||
|
|
@ -84921,6 +84922,39 @@ async function exportMiseEnv() {
|
|||
}
|
||||
endGroup();
|
||||
}
|
||||
async function outputToolVersions() {
|
||||
startGroup('Outputting tool versions');
|
||||
const cwd = getCwd();
|
||||
try {
|
||||
const output = await getExecOutput('mise', ['ls', '--json'], {
|
||||
cwd,
|
||||
silent: true
|
||||
});
|
||||
const tools = JSON.parse(output.stdout);
|
||||
const activeVersions = {};
|
||||
for (const [toolName, versions] of Object.entries(tools)) {
|
||||
const activeVersion = versions.find(v => v.active);
|
||||
if (activeVersion) {
|
||||
// Set individual output: steps.mise.outputs.bun = "1.0.0"
|
||||
setOutput(toolName, activeVersion.version);
|
||||
info(`${toolName}: ${activeVersion.version}`);
|
||||
// Collect for JSON output with full metadata
|
||||
activeVersions[toolName] = {
|
||||
version: activeVersion.version,
|
||||
requested_version: activeVersion.requested_version,
|
||||
install_path: activeVersion.install_path,
|
||||
source: activeVersion.source
|
||||
};
|
||||
}
|
||||
}
|
||||
// Set JSON output with all active versions
|
||||
setOutput('versions', JSON.stringify(activeVersions));
|
||||
}
|
||||
catch (error) {
|
||||
warning(`Failed to output tool versions: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
}
|
||||
endGroup();
|
||||
}
|
||||
function cleanVersion(version) {
|
||||
// remove 'v' prefix if present
|
||||
return version.replace(/^v/, '');
|
||||
|
|
|
|||
2
dist/index.js.map
generated
vendored
2
dist/index.js.map
generated
vendored
File diff suppressed because one or more lines are too long
63
src/index.ts
63
src/index.ts
|
|
@ -64,6 +64,7 @@ async function run(): Promise<void> {
|
|||
await testMise()
|
||||
if (core.getBooleanInput('install')) {
|
||||
await miseInstall()
|
||||
await outputToolVersions()
|
||||
if (cacheKey && core.getBooleanInput('cache_save')) {
|
||||
await saveCache(cacheKey)
|
||||
}
|
||||
|
|
@ -134,6 +135,68 @@ async function exportMiseEnv(): Promise<void> {
|
|||
core.endGroup()
|
||||
}
|
||||
|
||||
interface ToolSource {
|
||||
type: string
|
||||
path: string
|
||||
}
|
||||
|
||||
interface ToolInfo {
|
||||
version: string
|
||||
requested_version?: string
|
||||
install_path: string
|
||||
source?: ToolSource
|
||||
installed: boolean
|
||||
active: boolean
|
||||
}
|
||||
|
||||
interface ToolVersionOutput {
|
||||
version: string
|
||||
requested_version?: string
|
||||
install_path: string
|
||||
source?: ToolSource
|
||||
}
|
||||
|
||||
async function outputToolVersions(): Promise<void> {
|
||||
core.startGroup('Outputting tool versions')
|
||||
const cwd = getCwd()
|
||||
|
||||
try {
|
||||
const output = await exec.getExecOutput('mise', ['ls', '--json'], {
|
||||
cwd,
|
||||
silent: true
|
||||
})
|
||||
|
||||
const tools: Record<string, ToolInfo[]> = JSON.parse(output.stdout)
|
||||
const activeVersions: Record<string, ToolVersionOutput> = {}
|
||||
|
||||
for (const [toolName, versions] of Object.entries(tools)) {
|
||||
const activeVersion = versions.find(v => v.active)
|
||||
if (activeVersion) {
|
||||
// Set individual output: steps.mise.outputs.bun = "1.0.0"
|
||||
core.setOutput(toolName, activeVersion.version)
|
||||
core.info(`${toolName}: ${activeVersion.version}`)
|
||||
|
||||
// Collect for JSON output with full metadata
|
||||
activeVersions[toolName] = {
|
||||
version: activeVersion.version,
|
||||
requested_version: activeVersion.requested_version,
|
||||
install_path: activeVersion.install_path,
|
||||
source: activeVersion.source
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set JSON output with all active versions
|
||||
core.setOutput('versions', JSON.stringify(activeVersions))
|
||||
} catch (error) {
|
||||
core.warning(
|
||||
`Failed to output tool versions: ${error instanceof Error ? error.message : 'Unknown error'}`
|
||||
)
|
||||
}
|
||||
|
||||
core.endGroup()
|
||||
}
|
||||
|
||||
function cleanVersion(version: string) {
|
||||
// remove 'v' prefix if present
|
||||
return version.replace(/^v/, '')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue