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

Strict Environment Handling #4449

Merged
merged 17 commits into from
Apr 6, 2023
Merged
Show file tree
Hide file tree
Changes from 8 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
69 changes: 69 additions & 0 deletions cli/integration_tests/strict_env_vars/global_passthrough_env.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
Setup
$ . ${TESTDIR}/../setup.sh
$ . ${TESTDIR}/setup.sh $(pwd) global_passthrough_env

Strict + []
$ ${TURBO} build --env=strict -vv --filter=nothing > /dev/null
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: Global turbo version: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: No local turbo binary found at: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: No local turbo binary found at: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: Repository Root: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: Running command as global turbo (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::cli: pkg_inference_root set to "" (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: Found go binary at "[\-\w\/]+" (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: build tag: (go|rust) (re)
[-0-9:.TWZ+]+ \[INFO] turbo: skipping turbod since we appear to be in a non-interactive context (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: global hash env vars: vars=\["VERCEL_ANALYTICS_ID"] (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: new global hash: value=ef18881222fd6a72 (re)
[-0-9:.TWZ+]+ |[DEBUG] turbo: local cache folder: path="" (re)
No tasks were executed as part of this run.

Infer + []
$ ${TURBO} build --env=infer -vv --filter=nothing > /dev/null
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: Global turbo version: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: No local turbo binary found at: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: No local turbo binary found at: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: Repository Root: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: Running command as global turbo (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::cli: pkg_inference_root set to "" (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: Found go binary at "[\-\w\/]+" (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: build tag: (go|rust) (re)
[-0-9:.TWZ+]+ \[INFO] turbo: skipping turbod since we appear to be in a non-interactive context (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: global hash env vars: vars=\["VERCEL_ANALYTICS_ID"] (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: new global hash: value=9cda29cc8ed880a1 (re)
[-0-9:.TWZ+]+ |[DEBUG] turbo: local cache folder: path="" (re)
No tasks were executed as part of this run.

Loose + []
$ ${TURBO} build --env=loose -vv --filter=nothing > /dev/null
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: Global turbo version: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: No local turbo binary found at: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: No local turbo binary found at: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: Repository Root: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: Running command as global turbo (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::cli: pkg_inference_root set to "" (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: Found go binary at "[\-\w\/]+" (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: build tag: (go|rust) (re)
[-0-9:.TWZ+]+ \[INFO] turbo: skipping turbod since we appear to be in a non-interactive context (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: global hash env vars: vars=\["VERCEL_ANALYTICS_ID"] (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: new global hash: value=b7e2e8ed3383c982 (re)
[-0-9:.TWZ+]+ |[DEBUG] turbo: local cache folder: path="" (re)
No tasks were executed as part of this run.

Loose + ["BONUS_VAR"]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has the same hash as the above one, since loose explicitly means "don't pay attention to it."

$ rm turbo.json
$ mv turbo_loose.json turbo.json
$ ${TURBO} build --env=loose -vv --filter=nothing > /dev/null
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: Global turbo version: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: No local turbo binary found at: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: No local turbo binary found at: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: Repository Root: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: Running command as global turbo (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::cli: pkg_inference_root set to "" (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: Found go binary at "[\-\w\/]+" (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: build tag: (go|rust) (re)
[-0-9:.TWZ+]+ \[INFO] turbo: skipping turbod since we appear to be in a non-interactive context (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: global hash env vars: vars=\["VERCEL_ANALYTICS_ID"] (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: new global hash: value=b7e2e8ed3383c982 (re)
[-0-9:.TWZ+]+ |[DEBUG] turbo: local cache folder: path="" (re)
No tasks were executed as part of this run.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules/
.turbo
.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "my-app",
"scripts": {
"build": "echo 'building'"
},
"dependencies": {
"util": "*"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "monorepo",
"workspaces": [
"apps/**",
"packages/**"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "util",
"scripts": {
"build": "echo 'building'"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"build": {
"outputs": ["dist/**"]
}
},
"globalPassthroughEnv": []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"build": {
"outputs": ["dist/**"]
}
},
"globalPassthroughEnv": ["BONUS_VAR"]
}
3 changes: 3 additions & 0 deletions cli/integration_tests/strict_env_vars/monorepo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules/
.turbo
.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "my-app",
"scripts": {
"build": "echo 'building'"
},
"dependencies": {
"util": "*"
}
}
7 changes: 7 additions & 0 deletions cli/integration_tests/strict_env_vars/monorepo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "monorepo",
"workspaces": [
"apps/**",
"packages/**"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "util",
"scripts": {
"build": "echo 'building'"
}
}
8 changes: 8 additions & 0 deletions cli/integration_tests/strict_env_vars/monorepo/turbo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"build": {
"outputs": ["dist/**"]
}
}
}
8 changes: 8 additions & 0 deletions cli/integration_tests/strict_env_vars/setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash

SCRIPT_DIR=$(dirname ${BASH_SOURCE[0]})
TARGET_DIR=$1
FIXTURE=$2

cp -a ${SCRIPT_DIR}/$2/. ${TARGET_DIR}/
${SCRIPT_DIR}/../setup_git.sh ${TARGET_DIR}
67 changes: 67 additions & 0 deletions cli/integration_tests/strict_env_vars/strict_env_vars.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
Setup
$ . ${TESTDIR}/../setup.sh
$ . ${TESTDIR}/setup.sh $(pwd) monorepo

Strict with no passthroughEnv opts you into the new hashing behavior.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an optional decision. We could make it use the old hashing behavior here. ("You specified a nonsense combination of options.")

If we do that, though, we need to move the EnvMode flag into each individual task hash.

$ ${TURBO} build --env=strict -vv --filter=nothing > /dev/null
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: Global turbo version: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: No local turbo binary found at: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: No local turbo binary found at: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: Repository Root: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: Running command as global turbo (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::cli: pkg_inference_root set to "" (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: Found go binary at "[\-\w\/]+" (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: build tag: (go|rust) (re)
[-0-9:.TWZ+]+ \[INFO] turbo: skipping turbod since we appear to be in a non-interactive context (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: global hash env vars: vars=\["VERCEL_ANALYTICS_ID"] (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: new global hash: value=ef18881222fd6a72 (re)
[-0-9:.TWZ+]+ |[DEBUG] turbo: local cache folder: path="" (re)
No tasks were executed as part of this run.

Loose with no passthroughEnv also opts you into the new hashing behavior.
$ ${TURBO} build --env=loose -vv --filter=nothing > /dev/null
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: Global turbo version: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: No local turbo binary found at: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: No local turbo binary found at: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: Repository Root: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: Running command as global turbo (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::cli: pkg_inference_root set to "" (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: Found go binary at "[\-\w\/]+" (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: build tag: (go|rust) (re)
[-0-9:.TWZ+]+ \[INFO] turbo: skipping turbod since we appear to be in a non-interactive context (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: global hash env vars: vars=\["VERCEL_ANALYTICS_ID"] (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: new global hash: value=b7e2e8ed3383c982 (re)
[-0-9:.TWZ+]+ |[DEBUG] turbo: local cache folder: path="" (re)
No tasks were executed as part of this run.

Infer with no passthroughEnv keeps you on the old hashing
$ ${TURBO} build --env=infer -vv --filter=nothing > /dev/null
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: Global turbo version: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: No local turbo binary found at: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: No local turbo binary found at: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: Repository Root: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: Running command as global turbo (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::cli: pkg_inference_root set to "" (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: Found go binary at "[\-\w\/]+" (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: build tag: (go|rust) (re)
[-0-9:.TWZ+]+ \[INFO] turbo: skipping turbod since we appear to be in a non-interactive context (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: global hash env vars: vars=\["VERCEL_ANALYTICS_ID"] (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: global hash: value=f71f6eda617fc880 (re)
[-0-9:.TWZ+]+ |[DEBUG] turbo: local cache folder: path="" (re)
No tasks were executed as part of this run.

Weird arg for specifying infer, same old hashing
$ ${TURBO} build --env -vv --filter=nothing > /dev/null
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: Global turbo version: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: No local turbo binary found at: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: No local turbo binary found at: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: Repository Root: .* (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::shim: Running command as global turbo (re)
[-0-9:.TWZ+]+ \[DEBUG] turborepo_lib::cli: pkg_inference_root set to "" (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: Found go binary at "[\-\w\/]+" (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: build tag: (go|rust) (re)
[-0-9:.TWZ+]+ \[INFO] turbo: skipping turbod since we appear to be in a non-interactive context (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: global hash env vars: vars=\["VERCEL_ANALYTICS_ID"] (re)
[-0-9:.TWZ+]+ \[DEBUG] turbo: global hash: value=f71f6eda617fc880 (re)
[-0-9:.TWZ+]+ |[DEBUG] turbo: local cache folder: path="" (re)
No tasks were executed as part of this run.
16 changes: 11 additions & 5 deletions cli/internal/env/env.go
mehulkar marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ func (evm EnvironmentVariableMap) Merge(another EnvironmentVariableMap) {
}
}

// Add creates one new environment variable.
func (evm EnvironmentVariableMap) Add(key string, value string) {
evm[key] = value
}

// Names returns a sorted list of env var names for the EnvironmentVariableMap
func (evm EnvironmentVariableMap) Names() []string {
names := []string{}
Expand Down Expand Up @@ -85,7 +90,8 @@ func (evm EnvironmentVariableMap) ToHashable() EnvironmentVariablePairs {
})
}

func getEnvMap() EnvironmentVariableMap {
// GetEnvMap returns a map of env vars and their values from os.Environ
func GetEnvMap() EnvironmentVariableMap {
envMap := make(map[string]string)
for _, envVar := range os.Environ() {
if i := strings.Index(envVar, "="); i >= 0 {
Expand All @@ -96,8 +102,8 @@ func getEnvMap() EnvironmentVariableMap {
return envMap
}

// fromKeys returns a map of env vars and their values from a given set of env var names
func fromKeys(all EnvironmentVariableMap, keys []string) EnvironmentVariableMap {
// FromKeys returns a map of env vars and their values from a given set of env var names
func FromKeys(all EnvironmentVariableMap, keys []string) EnvironmentVariableMap {
output := EnvironmentVariableMap{}
for _, key := range keys {
output[key] = all[key]
Expand Down Expand Up @@ -138,14 +144,14 @@ func fromMatching(all EnvironmentVariableMap, keyMatchers []string, shouldExclud

// GetHashableEnvVars returns all sorted key=value env var pairs for both frameworks and from envKeys
func GetHashableEnvVars(keys []string, matchers []string, envVarContainingExcludePrefix string) (DetailedMap, error) {
all := getEnvMap()
all := GetEnvMap()

detailedMap := DetailedMap{
All: EnvironmentVariableMap{},
BySource: BySource{},
}

detailedMap.BySource.Explicit = fromKeys(all, keys)
detailedMap.BySource.Explicit = FromKeys(all, keys)
detailedMap.All.Merge(detailedMap.BySource.Explicit)

// Create an excluder function to pass to matcher.
Expand Down
2 changes: 2 additions & 0 deletions cli/internal/fs/testdata/correct/turbo.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
{
"pipeline": {
"build": {
"passthroughEnv": ["GITHUB_TOKEN"],
// mocked test comment
"dependsOn": [
// mocked test comment
Expand Down Expand Up @@ -40,6 +41,7 @@
},
"globalDependencies": ["some-file", "../another-dir/**", "$GLOBAL_ENV_VAR"],
"globlaEnv": ["SOME_VAR", "ANOTHER_VAR"],
"globalPassthroughEnv": ["AWS_SECRET_KEY"],
"remoteCache": {
"teamId": "team_id",
"signature": true
Expand Down
Loading