Skip to content

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

Merged
jdx merged 2 commits into
jdx:mainfrom
andrewthauer:andrewthauer/fix-mise-env-working-dir
Mar 6, 2026
Merged

fix: pass cwd to all exec calls in exportMiseEnv()#390
jdx merged 2 commits into
jdx:mainfrom
andrewthauer:andrewthauer/fix-mise-env-working-dir

Conversation

@andrewthauer

Copy link
Copy Markdown
Contributor

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

@andrewthauer
andrewthauer requested a review from jdx as a code owner March 6, 2026 15:33
@greptile-apps

greptile-apps Bot commented Mar 6, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes exportMiseEnv() so that working_directory (and its install_dir / process.cwd() fallbacks) is respected when running mise env, making it consistent with all other mise commands in the action that already use the shared mise() helper.

Key changes:

  • A cwd variable is resolved at the top of exportMiseEnv() using the same core.getInput('working_directory') || core.getInput('install_dir') || process.cwd() pattern already used in the mise() helper.
  • { cwd } is now passed to all four exec.getExecOutput calls inside the function: mise env --redacted --json, mise env --json, and both mise env --dotenv fallback paths.
  • The dist/index.js bundle and source map are regenerated to match the source change.
  • The fix directly addresses a CI hang caused by mise 2026.2.0's new lockfile-by-default behavior: without the correct cwd, mise env would try to resolve loose versions from the network and fail in private registry environments.

One pre-existing security best-practice issue was identified: the actual (unredacted) values call should also use silent: true to avoid logging sensitive data to the GitHub Actions output, matching the pattern already used for the redacted values call.

Confidence Score: 4/5

  • Safe to merge once the pre-existing security best-practice issue (missing silent: true on unredacted output) is addressed. Core logic is correct and consistent with existing patterns.
  • The core fix is correct, minimal, and consistent with the established cwd resolution pattern used throughout the codebase. The PR directly solves the stated problem of respecting working_directory in exportMiseEnv(). Score is 4 rather than 5 because: (1) one pre-existing but fixable security best-practice issue should be addressed to prevent logging sensitive data, and (2) the compiled dist/index.js cannot be independently verified in the diff.
  • src/index.ts — one security best-practice finding about logging sensitive data (missing silent: true on the actual values call)

Last reviewed commit: eacf433

@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request resolves a significant bug in the exportMiseEnv() function where the specified working directory was being ignored, leading to incorrect environment variable resolution and potential CI pipeline failures. By correctly determining and applying the intended current working directory to all mise command executions, the change ensures consistent and reliable behavior, especially in complex build environments involving private registries and lockfiles.

Highlights

  • Fix for exportMiseEnv() working directory: Resolved an issue where the exportMiseEnv() function was not respecting the working_directory or install_dir inputs, causing mise env --json to always execute in the process's default current working directory.
  • Prevention of CI hangs: Addressed a critical bug that led to CI hangs, particularly in environments with private npm registries, due to mise attempting to resolve loose tool versions from the network when a mise.lock was not found in the expected directory.
  • Consistent cwd passing: Ensured that the correct cwd (derived from working_directory, install_dir, or process.cwd()) is now passed to all exec.getExecOutput calls within exportMiseEnv(), aligning its behavior with other mise commands.
Changelog
  • src/index.ts
    • Added logic to determine the effective current working directory (cwd) based on working_directory, install_dir, or process.cwd() inputs.
    • Modified all exec.getExecOutput calls within exportMiseEnv() to explicitly pass the resolved cwd option.
Activity
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request addresses a bug where exportMiseEnv() ignored the working_directory, causing mise commands to execute in an incorrect directory. The fix correctly determines the working directory and passes it to all external process calls within the function. The change is logical and directly solves the described problem. I have one suggestion regarding code duplication to improve long-term maintainability.

Comment thread src/index.ts
Comment on lines +85 to +88
const cwd =
core.getInput('working_directory') ||
core.getInput('install_dir') ||
process.cwd()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This logic for determining the cwd is also present in the mise helper function (starting on line 353). To improve maintainability and avoid code duplication, consider extracting this logic into a shared helper function. For example:

function getMiseCwd(): string {
  return (
    core.getInput('working_directory') ||
    core.getInput('install_dir') ||
    process.cwd()
  );
}

This new function could then be called here and in the mise helper function to ensure consistency and a single source of truth for this logic.

@jdx

jdx commented Mar 6, 2026

Copy link
Copy Markdown
Owner

@greptileai

Comment thread src/index.ts
Comment on lines +110 to +112
const actualOutput = await exec.getExecOutput('mise', ['env', '--json'], {
cwd
})

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The call to mise env --json that retrieves actual (unredacted) environment variable values does not set silent: true. This means the real secret values will appear in the GitHub Actions log output, even though masking is applied after.

The preceding mise env --redacted --json call correctly uses { silent: true } to avoid exposing values in logs. The same option should be applied here to prevent logging sensitive data:

Suggested change
const actualOutput = await exec.getExecOutput('mise', ['env', '--json'], {
cwd
})
const actualOutput = await exec.getExecOutput('mise', ['env', '--json'], {
cwd,
silent: true
})

While GitHub Actions' masking should catch these values, the safest approach is to never log them at all.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

double check my thinking here @andrewthauer but I think we don't want to set silent. I think we want to rely on the redactions working. If we didn't do that, it would hide any errors from mise making debugging hard.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@greptileai what do you think?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with your reasoning. Not setting silent: true on the actual mise env --json call is the right approach here because:

  1. Errors need to be visible - If mise fails (e.g., lockfile issues, network problems, config errors), those error messages are critical for debugging and won't contain secrets
  2. Redaction mechanism should work - You're already calling mise env --redacted --json first and registering all the keys with core.setSecret(), so the actual values should be masked when they appear in logs
  3. The pattern is correct - First call (redacted, silent) → register masks → second call (actual, visible but masked) is the right sequence

The only outputs that would appear in logs from the non-silent call are:

  • Error messages (which you need to see)
  • Success output (which should be fully masked by the prior setSecret() calls)

Setting silent: true would hide mise errors and make CI failures much harder to diagnose, especially for the exact lockfile/network issues you're fixing in this PR.

@jdx
jdx merged commit cea720d into jdx:main Mar 6, 2026
18 checks passed
@mise-en-dev mise-en-dev mentioned this pull request Mar 6, 2026
jdx pushed a commit that referenced this pull request Mar 6, 2026
---
## [3.6.3](https://github.com/jdx/mise-action/compare/v3.6.2..v3.6.3) -
2026-03-06

### 🐛 Bug Fixes

- pass cwd to all exec calls in exportMiseEnv() (#390) by
[@andrewthauer](https://github.com/andrewthauer) in
[#390](#390)

### New Contributors

* @andrewthauer made their first contribution in
[#390](#390)

<!-- generated by git-cliff -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants