Skip to content

Commit

Permalink
fix(core): fix default environment resolution
Browse files Browse the repository at this point in the history
This fixes a regression in the resolution flow for template strings in
`project.defaultEnvironment`.
thsig committed Sep 14, 2020
1 parent 42a1c9b commit 19e5f55
Showing 4 changed files with 80 additions and 24 deletions.
10 changes: 5 additions & 5 deletions core/src/config/project.ts
Original file line number Diff line number Diff line change
@@ -373,9 +373,7 @@ export const projectSchema = () =>
environments: environmentsSchema(),
})

export function getDefaultEnvironmentName(config: ProjectConfig): string {
const { defaultEnvironment } = config

export function getDefaultEnvironmentName(defaultEnvironment: string, config: ProjectConfig): string {
// TODO: get rid of the default environment config
const environments = (config.environments || []).length === 0 ? cloneDeep(defaultEnvironments) : config.environments

@@ -401,11 +399,13 @@ export function getDefaultEnvironmentName(config: ProjectConfig): string {
* @param config raw project configuration
*/
export function resolveProjectConfig({
defaultEnvironment,
config,
artifactsPath,
username,
secrets,
}: {
defaultEnvironment: string
config: ProjectConfig
artifactsPath: string
username: string
@@ -417,7 +417,6 @@ export function resolveProjectConfig({
const globalConfig = resolveTemplateStrings(
{
apiVersion: config.apiVersion,
defaultEnvironment: config.defaultEnvironment,
sources: config.sources,
varfile: config.varfile,
variables: config.variables,
@@ -432,6 +431,7 @@ export function resolveProjectConfig({
...config,
...globalConfig,
name,
defaultEnvironment,
environments: [],
},
schema: projectSchema(),
@@ -462,7 +462,7 @@ export function resolveProjectConfig({
providers,
}

config.defaultEnvironment = getDefaultEnvironmentName(config)
config.defaultEnvironment = getDefaultEnvironmentName(defaultEnvironment, config)

// // TODO: get rid of the default environment config
if (config.environments.length === 0) {
14 changes: 11 additions & 3 deletions core/src/garden.ts
Original file line number Diff line number Diff line change
@@ -302,11 +302,13 @@ export class Garden {
// Connect to the state storage
await ensureConnected()

const defaultEnvironment = resolveTemplateString(
getDefaultEnvironmentName(config),
const defaultEnvironmentName = resolveTemplateString(
config.defaultEnvironment,
new DefaultEnvironmentContext({ projectName, artifactsPath, username: _username })
) as string

const defaultEnvironment = getDefaultEnvironmentName(defaultEnvironmentName, config)

if (!environmentStr) {
environmentStr = defaultEnvironment
}
@@ -324,7 +326,13 @@ export class Garden {
clientAuthToken = enterpriseInitResult.clientAuthToken
}

config = resolveProjectConfig({ config, artifactsPath, username: _username, secrets })
config = resolveProjectConfig({
defaultEnvironment: defaultEnvironmentName,
config,
artifactsPath,
username: _username,
secrets,
})

const { sources: projectSources, path: projectRoot } = config

1 change: 1 addition & 0 deletions core/test/data/test-project-templated/garden.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
kind: Project
name: test-project-templated
defaultEnvironment: "${local.env.TEST_VARIABLE == 'banana' ? 'local' : 'local'}"
environments:
- name: local
providers:
79 changes: 63 additions & 16 deletions core/test/unit/src/config/project.ts
Original file line number Diff line number Diff line change
@@ -30,20 +30,29 @@ import { keyBy } from "lodash"

describe("resolveProjectConfig", () => {
it("should pass through a canonical project config", async () => {
const defaultEnvironment = "default"
const config: ProjectConfig = {
apiVersion: DEFAULT_API_VERSION,
kind: "Project",
name: "my-project",
path: "/tmp/foo",
defaultEnvironment: "default",
defaultEnvironment,
dotIgnoreFiles: defaultDotIgnoreFiles,
environments: [{ name: "default", defaultNamespace, variables: {} }],
outputs: [],
providers: [{ name: "some-provider", dependencies: [] }],
variables: {},
}

expect(resolveProjectConfig({ config, artifactsPath: "/tmp", username: "some-user", secrets: {} })).to.eql({
expect(
resolveProjectConfig({
defaultEnvironment,
config,
artifactsPath: "/tmp",
username: "some-user",
secrets: {},
})
).to.eql({
...config,
environments: [
{
@@ -58,20 +67,29 @@ describe("resolveProjectConfig", () => {
})

it("should inject a default environment if none is specified", async () => {
const defaultEnvironment = "local"
const config: ProjectConfig = {
apiVersion: DEFAULT_API_VERSION,
kind: "Project",
name: "my-project",
path: "/tmp/foo",
defaultEnvironment: "local",
defaultEnvironment,
dotIgnoreFiles: defaultDotIgnoreFiles,
environments: [],
outputs: [],
providers: [{ name: "some-provider", dependencies: [] }],
variables: {},
}

expect(resolveProjectConfig({ config, artifactsPath: "/tmp", username: "some-user", secrets: {} })).to.eql({
expect(
resolveProjectConfig({
defaultEnvironment,
config,
artifactsPath: "/tmp",
username: "some-user",
secrets: {},
})
).to.eql({
...config,
sources: [],
environments: defaultEnvironments,
@@ -81,13 +99,14 @@ describe("resolveProjectConfig", () => {

it("should resolve template strings on fields other than environment and provider configs", async () => {
const repositoryUrl = "git://github.com/foo/bar.git#boo"
const defaultEnvironment = "default"

const config: ProjectConfig = {
apiVersion: DEFAULT_API_VERSION,
kind: "Project",
name: "my-project",
path: "/tmp/foo",
defaultEnvironment: "default",
defaultEnvironment,
dotIgnoreFiles: defaultDotIgnoreFiles,
environments: [
{
@@ -115,7 +134,13 @@ describe("resolveProjectConfig", () => {
process.env.TEST_ENV_VAR = "foo"

expect(
resolveProjectConfig({ config, artifactsPath: "/tmp", username: "some-user", secrets: { foo: "banana" } })
resolveProjectConfig({
defaultEnvironment,
config,
artifactsPath: "/tmp",
username: "some-user",
secrets: { foo: "banana" },
})
).to.eql({
...config,
environments: [
@@ -146,12 +171,13 @@ describe("resolveProjectConfig", () => {
})

it("should pass through templated fields on provider configs", async () => {
const defaultEnvironment = "default"
const config: ProjectConfig = {
apiVersion: DEFAULT_API_VERSION,
kind: "Project",
name: "my-project",
path: "/tmp/foo",
defaultEnvironment: "default",
defaultEnvironment,
dotIgnoreFiles: defaultDotIgnoreFiles,
environments: [
{
@@ -179,7 +205,9 @@ describe("resolveProjectConfig", () => {
process.env.TEST_ENV_VAR_A = "foo"
process.env.TEST_ENV_VAR_B = "boo"

expect(resolveProjectConfig({ config, artifactsPath: "/tmp", username: "some-user", secrets: {} })).to.eql({
expect(
resolveProjectConfig({ defaultEnvironment, config, artifactsPath: "/tmp", username: "some-user", secrets: {} })
).to.eql({
...config,
environments: [
{
@@ -213,12 +241,13 @@ describe("resolveProjectConfig", () => {
})

it("should pass through templated fields on environment configs", async () => {
const defaultEnvironment = "default"
const config: ProjectConfig = {
apiVersion: DEFAULT_API_VERSION,
kind: "Project",
name: "my-project",
path: "/tmp/foo",
defaultEnvironment: "default",
defaultEnvironment,
dotIgnoreFiles: defaultDotIgnoreFiles,
environments: [
{
@@ -233,26 +262,35 @@ describe("resolveProjectConfig", () => {
variables: {},
}

const result = resolveProjectConfig({ config, artifactsPath: "/tmp", username: "some-user", secrets: {} })
const result = resolveProjectConfig({
defaultEnvironment,
config,
artifactsPath: "/tmp",
username: "some-user",
secrets: {},
})

expect(result.environments[0].variables).to.eql(config.environments[0].variables)
})

it("should set defaultEnvironment to first environment if not configured", async () => {
const defaultEnvironment = ""
const config: ProjectConfig = {
apiVersion: DEFAULT_API_VERSION,
kind: "Project",
name: "my-project",
path: "/tmp/foo",
defaultEnvironment: "",
defaultEnvironment,
dotIgnoreFiles: defaultDotIgnoreFiles,
environments: [],
outputs: [],
providers: [{ name: "some-provider", dependencies: [] }],
variables: {},
}

expect(resolveProjectConfig({ config, artifactsPath: "/tmp", username: "some-user", secrets: {} })).to.eql({
expect(
resolveProjectConfig({ defaultEnvironment, config, artifactsPath: "/tmp", username: "some-user", secrets: {} })
).to.eql({
...config,
defaultEnvironment: "local",
environments: defaultEnvironments,
@@ -262,20 +300,23 @@ describe("resolveProjectConfig", () => {
})

it("should populate default values in the schema", async () => {
const defaultEnvironment = ""
const config: ProjectConfig = {
apiVersion: DEFAULT_API_VERSION,
kind: "Project",
name: "my-project",
path: "/tmp/foo",
defaultEnvironment: "",
defaultEnvironment,
dotIgnoreFiles: defaultDotIgnoreFiles,
environments: [],
outputs: [],
providers: [{ name: "some-provider", dependencies: [] }],
variables: {},
}

expect(resolveProjectConfig({ config, artifactsPath: "/tmp", username: "some-user", secrets: {} })).to.eql({
expect(
resolveProjectConfig({ defaultEnvironment, config, artifactsPath: "/tmp", username: "some-user", secrets: {} })
).to.eql({
...config,
defaultEnvironment: "local",
environments: defaultEnvironments,
@@ -285,6 +326,7 @@ describe("resolveProjectConfig", () => {
})

it("should include providers in correct precedence order from all possible config keys", async () => {
const defaultEnvironment = "default"
const config: ProjectConfig = {
apiVersion: DEFAULT_API_VERSION,
kind: "Project",
@@ -317,7 +359,9 @@ describe("resolveProjectConfig", () => {
variables: {},
}

expect(resolveProjectConfig({ config, artifactsPath: "/tmp", username: "some-user", secrets: {} })).to.eql({
expect(
resolveProjectConfig({ defaultEnvironment, config, artifactsPath: "/tmp", username: "some-user", secrets: {} })
).to.eql({
...config,
environments: [
{
@@ -350,6 +394,7 @@ describe("resolveProjectConfig", () => {
})

it("should convert old-style environment/provider config to the new canonical form", async () => {
const defaultEnvironment = "default"
const config: ProjectConfig = {
apiVersion: DEFAULT_API_VERSION,
kind: "Project",
@@ -382,7 +427,9 @@ describe("resolveProjectConfig", () => {
},
}

expect(resolveProjectConfig({ config, artifactsPath: "/tmp", username: "some-user", secrets: {} })).to.eql({
expect(
resolveProjectConfig({ defaultEnvironment, config, artifactsPath: "/tmp", username: "some-user", secrets: {} })
).to.eql({
...config,
environments: [
{

0 comments on commit 19e5f55

Please sign in to comment.