Skip to content
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

Merged
merged 6 commits into from
Jan 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
637 changes: 428 additions & 209 deletions packages/build/package-lock.json

Large diffs are not rendered by default.

26 changes: 12 additions & 14 deletions packages/build/src/core/config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict'

const resolveConfig = require('@netlify/config')
const mapObj = require('map-obj')

const { getChildEnv } = require('../env/main')
const { addApiErrorHandlers } = require('../error/api')
Expand All @@ -24,6 +25,7 @@ const tLoadConfig = async function ({
envOpt,
debug,
mode,
offline,
deployId,
logs,
testOpts,
Expand All @@ -33,10 +35,10 @@ const tLoadConfig = async function ({
buildDir,
config: netlifyConfig,
context: contextA,
branch: branchA,
token: tokenA,
api,
siteInfo,
env,
} = await resolveFullConfig({
config,
defaultConfig,
Expand All @@ -48,26 +50,18 @@ const tLoadConfig = async function ({
baseRelDir,
token,
siteId,
deployId,
mode,
offline,
envOpt,
testOpts,
})
logConfigInfo({ logs, configPath, buildDir, netlifyConfig, context: contextA, debug })

const apiA = addApiErrorHandlers(api)
const [childEnv, { packageJson }] = await Promise.all([
getChildEnv({
netlifyConfig,
buildDir,
context: contextA,
branch: branchA,
siteInfo,
deployId,
envOpt,
mode,
}),
getPackageJson(buildDir),
])
const envValues = mapObj(env, (key, { value }) => [key, value])
const childEnv = getChildEnv({ envOpt, env: envValues })
const { packageJson } = await getPackageJson(buildDir)
return { netlifyConfig, configPath, buildDir, packageJson, childEnv, token: tokenA, api: apiA, siteInfo }
}

Expand All @@ -86,7 +80,9 @@ const resolveFullConfig = async function ({
baseRelDir,
token,
siteId,
deployId,
mode,
offline,
envOpt,
testOpts,
}) {
Expand All @@ -102,7 +98,9 @@ const resolveFullConfig = async function ({
baseRelDir,
token,
siteId,
deployId,
mode,
offline,
env: envOpt,
testOpts,
})
Expand Down
5 changes: 5 additions & 0 deletions packages/build/src/core/flags.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,11 @@ Default: true`,
describe: 'Statsd port',
hidden: true,
},
offline: {
boolean: true,
describe: `Do not send requests to the Netlify API to retrieve site settings.
Default: false`,
},
buffer: {
boolean: true,
describe: 'Buffer output instead of printing it',
Expand Down
2 changes: 2 additions & 0 deletions packages/build/src/core/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ const tExecBuild = async function ({
functionsDistDir,
dry,
mode,
offline,
deployId,
testOpts,
featureFlags,
Expand Down Expand Up @@ -154,6 +155,7 @@ const tExecBuild = async function ({
envOpt,
debug,
mode,
offline,
deployId,
logs,
testOpts,
Expand Down
1 change: 1 addition & 0 deletions packages/build/src/core/normalize_flags.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const getDefaultFlags = function ({ env: envOpt = {}, mode = REQUIRE_MODE }) {
nodePath: execPath,
token: combinedEnv.NETLIFY_AUTH_TOKEN,
mode: REQUIRE_MODE,
offline: false,
functionsDistDir: DEFAULT_FUNCTIONS_DIST,
deployId: combinedEnv.DEPLOY_ID,
debug: Boolean(combinedEnv.NETLIFY_BUILD_DEBUG),
Expand Down
106 changes: 3 additions & 103 deletions packages/build/src/env/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,12 @@ const { env } = require('process')
const filterObj = require('filter-obj')

const { getParentColorEnv } = require('../log/colors')
const { omit } = require('../utils/omit')

const { getGitEnv } = require('./git')

// Retrieve the environment variables passed to plugins and `build.command`
// When run locally, this tries to emulate the production environment.
const getChildEnv = async function ({ netlifyConfig, buildDir, branch, context, siteInfo, deployId, envOpt, mode }) {
const parentEnv = getParentEnv(envOpt)

if (mode === 'buildbot') {
return parentEnv
}

const defaultEnv = getDefaultEnv()
const configurableEnv = getConfigurableEnv()
const configEnv = getConfigEnv(netlifyConfig, deployId)
const forcedEnv = await getForcedEnv({ buildDir, branch, context, siteInfo })
return {
...defaultEnv,
...parentEnv,
...configurableEnv,
...configEnv,
...forcedEnv,
}
}

// Current process's environment variables, with some of them removed
const getParentEnv = function (envOpt) {
const parentEnv = { ...env, ...envOpt }
const getChildEnv = function ({ envOpt, env: allConfigEnv }) {
const parentColorEnv = getParentColorEnv()
const parentEnv = { ...env, ...allConfigEnv, ...envOpt, ...parentColorEnv }
return filterObj(parentEnv, shouldKeepEnv)
}

Expand All @@ -43,81 +20,4 @@ const shouldKeepEnv = function (key) {

const REMOVED_PARENT_ENV = new Set(['bugsnag_key'])

// Environment variables that can be unset by local ones or configuration ones
const getDefaultEnv = function () {
return {}
}

// Environment variables that can be unset by configuration ones but not local
const getConfigurableEnv = function () {
const parentColorEnv = getParentColorEnv()
return {
// Localization
LANG: 'en_US.UTF-8',
LANGUAGE: 'en_US:en',
LC_ALL: 'en_US.UTF-8',
// Disable telemetry of some tools
GATSBY_TELEMETRY_DISABLED: '1',
NEXT_TELEMETRY_DISABLED: '1',
// Colors
...parentColorEnv,
}
}

// Environment variables specified in UI settings, in `build.environment` or
// in CLI flags
const getConfigEnv = function ({ build: { environment } }, deployId) {
const deployIdEnv = deployId === undefined ? {} : { DEPLOY_ID: deployId }
const configEnv = omit(environment, READONLY_ENV)
return { ...deployIdEnv, ...configEnv }
}

// Those environment variables cannot be overriden by configuration
const READONLY_ENV = [
// Set in local builds
'BRANCH',
'CACHED_COMMIT_REF',
'COMMIT_REF',
'CONTEXT',
'HEAD',
'REPOSITORY_URL',
'URL',

// Purposely left unset in local builds
'NETLIFY',

// Not set in local builds because there is CI build/deploy, incoming hooks nor PR
'BUILD_ID',
'DEPLOY_ID',
'DEPLOY_PRIME_URL',
'DEPLOY_URL',
'INCOMING_HOOK_BODY',
'INCOMING_HOOK_TITLE',
'INCOMING_HOOK_URL',
'NETLIFY_BUILD_BASE',
'NETLIFY_BUILD_LIFECYCLE_TRIAL',
'NETLIFY_IMAGES_CDN_DOMAIN',
'PULL_REQUEST',
'REVIEW_ID',
]

// Environment variables that can be unset by neither local nor configuration
const getForcedEnv = async function ({
buildDir,
branch,
context,
siteInfo: { url, build_settings: { repo_url: REPOSITORY_URL } = {} },
}) {
const gitEnv = await getGitEnv(buildDir, branch)
return {
// Netlify Site information
...(url === undefined ? {} : { URL: url }),
...(REPOSITORY_URL === undefined ? {} : { REPOSITORY_URL }),
// Configuration file context
CONTEXT: context,
// Git-related environment variables
...gitEnv,
}
}

module.exports = { getChildEnv }
71 changes: 71 additions & 0 deletions packages/build/tests/core/snapshots/tests.js.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,74 @@ Generated by [AVA](https://ava.li).
},␊
"configPath": "/file/path",␊
"context": "production",␊
"env": {␊
"BRANCH": {␊
"sources": [␊
"general"␊
],␊
"value": "branch"␊
},␊
"CACHED_COMMIT_REF": {␊
"sources": [␊
"general"␊
],␊
"value": "HEXADECIMAL_ID"␊
},␊
"COMMIT_REF": {␊
"sources": [␊
"general"␊
],␊
"value": "HEXADECIMAL_ID"␊
},␊
"CONTEXT": {␊
"sources": [␊
"general"␊
],␊
"value": "production"␊
},␊
"GATSBY_TELEMETRY_DISABLED": {␊
"sources": [␊
"general"␊
],␊
"value": "1"␊
},␊
"HEAD": {␊
"sources": [␊
"general"␊
],␊
"value": "branch"␊
},␊
"LANG": {␊
"sources": [␊
"general"␊
],␊
"value": "en_US.UTF-8"␊
},␊
"LANGUAGE": {␊
"sources": [␊
"general"␊
],␊
"value": "en_US:en"␊
},␊
"LC_ALL": {␊
"sources": [␊
"general"␊
],␊
"value": "en_US.UTF-8"␊
},␊
"NEXT_TELEMETRY_DISABLED": {␊
"sources": [␊
"general"␊
],␊
"value": "1"␊
},␊
"PULL_REQUEST": {␊
"sources": [␊
"general"␊
],␊
"value": "false"␊
}␊
},␊
"siteInfo": {}␊
}`

Expand Down Expand Up @@ -585,6 +653,9 @@ Generated by [AVA](https://ava.li).
Default: Current Node.js binary [string]␊
--telemetry Enable telemetry.␊
Default: true [boolean]␊
--offline Do not send requests to the Netlify API to retrieve site␊
settings.␊
Default: false [boolean]␊
--buffer Buffer output instead of printing it [boolean]`

## --node-path is not used by core plugins
Expand Down
Binary file modified packages/build/tests/core/snapshots/tests.js.snap
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[build.environment]
NETLIFY = "test"
TEST = "test"

[[plugins]]
package = "./plugin"
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
'use strict'

const {
env: { LANG },
env: { BRANCH },
} = require('process')

module.exports = {
onPreBuild() {
console.log(LANG)
console.log(BRANCH)
},
}
11 changes: 0 additions & 11 deletions packages/build/tests/env/fixtures/build_readonly/plugin.js

This file was deleted.

3 changes: 3 additions & 0 deletions packages/build/tests/env/fixtures/context/netlify.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
[build.environment]
TEST = "test"

[[plugins]]
package = "./plugin"
5 changes: 5 additions & 0 deletions packages/build/tests/env/fixtures/deploy_id/netlify.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[build.environment]
TEST = "test"

[[plugins]]
package = "./plugin"
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
'use strict'

const {
env: { NETLIFY },
env: { DEPLOY_ID },
} = require('process')

module.exports = {
onPreBuild() {
console.log(NETLIFY)
console.log(DEPLOY_ID)
},
}
5 changes: 0 additions & 5 deletions packages/build/tests/env/fixtures/empty_string/index.js

This file was deleted.

5 changes: 0 additions & 5 deletions packages/build/tests/env/fixtures/empty_string/netlify.toml

This file was deleted.

Loading