Skip to content

fix(env): resolve sourced env for tool templates#7895

Merged
jdx merged 11 commits intojdx:mainfrom
corymhall:fix-env-resolution
Feb 4, 2026
Merged

fix(env): resolve sourced env for tool templates#7895
jdx merged 11 commits intojdx:mainfrom
corymhall:fix-env-resolution

Conversation

@corymhall
Copy link
Contributor

Tool versions that template env vars are rendered while reading mise.toml, so only literal [env] values were available in the context. This meant values from _.source / vfox env modules were missing, causing "Variable env.* not found" errors when tools referenced those vars.

This change resolves non-tool env results during config load and merges them into the per-file Tera context used for tool version rendering. The merge preserves local [env] values defined in the file, then overlays resolved env results (including removals) so sourced values are visible without changing explicit per-file overrides.

Examples:

[env]
_.source = "./set-go-version.sh"
[tools]
go = "{{env.MY_GO_VERSION}}"
[env]
_.vfox-myplugin = {}
[tools]
go = "{{env.MY_GO_VERSION}}"

Rationale:

  • Aligns tool templating with the documented "tools = true" / lazy env behavior by ensuring env directives are resolved before tool version templating.
  • Avoids changing tool resolution order beyond existing non-tools env pass.

Discussions:

Tool versions that template env vars are rendered while reading mise.toml,
so only literal [env] values were available in the context. This meant values
from _.source / vfox env modules were missing, causing "Variable env.* not found"
errors when tools referenced those vars.

This change resolves non-tool env results during config load and merges them
into the per-file Tera context used for tool version rendering. The merge
preserves local [env] values defined in the file, then overlays resolved env
results (including removals) so sourced values are visible without changing
explicit per-file overrides.

Examples:
```toml
[env]
_.source = "./set-go-version.sh"
[tools]
go = "{{env.MY_GO_VERSION}}"
```

```toml
[env]
_.vfox-myplugin = {}
[tools]
go = "{{env.MY_GO_VERSION}}"
```

Rationale:
- Aligns tool templating with the documented "tools = true" / lazy env behavior
  by ensuring env directives are resolved before tool version templating.
- Avoids changing tool resolution order beyond existing non-tools env pass.

Discussions:
- jdx#5733
- jdx#3782
Copilot AI review requested due to automatic review settings January 29, 2026 17:07
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes an issue where tool versions using env var templates could only access literal [env] values, not those from _.source directives or vfox env modules. The fix resolves non-tool env results during config load and merges them into the Tera context used for tool version rendering.

Changes:

  • Pre-resolves env results during config load to ensure sourced env vars are available
  • Merges resolved env results into per-file Tera context for tool version templating
  • Updates method signatures to use Arc<Config> where needed for async operations

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated no comments.

File Description
src/toolset/tool_request_set.rs Changed build and load_config_files to accept &Arc<Config> instead of &Config to support async env_results calls
src/config/mod.rs Added env_results_cached() method and pre-resolves env results during config load; updated get_tool_request_set() to require Arc<Self>
src/config/config_file/mise_toml.rs Modified to_tool_request_set() to merge cached env results into the Tera context before rendering tool versions; added test for env source vars in tools
mise.lock Added macOS ARM64 checksum for wait-for-gh-rate-limit tool

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jdx
Copy link
Owner

jdx commented Jan 30, 2026

/gemini review

Copy link
Contributor

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

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 correctly resolves an issue where sourced environment variables were not available for tool version templating. The approach of resolving non-tool environment variables during config load and merging them into the Tera context is sound. The changes are well-contained and include a new test case that validates the fix. I have one minor suggestion to improve performance.

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@jdx jdx marked this pull request as draft January 30, 2026 11:16
@corymhall
Copy link
Contributor Author

The original fix makes env directives (e.g., _.source, _.file, vfox env modules) available to tool version templates by resolving non‑tool env during config load. This is the desired behavior, but it moved module execution before the existing toolset env cache, which reintroduced the “plugins run every time”
regression (e2e/env/test_env_cache_plugin).

This change keeps the new behavior and restores the cache invariants by introducing a dedicated cache for non‑tool env results (i.e., ToolsFilter::NonToolsOnly) used during config load.

Key Changes

  1. Non‑tool env cache
    • Added CachedNonToolEnv in src/toolset/env_cache.rs.
    • Reuses the same encryption/TTL + watch file validation as the existing env cache.
    • Cache key uses config file mtimes, settings hash, base PATH (and a "non-tool-env" salt) — no tool versions.
    • Stores the parts of EnvResults needed for templating: env, env_remove, env_paths, env_files, env_scripts, redactions, watch_files, etc.
  2. Cache-aware config‑time env resolution
    • Config::load_env now:
      • Loads from CachedNonToolEnv if enabled and valid.
      • On cache miss, resolves directives and saves back to cache if !has_uncacheable.
    • Maintains existing eager resolution for templating, but with a fast path.
  3. Docs update
    • docs/dev-tools/index.md now reflects the intended behavior: tool templates can use env values from the config hierarchy, including env directives/modules.

Why this fixes CI

e2e/env/test_env_cache_plugin validates that MISE_ENV_CACHE=1 prevents plugin re‑execution across runs.
Previously, modules were executed during config load, before the toolset cache check.
With this change, config‑time env resolution is cached separately and avoids re‑running plugins when the cache is valid.

Behavioral Implications

  • Tool templates now see env values resolved from env directives across the config hierarchy (parent + child configs).
  • Env cache behavior remains intact:
    • Plugins can still mark results cacheable = true and supply watch_files.
    • Cache invalidates on config mtime changes, watch file changes, settings changes, TTL, mise version, etc.
  • Toolset env cache remains unchanged (still keyed on tool versions).

@corymhall corymhall marked this pull request as ready for review February 4, 2026 10:33
@jdx jdx merged commit 63ab65f into jdx:main Feb 4, 2026
34 checks passed
mise-en-dev added a commit that referenced this pull request Feb 5, 2026
### 🐛 Bug Fixes

- **(env)** resolve sourced env for tool templates by @corymhall in
[#7895](#7895)
- **(npm)** only declare the configured package manager as a dependency
by @jdx in [#7995](#7995)
- **(upgrade)** respect use_locked_version when checking tracked configs
by @jdx in [#7997](#7997)
- ignore MISE_TOOL_VERSION in env var parsing by @jdx in
[#8004](#8004)

### New Contributors

- @corymhall made their first contribution in
[#7895](#7895)
github-merge-queue bot pushed a commit to pulumi/ci-mgmt that referenced this pull request Feb 13, 2026
This is no longer required as
jdx/mise#6339 has been resolved by
jdx/mise#7895 (thanks again @corymhall). We can
now consume `env` variables directly.

Given the huge blast radius of this change, I am triggering a dry-run on
all providers first:
https://github.com/pulumi/ci-mgmt/actions/runs/21947234269

From that run the only workflows that failed were:
* pulumi/pulumi-gcp#3583
* pulumi/pulumi-vault#954
* pulumi/pulumi-terraform-module#727
* pulumi/pulumi-kubernetes#4141

And I verified those errors are unrelated to the change itself.
lucasew pushed a commit to lucasew/CONTRIB-mise that referenced this pull request Feb 18, 2026
Tool versions that template env vars are rendered while reading
mise.toml, so only literal [env] values were available in the context.
This meant values from _.source / vfox env modules were missing, causing
"Variable env.* not found" errors when tools referenced those vars.

This change resolves non-tool env results during config load and merges
them into the per-file Tera context used for tool version rendering. The
merge preserves local [env] values defined in the file, then overlays
resolved env results (including removals) so sourced values are visible
without changing explicit per-file overrides.

Examples:
```toml
[env]
_.source = "./set-go-version.sh"
[tools]
go = "{{env.MY_GO_VERSION}}"
```

```toml
[env]
_.vfox-myplugin = {}
[tools]
go = "{{env.MY_GO_VERSION}}"
```

Rationale:
- Aligns tool templating with the documented "tools = true" / lazy env
behavior by ensuring env directives are resolved before tool version
templating.
- Avoids changing tool resolution order beyond existing non-tools env
pass.

Discussions:
- jdx#5733
- jdx#3782

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
lucasew pushed a commit to lucasew/CONTRIB-mise that referenced this pull request Feb 18, 2026
### 🐛 Bug Fixes

- **(env)** resolve sourced env for tool templates by @corymhall in
[jdx#7895](jdx#7895)
- **(npm)** only declare the configured package manager as a dependency
by @jdx in [jdx#7995](jdx#7995)
- **(upgrade)** respect use_locked_version when checking tracked configs
by @jdx in [jdx#7997](jdx#7997)
- ignore MISE_TOOL_VERSION in env var parsing by @jdx in
[jdx#8004](jdx#8004)

### New Contributors

- @corymhall made their first contribution in
[jdx#7895](jdx#7895)
github-merge-queue bot pushed a commit to pulumi/ci-mgmt that referenced this pull request Feb 19, 2026
Previously:
* #2040
* #2055

This is no longer required as
jdx/mise#6339 has been resolved by
jdx/mise#7895 (thanks again @corymhall). We can
now consume `env` variables directly.

Verified this change locally with `pulumi-eks`, `pulumi-gcp` and
`pulumi-aws`.
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.

3 participants