-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Keep bindable environment references intact
App Platform allows for bindable variables in environment variables (see https://docs.digitalocean.com/products/app-platform/how-to/use-environment-variables/#using-bindable-variables-within-environment-variables). They look like "normal" env-var references though and so our env-var-expansion process destroyed those references since generally the respective value isn't present on the action's env. This fixes that by not expanding the respective env vars if no value is present in the environment and the reference looks like a bindable reference.
- Loading branch information
1 parent
9484e02
commit 975c726
Showing
5 changed files
with
100 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package utils | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"strings" | ||
) | ||
|
||
// appWideVariables are the environment variables that are shared across all components. | ||
// See https://docs.digitalocean.com/products/app-platform/how-to/use-environment-variables/#app-wide-variables. | ||
var appWideVariables = map[string]struct{}{ | ||
"APP_DOMAIN": {}, | ||
"APP_URL": {}, | ||
"APP_NAME": {}, | ||
} | ||
|
||
// ExpandEnvRetainingBindables expands the environment variables in s, but it | ||
// keeps bindable variables intact. | ||
// Since bindable variables look like env vars, notation-wise, we just don't | ||
// expand them at all. | ||
func ExpandEnvRetainingBindables(s string) string { | ||
return os.Expand(s, func(name string) string { | ||
value := os.Getenv(name) | ||
if value == "" { | ||
if _, ok := appWideVariables[name]; ok || looksLikeBindable(name) { | ||
// If the environment variable is not set, keep the respective | ||
// reference intact. | ||
return fmt.Sprintf("${%s}", name) | ||
} | ||
} | ||
return value | ||
}) | ||
} | ||
|
||
// looksLikeBindable returns true if the key looks like a bindable variable. | ||
// Environment variables can't usually contain dots, so if they do, we're | ||
// fairly confident that it's a bindable variable. | ||
func looksLikeBindable(key string) bool { | ||
return strings.Contains(key, ".") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package utils | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestExpandEnvRetainingBindables(t *testing.T) { | ||
t.Setenv("FOO", "bar") | ||
t.Setenv("APP_URL", "baz") | ||
|
||
tests := []struct { | ||
name string | ||
in string | ||
out string | ||
}{{ | ||
name: "simple", | ||
in: "hello $FOO", | ||
out: "hello bar", | ||
}, { | ||
name: "bindable", | ||
in: "hello ${FOO.bar}", | ||
out: "hello ${FOO.bar}", | ||
}, { | ||
name: "global bindable, unset", | ||
in: "hello ${APP_DOMAIN}", | ||
out: "hello ${APP_DOMAIN}", | ||
}, { | ||
name: "global bindable, overridden in env", | ||
in: "hello ${APP_URL}", | ||
out: "hello baz", | ||
}} | ||
|
||
for _, test := range tests { | ||
t.Run(test.name, func(t *testing.T) { | ||
got := ExpandEnvRetainingBindables(test.in) | ||
require.Equal(t, test.out, got) | ||
}) | ||
} | ||
} |