Non-deterministic builds? Longstanding issue w/ env vars

Hey folks,

Site name: well we have dozens but here’s an example one: soti-alpha

It is a static site (vue app + browser video game) that is built using TypeScript & Parcel.js.

We use dotenv paired with the NODE_ENV flag for environment variables per environment.

So in the repository we’ve got files like:

.env.local
.env.qa
.env.production

Which contain variables like:

(.env.local)
SOME_ENV_VAR=valueForLocal

(.env.qa)
SOME_ENV_VAR=valueForQA

(.env.production)
SOME_ENV_VAR=valueForProduction

And we want those variables to be different per environment when we build and deploy to Netlify.

In ~80% of builds that we do, this combination of tech all works fine! But in roughly ~1 in 5 deploys, it ends up picking the values from .env.local, so we’ll get a deployment to https://alpha.soti.io/ that has the website built with the value: valueForLocal instead of the value it should have of valueForQA (the value for the env var in .env.qa for example, if the destination environment was QA).

I’ve had this recurring issue with Netlify for 2 years now (literally), but it’s been infrequent enough that I haven’t bothered to post about it. This week I decided I should :slight_smile:

Our deployment process for these 2 years, in light of this bug, has been:

  1. Deploy
  2. Check if the env var bug is present (see if the deployment that just finished is using incorrect .env.local values)
  3. If no, do nothing - deployment successful
  4. If yes: boot up netlify, trigger a cache wipe deploy, and the issue will be resolved

This means some deploys (~1 in 5) necessitate a 2nd deploy, and will have a narrow window of time where the site is actually broken.

Am I missing something obvious? Any advice?

I’m not an expert on how dotenv works - I think that’s what reads your env files, yes? I usually recommend people avoid it since it doesn’t “just work” perfectly for all cases at netlify (cf [Support Guide] Using environment variables on Netlify correctly)

I’d suggest instead using our deploy contexts to set things via netlify.toml - any chance that your workflow could be adapted to that?

If not, I’d suggest at a minimum to abort your build if it is set wrong - you could check before starting build, something like:

if [ "$SOME_ENV_VAR" == "localvalue"] ; then exit 1; fi && your-normal-build-command

Happy to take a bug report if you can find a reliable reproduction step too but this will maybe help you avoid the 20% bad builds with no major effort :slight_smile:

@fool no I don’t think that using netlify deploy contexts will solve the issue because the feature of parcel that we are using is hard-baked into dotenv integration, and actually modifies the compiled code as a result of the values read from the dot env file.

For example, say we had this code:

if (process.env.NODE_ENV === 'production') {
  // code to only be in the production build
}

And while compilation is taking place, NODE_ENV is set to ‘beta’ not ‘production’ – then that entire if statement actually won’t be present in the compiled code at all. So I say this to say that it is a very tight and explicit integration between dotenv and parcel - not one that could be subbed in to use netlify TOML files unless an equivalent parcel integration was created (something for your developer advocacy team to make and contribute to Parcel, perhaps?).

We will try what you suggested here w.r.t. the bash interjection prior to running the build command and see where it takes us!