microsoft/rushstack

[heft] `set-environment-variables-plugin` variables remain set in unrelated phases

Opened this issue · 0 comments

Summary

The @rushstack/heft plugin set-environment-variables-plugin sets the environment variable for the entire Heft process, not just the currently running phase. Since it is a taskPlugin, ideally it should only impact the phase that the plugin is declared in. However, since it sets the value on the process.env, it impacts other Heft phases that are running in parallel, and also remains set for downstream phases.

Repro steps

  • Add the set-environment-variables-plugin task plugin to a phase and set some environment variable

  • Observe the environment variable value in depending phases, or phases that run in parallel

    Expected result: The environment variable does not exist in parallel or downstream phases

    Actual result: Phases or tasks that run after the execution of the task containing the plugin have the environment variable set, regardless of phase

Details

This is caused because there is no process isolation in Heft at the phase level, so any environment variables set by the plugin will apply to all other tasks. There are a couple options here:

  • Implement phase-level process isolation in Heft. This could also have some other benefits in terms of parallelism on multi-core machines, but would be impacted by having to reload all imports in each new process due to missing the node_modules require cache. This is essentially how Rush executes our Heft-based phases in the Rushstack repo already, but would also now do it internal when running Heft
  • Make the set-environment-variables-plugin into a lifecyclePlugin, so that it's implicit that the environment variable should be set on all phases. However, this removes some of the more targeting utility of the plugin if left as a taskPlugin

Ideally, both of the above suggestions could be implemented, allowing the plugin to be both a lifecyclePlugin and a taskPlugin for increased utility, while also introducing phase-level process isolation.