microsoft / rushstack

Monorepo for tools developed by the Rush Stack community
https://rushstack.io/
Other
5.81k stars 592 forks source link

[rush] read in environment variables from `.env` or similar. #2396

Open chopfitzroy opened 3 years ago

chopfitzroy commented 3 years ago

Summary

Would like to be able to load things like NPM_AUTH_TOKEN from a root level .env file or similar (in an OS agnostic way).

Details

Currently the only way to do this is via the flag --npm-auth-token or by setting NPM_AUTH_TOKEN at a more global level.

This can be a bit of a pain if you have developers working in a number of shells (currently the README for our project has CMD/Powershell/Bash/Fish commands to copy paste to create the environment variable).

Was hoping to use something like env-cmd to automatically read from an .env if it is present.

I did try setting up a custom command like rush provision to read in from .env and set the environment variable at a shell level, unfortunately this is not how environment variables work and child processes cannot set variables in parent shells.

Standard questions

Please answer these questions to help us investigate your issue more quickly:

Question Answer
@microsoft/rush globally installed version? 5.35.2
rushVersion from rush.json? 5.35.2
useWorkspaces from rush.json? N/A
Operating system? Windows (WSL 2 - 18.04)
Would you consider contributing a PR? No (Had a look at this commit and I am out of my depth)
Node.js version (node -v)? 14.15.1
apostolisms commented 3 years ago

This is by design and we intentionally made environment variables something to be used by CI machines only. That being said we are not opposed to this proposal, If you want to add this behavior please feel free to open a PR.

leohxj commented 2 years ago

@chopfitzroy do you have some workaround to make it works?

elliot-nelson commented 1 year ago

There was a recent Zulipchat thread about this, so I'll summarize some possible options...

Custom rush plugin

While Rush doesn't offer some kind of "global dotenv" out of the box, you could build it into your monorepo with a plugin. (See Using Rush plugins and Creating plugins in the Rush docs for more info on plugins.)

At a high-level: you'll create a small project in your monorepo for your plugin code, publish it to your private NPM registry, add a rush-plugins autoinstaller with your new plugin as a dependency, and then add the plugin to the rush-plugins config file.

In theory the code is pretty simple:

import dotenv;

// ...

  rushSession.hooks.runAnyPhasedCommand.tapAsync(( ... ) => {
    /* load dotenv from monorepo root here */
  });

This would force any Rush command you run in the monorepo to include the root-level .env file; you could adjust and extend this behavior as necessary for your use case.

That said: I'm not sure you really want to do this, because dotenv is a popular strategy used by many application teams; you may have several teams working on service in your repo already using .env files in their individual projects, potentially with different or conflicting variables. You'd want to make sure it's understand there is a set of global .env files in addition to project-specific .env files at play for local developers.

(But if you're willing to enforce a specific, consistent way for all projects to consume .env and a consistent set of variables they should use, it could be a time-saver when spinning up new projects.)

Existing solutions (direnv)

Another option would be to leave Rush alone completely, and look into existing shell extensions like https://direnv.net/. An advantage to this approach is that if your company chooses it as a standard, it's an approach you can use in any repo (including other repos that are not part of your monorepo, for whatever reason).

A downside is that each developer needs to "opt-in" to getting it set up in their environment. Also, tools that run on every directory change can be a bit slow, adding lag to terminal operations that some developers might find unacceptable.

NPM Registry auth

Finally, I'll note that neither of the above are ideal solutions for NPM_AUTH_TOKEN -- you mentioned this var specifically, but this var is special because very likely a local developer can't rush install or install an autoinstaller at all until it is setup properly. A command, rush setup, was added to assist people who use jFrog Artifactory as their private registry in setting up the local user's .npmrc file; if you use a different private registry, another option would be contributing additional configuration options to this tool (for e.g. GitHub Packages, Nexus, etc.).

elliot-nelson commented 1 year ago

(A dotenv feature is not likely to be built into Rush core, so I will schedule this ticket to be closed after Jan 22.)