fix: pass cwd to all exec calls in exportMiseEnv() (#390)

## Problem

The `exportMiseEnv()` function ignores the `working_directory` (and
`install_dir`) input when running `mise env --json`. It always executes
in the process default CWD — the GitHub Actions workspace root —
regardless of what directory was used for `mise install`.

This means if a caller sets `working_directory: path/to/subdir`, mise
resolves environment variables against the workspace root's `mise.toml`,
not the intended subdirectory's config.

### Impact

Since mise 2026.2.0, lockfiles are enabled by default. When `mise env
--json` runs without a `mise.lock` present (e.g. because the correct
`working_directory` was not used), mise attempts to resolve loose tool
versions (like `"latest"`) from the network. In environments with
private npm registries, this causes `npm view` calls that fail with 403
errors. Mise retries indefinitely, spawning 20+ orphaned npm processes
and eventually hitting `EAGAIN` (OS error 11), hanging CI permanently.

The other mise commands (`miseInstall`, `miseReshim`, etc.) already pass
`cwd` correctly via the shared `mise()` helper. Only `exportMiseEnv()`
was missing this.

## Fix

Resolve `working_directory` (falling back to `install_dir`, then
`process.cwd()`) at the top of `exportMiseEnv()` and pass `{ cwd }` to
all four `exec.getExecOutput` calls within the function:

- `mise env --redacted --json`
- `mise env --json`
- `mise env --dotenv` (redacted fallback)
- `mise env --dotenv` (legacy fallback)

## Related

- Issue #267: `working_directory` not respected for env export

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
Andrew Thauer 2026-03-06 11:12:44 -05:00 committed by GitHub
parent e79ddf65a1
commit cea720d8cd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 29 additions and 9 deletions

View file

@ -82,6 +82,11 @@ async function run(): Promise<void> {
async function exportMiseEnv(): Promise<void> {
core.startGroup('Exporting mise environment variables')
const cwd =
core.getInput('working_directory') ||
core.getInput('install_dir') ||
process.cwd()
// Check if mise supports --redacted flags based on version input
const supportsRedacted = checkMiseSupportsRedacted()
@ -91,7 +96,7 @@ async function exportMiseEnv(): Promise<void> {
const redactedOutput = await exec.getExecOutput(
'mise',
['env', '--redacted', '--json'],
{ silent: true }
{ silent: true, cwd }
)
const redactedVars = JSON.parse(redactedOutput.stdout)
@ -102,7 +107,9 @@ async function exportMiseEnv(): Promise<void> {
}
// Then get the actual values
const actualOutput = await exec.getExecOutput('mise', ['env', '--json'])
const actualOutput = await exec.getExecOutput('mise', ['env', '--json'], {
cwd
})
const actualVars = JSON.parse(actualOutput.stdout)
// Export all environment variables
@ -114,12 +121,16 @@ async function exportMiseEnv(): Promise<void> {
} catch {
// Fall back to dotenv format if the redacted command fails
core.info('Falling back to dotenv format')
const output = await exec.getExecOutput('mise', ['env', '--dotenv'])
const output = await exec.getExecOutput('mise', ['env', '--dotenv'], {
cwd
})
fs.appendFileSync(process.env.GITHUB_ENV!, output.stdout)
}
} else {
// Fall back to the old --dotenv format for older versions
const output = await exec.getExecOutput('mise', ['env', '--dotenv'])
const output = await exec.getExecOutput('mise', ['env', '--dotenv'], {
cwd
})
fs.appendFileSync(process.env.GITHUB_ENV!, output.stdout)
}