nx icon indicating copy to clipboard operation
nx copied to clipboard

NX_* Environment Variables not working on prod builds in our test/staging deployments from gitlab, but only sometimes

Open KevinVandy opened this issue 3 years ago • 36 comments

Current Behavior

We use environment variables to point to different aws resources in our dev, test, and prod environments.

Locally, we use a .env file, and prefix all of the environment variables with NX_, like we are supposed to, and it all works fine.

In a Dev environment deployment that we set up that is built in a gitlab pipeline, and deployed to an S3 bucket, it also works fine with the env variables we set up in our gitlab CI/CD settings that are scoped to the dev environments.

However, in the exact same kind of pipeline for our Test (Staging) environment, it seems as if the NX build just simply won't recognize our environmental variables from our gitlab CI/CD settings that we have set there, but sometimes it does. We've tried adding the --skip-nx-cache to see if that was messing it up or not. Lately it seems like if we commit and push directly to our main branch, the build will include our env variables just fine, but if we make a merge request, and have a merge commit that results in the pipeline, none of our env variables get used and they are all undefined.

Here are our gitlab-ci steps for both of those pipelines. In the pipeline, we echo some of the variables that have been set as a sanity check to make sure gitlab itself is not misconfigured during the pipeline.

# store node_modules in a cache
cache:
  untracked: true
  key: '*******_portals_node_cache'
  paths:
    - node_modules/

# build apps dev
build_ap_dev:
  stage: build
  dependencies: []
  environment:
    name: ap_dev
    action: prepare
  only:
    - develop
    - /(^\d)*-feature-.*/
    - /(^\d)*-bugfix-.*/
  script:
    - echo "cognito user pool - $NX_COGNITO_USER_POOLS_ID" # successfully echos here, so gitlab variable not a problem
    - yarn build-ap --prod --skip-nx-cache
    - echo "Build Successful"
  artifacts:
    expire_in: 4 hour
    paths:
      - dist/apps/agent-portal-frontend

build_ap_test:
  stage: build
  dependencies: []
  environment:
    name: ap_test
    action: prepare
  only:
    - main
    - /(^\d)*-hotfix-.*/
  script:
    - echo "cognito user pool - $NX_COGNITO_USER_POOLS_ID" # successfully echos here, so gitlab variable not a problem
    - yarn build-ap --prod --skip-nx-cache
    - echo "Build Successful"
  artifacts:
    expire_in: 4 hour
    paths:
      - dist/apps/agent-portal-frontend

package.json build scripts are kept simple, the pipeline adds the flags we need above

Screenshot-20210827123053-497x78

Other things from googling around, we've tried making sure our environment.prod.ts is like this:

export const environment = {
  production: false,
};

Might this be related to some kind of Nx caching issue that gets stored in our node_modules cache for our pipelines?

Expected Behavior

Nx environment variables should work in all environments (dev, test, prod) when all of them have the same build command.

yarn build-appname --prod

Steps to Reproduce

  1. Set up environment variables on gitlab CI/CD that are scoped to specific environments
  2. Develop locally with a .env file in the root of the monorepo with variables that are prefixed with NX_*
  3. Make Merge Request to develop branch and merge - DEV environment build works fine.
  4. Make Merge Request from develop to main branch and merge - TEST environment build is missing env variables.
  5. Panic and directly commit some console.logs of env variables on the main branch and run a new pipeline in TEST env - It sometimes magically works, but sometimes not.

Failure Logs

When we download the artifacts from the build to look to see if the variables got used by Nx, we don't see them in a grep, is this normal?

Screenshot-20210827120917-1190x1013

Environment

env for my local machine, but problem happens in our pipelines that run on a node:15.14 docker image

nx report

>  NX  Report complete - copy this into the issue template

  Node : 15.14.0
  OS   : linux x64
  yarn : 1.22.5
  
  nx : Not Found
  @nrwl/angular : Not Found
  @nrwl/cli : 12.6.4
  @nrwl/cypress : 12.6.4
  @nrwl/devkit : 12.6.4
  @nrwl/eslint-plugin-nx : 12.6.4
  @nrwl/express : Not Found
  @nrwl/jest : 12.6.4
  @nrwl/linter : 12.6.4
  @nrwl/nest : Not Found
  @nrwl/next : Not Found
  @nrwl/node : Not Found
  @nrwl/nx-cloud : Not Found
  @nrwl/react : 12.6.4
  @nrwl/schematics : Not Found
  @nrwl/tao : 12.6.4
  @nrwl/web : 12.6.4
  @nrwl/workspace : 12.6.4
  @nrwl/storybook : 12.7.2
  @nrwl/gatsby : Not Found
  typescript : 4.3.5

KevinVandy avatar Aug 30 '21 13:08 KevinVandy

I noticed updating from nx 12.6.3 to 12.8.0, dotenv got updated. And looking at the releases, it seems to be in your interest to at least do this update.

marckassay avatar Aug 30 '21 16:08 marckassay

update, we upgraded to the Nx 12.8 releases last week, and the first few deploys were successful. But now a few days later, with no package upgrades at all, we have had the exact same problem pop up again where we know that our gitlab env variables are being set correctly, but every other Nx build in our dev environment has undefined env vars

KevinVandy avatar Sep 10 '21 01:09 KevinVandy

Hi, any solution so far? Our team is having the same problem on production builds with env variables being undefined

sediatis avatar Oct 06 '21 09:10 sediatis

Hi, any solution so far? Our team is having the same problem on production builds with env variables being undefined

Yes, but it is a slow workaround. We added a line in our pipeline scripts to delete node_modules/.cache/nx so that is guaranteed to rerun the entire build step during the build step in our gitlab pipeline.

KevinVandy avatar Oct 12 '21 01:10 KevinVandy

Hi, can this be prioritized please? Currently environment variables are not being read and it is a big issue

StallionV avatar Oct 20 '21 04:10 StallionV

+1

istvandesign avatar Nov 03 '21 20:11 istvandesign

I'm not certain if it's an identical issue, but it sure seems similar: My project, running Nx v13.0.2 presently, has zero problems whatsoever with environment issues when started or built normally. However, when I run my Cypress e2e tests, they all disappear completely. This makes very little sense to me, since I assumed the same Webpack config was being used to build both versions out... but when I check my variables while running the watcher used to execute Cypress tests, all I see are these:

{
  "NODE_ENV": "development",
  "NX_CLI_SET": "true",
  "NX_INVOKED_BY_RUNNER": "true",
  "NX_WORKSPACE_ROOT": "<dir>/parfait-nx",
  "NX_TASK_TARGET_PROJECT": "parfait-e2e",
  "NX_TASK_HASH": "<hash>"
}

There are around a dozen environment variables (usually read from my .env file) missing from that readout.

crates avatar Nov 17 '21 22:11 crates

have u find any solution? Im also facing this issue right now

nurbashanghai avatar Dec 03 '21 09:12 nurbashanghai

@nurbashanghai - That depends. If you're having Kevin Vandy's problem, I can't help you. However, if you're having the same issue I was having (where the env vars don't populate for Cypress tests), you are in luck my friend!

I worked around this issue by manually bootstrapping the environment variables already available in my project, using the env-cmd NPM package. Here's the updated package.json command I use to launch my end-to-end tests: env-cmd -f ./apps/myapp/.env nx e2e myapp-e2e

Eventually, I imagine the Nx team will find and fix this bug. The good news is that regardless of if/when/how they do that, this fix should remain working regardless.

crates avatar Dec 03 '21 14:12 crates

We're having the same issue right now, using Azure pipelines. All environment variables set with a .env file are gone, it would be great if this gets addressed.

Graveheart avatar Dec 09 '21 12:12 Graveheart

We have a very similar issue @KevinVandy, the env variables are cached between builds when going through a complete Git flow (push branch for PR review -> merge to dev -> PR dev to main -> merge to main).

If we push directly from the local main branch from the CLI to the remote main, the values are properly set.

This have a big impact for us because we control the meta robots index/follow through env variables, where we allow some content pages indexation only on production. At the moment, every time we push to main after going through a full Git flow, we have to do an extra & empty "magic" push directly from the main local branch (described above) to get the good values...

We are using Vercel for the deployments and we thought it was an issue on their end with the builds cache, but it might be more complex than that, based on several discussions I could find (including this one):

  • https://github.com/nrwl/nx/issues/4662
  • https://github.com/nrwl/nx/issues/4455

We are using Nx 12.7.2, we did not try to upgrade to the latest yet

rlenoir-codepoint avatar Dec 14 '21 09:12 rlenoir-codepoint

Just FYI, upgrading to the latest NX 13.3.1 didn't fix the issue. It happens to us when using Dockerfile in the pipeline but it doesn't happen when running nx build from the pipeline itself.

Graveheart avatar Dec 14 '21 09:12 Graveheart

At last, I found a solution by using dotenv-webpack plugin and passing a .env file to it! I tried it with env-cmd too but it didn't help while running nx build

Graveheart avatar Dec 14 '21 10:12 Graveheart

@vsavkin ~ Any thoughts? It looks like env vars are broken for quite a few folks. Is this on the roadmap for a fix?

crates avatar Dec 14 '21 16:12 crates

Nx why have you forsaken us?

KevinVandy avatar Dec 14 '21 16:12 KevinVandy

This is a major problem. I just recently started to use NX and now I'm wondering if I should back out. My prod builds are simply broken atm. It's kind of worst possible case.

kryptus36 avatar Dec 31 '21 20:12 kryptus36

This is a major problem. I just recently started to use NX and now I'm wondering if I should back out. My prod builds are simply broken atm. It's kind of worst possible case.

We have a solution to be clear, it just makes the builds go a lot slower.

Yes, but it is a slow workaround. We added a line in our pipeline scripts to delete node_modules/.cache/nx so that is guaranteed to rerun the entire build step during the build step in our gitlab pipeline.

KevinVandy avatar Jan 03 '22 15:01 KevinVandy

This is a major problem. I just recently started to use NX and now I'm wondering if I should back out. My prod builds are simply broken atm. It's kind of worst possible case.

We have a solution to be clear, it just makes the builds go a lot slower.

Yes, but it is a slow workaround. We added a line in our pipeline scripts to delete node_modules/.cache/nx so that is guaranteed to rerun the entire build step during the build step in our gitlab pipeline.

That didn't work for me. Oddly my nestjs app picks up my environment from Kubernetes, but react doesn't. My issue may be different. But I'm not sure what to do either way.

kryptus36 avatar Jan 07 '22 21:01 kryptus36

Same problem here deploying to Vercel. I have multiple CRA & Nextjs apps in the workspace.

niek-dev avatar Feb 01 '22 23:02 niek-dev

Can confirm that this is a problem for builds. I haven't tested it on Vercel, but running the built version of my app locally shows that the environment variables aren't being passed in.

nichwch avatar Mar 28 '22 23:03 nichwch

This is ridiculous, how has this not been resolved by now

JamesGrom avatar Apr 02 '22 17:04 JamesGrom

I have not really had problems with environment variables, but found today that NX_INVOKED_BY_RUNNER doesn't seem to be set in some cases. I can't even find the code that sets it anymore. This breaks a whole bunch of our targets. Is this a known issue?

richtera avatar Apr 20 '22 12:04 richtera

Have you all just investigate pure JavaScript files you have? As it's converted during compilation time.

Lonli-Lokli avatar Apr 23 '22 21:04 Lonli-Lokli

I was able to get this working using runtimeCacheInputs something like:

"tasksRunnerOptions": {
    "default": {
      "runner": "@nrwl/workspace/tasks-runners/default",
      "options": {
        "cacheableOperations": [
          "build",
          "lint",
          "test",
          "e2e"
        ],
        "runtimeCacheInputs": [
          "echo $NX_ENV_VARIABLE",
          "echo $NX_ENV_VARIABLE_1",
          "echo $NX_ENV_VARIABLE_2",
          "echo $NX_ENV_VARIABLE_3"
        ]
      }
    }
  },

Maybe this might help someone else

sohailykhan94 avatar Apr 26 '22 17:04 sohailykhan94

+1

hoevelmanns avatar Sep 21 '22 15:09 hoevelmanns

I try to use Runtime Hash Inputs by watching some ENV changed and NX still not invalidate cache. But if I use

  "targetDefaults": {
    "build": {
      "dependsOn": ["^build"],
      "inputs": [
        {
          "runtime": "cat .env"
        }
      ]
    }
  },

NX will invalidate cache, not sure this is proper way?

tanint avatar Sep 23 '22 20:09 tanint

Any help with this? We still cannot seem to read the env vars on production.

sediatis avatar Sep 24 '22 17:09 sediatis

I was having the same issue as well. My situation is that I'm using environment variables to determine if the environment is a preview or production. I would build out on staging and if the staging build is good to go, I'd rebase that onto production (which triggers a rebuild on Vercel). But, because of Nx caching, the env. vars would still be on staging, even though it was just rebuilt on production.

As soon as I implemented https://github.com/nrwl/nx/issues/6891#issuecomment-1110052748 solution, it now works as expected.

l1qu1d avatar Nov 16 '22 07:11 l1qu1d

I was having the same issue as well. My situation is that I'm using environment variables to determine if the environment is a preview or production. I would build out on staging and if the staging build is good to go, I'd rebase that onto production (which triggers a rebuild on Vercel). But, because of Nx caching, the env. vars would still be on staging, even though it was just rebuilt on production.

As soon as I implemented #6891 (comment) solution, it now works as expected.

@l1qu1d Interesting, that did not work for me, in fact, the only thing on this issue that worked was https://github.com/nrwl/nx/issues/6891#issuecomment-1256641188. Thanks @tanint

I don't think this should be necessary, though nor am I sure what the proper solution is. It's very surprising that such an important issue is open for so long.

jamesbhobbs avatar Dec 31 '22 10:12 jamesbhobbs

I was having the same issue as well. My situation is that I'm using environment variables to determine if the environment is a preview or production. I would build out on staging and if the staging build is good to go, I'd rebase that onto production (which triggers a rebuild on Vercel). But, because of Nx caching, the env. vars would still be on staging, even though it was just rebuilt on production. As soon as I implemented #6891 (comment) solution, it now works as expected.

@l1qu1d Interesting, that did not work for me, in fact, the only thing on this issue that worked was #6891 (comment). Thanks @tanint

I don't think this should be necessary, though nor am I sure what the proper solution is. It's very surprising that such an important issue is open for so long.

@benjaminhobbs I was stating my situation and what I believe is the cause, not a solution to the problem. The solution that you referenced is the same one that I did as well.

l1qu1d avatar Dec 31 '22 18:12 l1qu1d