-
Notifications
You must be signed in to change notification settings - Fork 57
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve environment variables in local builds #2040
Conversation
@@ -1,3 +1,4 @@ | |||
/* eslint-disable max-lines */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be fixed in a separate PR.
This is amazing, thank you for this. Great to align our logic and remove duplication.
I find these logs quite useful for debugging. Maybe @fool or someone else from support can comment on this.
Missing env variables are most likely to break functionality, for example missing auth tokens, secrets, etc. This is the case for the
Offline is an explicit choice. I assume it is mostly used when a user doesn't have an internet connection and still wants to run
We can solve this by retrying requests (we've discussed this before in regards with the
I think it should be
We can solve this by adding a source property to each env.
I believe you're correct here. |
Thanks a lot for pondering this PR @erezrokah, this is a tricky one. For the source of each env, I'm going to add this by returning I will fix the priority order to For the offline flag, I'd still think not requiring an explicit opt-in and guessing it instead (e.g. by making a HTTP request or by using |
This is a great solution.
I agree, this should at least come with a log warning if
I think we should keep the current behaviour until we reach some product decisions here considering:
Sadly, we're not so close to reaching 3 specifically for Removing code duplicate is a big step forward to aligning commands behaviour. So far we've being doing it one step at a time depending on the area of the code we touch, but maybe there is a place for a more dedicated effort. |
Thanks, this makes total sense. This means:
When it comes to
Missing those (especially the UI build settings) will often result in local build errors. Not only would this confuse errors, but this would also create support issues/tickets from those users. We could possibly not fail providing |
I think you mean The defaults you presented makes sense for Netlify build and for the CLI we would need to provide slightly other defaults. I see 3 scenarios here:
I think that level of granularity should be controlled by the CLI and configurable via TLDR: we're good to move forward with this 🚀 |
2a698ba
to
c2920ae
Compare
packages/build/src/core/flags.js
Outdated
@@ -1,3 +1,5 @@ | |||
/* eslint-disable max-lines */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no great benefit in splitting this file.
I fixed all the points above. I renamed Since this is a breaking change for Netlify CLI, this would be released as a major release. According to the above discussion, those are some follow-up we would need to do in the Netlify CLI to upgrade:
Please let me know if I missed anything, and we can create issues for those. |
This looks good. I'm going to test this PR locally with the CLI starting next week |
Great! |
Sure. I'm going to link |
21ec85a
to
c3636e0
Compare
Site's environment variables. Each property is an object of key-value pairs: | ||
|
||
- `general`: general environment variables set for all sites | ||
- `account`: environment variables set in the Netlify UI for a specific account |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The term account
is widely used in netlify/build
, but CLI uses team
. Should we try to standardise this? If so, which one should we adopt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes we should, great point :) We refer to those publicly as team:
So it make sense to me to use that term. @ehmicky WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point! I opened an issue at https://github.com/netlify/build/issues/2164
I have a question, looking at this from the CLI side. We're now getting from However, in CLI there are two additional sources that we need to add to the mix (both of which have a higher precedence than the vars coming from config):
But CLI doesn't really know what source X is, because the precedence chain has been computed by One option would be to change the shape of the {
"TEST_VAR_1": {
"value": "foo",
"source": "team"
},
"TEST_VAR_2": {
"value": "bar",
"source": "ui"
},
"GATSBY_TELEMETRY_DISABLED": {
"value": "1",
"source": "general"
}
} What do we think? Do you see any downsides of this approach? |
This looks good to me. does that mean we can simplify |
Yes, we can turn those properties into arrays. Alternatively, we can get rid of them altogether and have {
"TEST_VAR_1": {
"value": "foo",
"sources": ["team", "addons"]
},
"TEST_VAR_2": {
"value": "bar",
"sources": ["ui"]
},
"GATSBY_TELEMETRY_DISABLED": {
"value": "1",
"sources": ["general", "team"]
}
} Where |
That's even better :) |
I made the changes described above. For convenience, here's a direct link to the diff of my commits: https://github.com/netlify/build/pull/2040/files/c3636e0a0f59b2f37ce50b98d91cb41bb624f467..a0a499671faed7b01d12a871aae1132614f24462. @ehmicky I tried adding you as a reviewer, but GitHub won't let me, since you created the PR. |
packages/config/src/env/main.js
Outdated
}) | ||
}) | ||
|
||
return environment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[sand] Would using map-obj
help remove the linting warnings, and maybe simplify the logic? For example:
const envs = [generalEnv, accountEnv, addonsEnv, uiEnv, configFileEnv]
const envNames = ['general', 'account', 'addons', 'ui', 'configFile']
return mapObj(Object.assign({}, ...envs), (name, value) => [
name,
sources: envs.filter((env) => env[name] !== undefined).map((_, index) => envNames[index]),
])
(alternative: merge envs
and envNames
to a single object and use Object.entries()
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't too happy about disabling the linting rule, so I'm glad you brought this up.
I tried a different alternatives and wasn't convinced by any of them, but usingmap-obj
is an interesting approach. Personally, I still find the mutation route easier to read, but not enough to justify disabling linting rules.
I'll change it. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
Oh, that's ideal. I'll use it. Thanks! |
@eduardoboucas The changes look great, thanks! 🎉 |
Done in cdd3953. |
cdd3953
to
d0ef738
Compare
- `addons`: addon-specific environment variables | ||
- `ui`: environment variables set in the Netlify UI for a specific site | ||
- `configFile`: environment variables set in `netlify.toml` | ||
- `all`: all of the above, merged |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@eduardoboucas We probably should update this section of the README.md
.
// The buildbot already has the right environment variables. This is mostly | ||
// meant so that local builds can mimic production builds | ||
// TODO: add `netlify.toml` `build.environment`, after normalization | ||
// TODO: add `CONTEXT` and others |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can remove the 2 above TODO
comments.
Fixes #2036.
This PR improves how environment variables are handled in local builds by moving most of the logic from
@netlify/build
to@netlify/config
The main benefits are:
URL
,REPOSITORY_URL
,DEPLOY_ID
,CONTEXT
,LANG
,LANGUAGE
,LC_ALL
,GATSBY_TELEMETRY_DISABLED
,NEXT_TELEMETRY_DISABLED
,BRANCH
,HEAD
,PULL_REQUEST
,COMMIT_REF
,CACHED_COMMIT_REF
.@netlify/build
,@netlify/config
,netlify-cli
) to to a single place (@netlify/config
)The behavior of
@netlify/build
should not change, neither locally nor in production.The main change is that, in local builds (not production),
@netlify/config
now returns asiteEnv
plain object.siteEnv
emulates the set of environment variables in production. This allows local builds and CLI commands (netlify build
,netlify dev
,netlify dev:exec
andnetlify functions:create
) to mimic production behavior. This would replace the current logic in the CLI (getSiteInformation()
). Note: since a singlesiteEnv
object is returned, we don't have enough granularity to know where an environment variable came from. The logs printing the injected environment variables in the CLI would need to be simplified (or even removed? Do we need those?). Please let me know if you think this is a problem.@netlify/config
makes 3 API calls to retrieve site, account and addons environment variables. If the API call fails (or return a response with an invalid shape), it ignores those silently. This is meant to work like the--offline
CLI flag, but without the user having to specify when they are offline or not to turn on/off error messages, which I believe might be a simpler experience. This is also more resilient to users experiencing temporary network problems.The
addonsUrls
used bynetlify dev
are not handled by@netlify/config
. Netlify CLI would still need to fetch and compute those itself. In a follow-up PR, we could optimize this by computing those in@netlify/config
if we're concerned with fetching the addons twice when usingnetlify dev
.The priority order (from highest to lowest) is: site > account > addons. At the moment, the CLI uses account > addons > site, but this seemed to be wrong to me. Please let me know what you think.
The
config.build.environment
property returned by@netlify/config
used to contain bothnetlify.toml
environment variables and UI environment variables. Now it only contains the former one, sincesiteEnv
can now be used to retrieve the later one. Thenetlify env:list
andnetlify env:get
CLI commands is currently usingconfig.build.environment
. By switching to usingsiteEnv
instead, it will list a set of environment variables richer and closer to the actual set used in production builds (and now local builds too). However, it will now mix user-defined and mock environment variables. This might be an issue fornetlify env:list
? If so, we might need to iterate on this in a follow-up PR. Apart from those CLI commands and from builds, I do not think theconfig.build.environment
property returned by@netlify/config
is used.In order to mimic the
DEPLOY_ID
environment variable,@netlify/config
now accepts a--deploy-id
option, just like@netlify/build
does. This might not be useful at the moment though since Netlify CLI does not have a deploy ID to pass (please correct me if I'm wrong).This feature is fully tested, but we should release this as a major version to be on the safe side, and do additional testing both in the CLI and in the buildbot.
Many test snapshots are updated due to the additional
siteEnv
return value of@netlify/config
.