@catladder/pipeline 1.54.0 → 1.55.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/build/index.d.ts +2 -1
  2. package/dist/build/types.d.ts +3 -0
  3. package/dist/bundles/catladder-gitlab/index.js +3 -3
  4. package/dist/constants.js +1 -1
  5. package/dist/context/getEnvConfig.d.ts +2 -0
  6. package/dist/context/getEnvConfig.js +26 -0
  7. package/dist/context/getEnvType.d.ts +4 -0
  8. package/dist/context/getEnvType.js +18 -0
  9. package/dist/context/getEnvironment.d.ts +2 -4
  10. package/dist/context/getEnvironment.js +15 -195
  11. package/dist/context/getEnvironmentContext.d.ts +4 -0
  12. package/dist/context/getEnvironmentContext.js +36 -0
  13. package/dist/context/getEnvironmentVariables.d.ts +10 -0
  14. package/dist/context/getEnvironmentVariables.js +322 -0
  15. package/dist/context/index.d.ts +1 -0
  16. package/dist/context/index.js +12 -16
  17. package/dist/deploy/cloudRun/deployJob.js +61 -24
  18. package/dist/deploy/cloudRun/index.d.ts +1 -6
  19. package/dist/deploy/cloudRun/index.js +51 -31
  20. package/dist/deploy/index.d.ts +7 -20
  21. package/dist/deploy/index.js +8 -21
  22. package/dist/deploy/kubernetes/additionalSecretKeys.d.ts +3 -3
  23. package/dist/deploy/kubernetes/additionalSecretKeys.js +5 -5
  24. package/dist/deploy/kubernetes/index.js +2 -2
  25. package/dist/deploy/types/googleCloudRun.d.ts +27 -23
  26. package/dist/deploy/types/index.d.ts +2 -4
  27. package/dist/tsconfig.tsbuildinfo +1 -1
  28. package/dist/types/config.d.ts +1 -0
  29. package/dist/types/environmentContext.d.ts +22 -0
  30. package/dist/types/environmentContext.js +3 -0
  31. package/package.json +1 -1
  32. package/src/build/index.ts +4 -1
  33. package/src/build/types.ts +6 -0
  34. package/src/context/getEnvConfig.ts +21 -0
  35. package/src/context/getEnvType.ts +17 -0
  36. package/src/context/getEnvironment.ts +16 -164
  37. package/src/context/getEnvironmentContext.ts +57 -0
  38. package/src/context/getEnvironmentVariables.ts +152 -0
  39. package/src/context/index.ts +17 -14
  40. package/src/deploy/cloudRun/deployJob.ts +75 -24
  41. package/src/deploy/cloudRun/index.ts +12 -23
  42. package/src/deploy/index.ts +11 -23
  43. package/src/deploy/kubernetes/additionalSecretKeys.ts +7 -7
  44. package/src/deploy/kubernetes/index.ts +2 -2
  45. package/src/deploy/types/googleCloudRun.ts +25 -23
  46. package/src/types/config.ts +2 -0
  47. package/src/types/environmentContext.ts +26 -0
@@ -1,187 +1,39 @@
1
- import { isObject, merge } from "lodash";
2
- import type { EnvVarContext } from "../deploy";
3
- import { DEPLOY_TYPES } from "../deploy";
4
- import type { Config, DevLocalEnvConfig } from "../types/config";
5
- import { isKnowEnvType } from "../types/config";
6
- import type { CommitInfo, Context, Environment } from "../types/context";
7
- import { mergeWithMergingArrays } from "../utils";
8
- import {
9
- resolveReferences,
10
- translateLegacyFromComponents,
11
- } from "./resolveReferences";
1
+ import type { Config } from "../types/config";
2
+
3
+ import type { CommitInfo, Environment } from "../types/context";
4
+ import { getEnvironmentContext } from "./getEnvironmentContext";
5
+ import { getEnvironmentVariables } from "./getEnvironmentVariables";
12
6
 
13
7
  export const getEnvironment = async (
14
8
  config: Config,
15
9
  componentName: string,
16
10
  env: string,
17
- commitInfo?: CommitInfo,
18
- alreadyVisited: Record<string, Record<string, boolean>> = {} // to prevent endless loop
11
+ commitInfo?: CommitInfo
19
12
  ): Promise<Environment> => {
20
- const envConfig = getEnvConfig(config, componentName, env);
21
- // env type: if its set manually, use that, otherwise use the known env types
22
- const envType = envConfig?.type ?? (isKnowEnvType(env) ? env : null);
23
-
24
- if (!envType) {
25
- throw new Error(
26
- "Missing type in environment " + env + " in component " + componentName
27
- );
28
- }
29
-
30
- const basePredefinedVariables = {
31
- ENV_SHORT: env,
32
- APP_DIR: envConfig.dir,
33
- ENV_TYPE: envType,
34
- };
13
+ const { envVars, secretEnvVarKeys, host, url } =
14
+ await getEnvironmentVariables(config, componentName, env, commitInfo);
35
15
 
36
- const gitlabEnvironmentName =
37
- envType === "review" && commitInfo
38
- ? `${env}/${commitInfo.refName}/${componentName}`
39
- : `${env}/${componentName}`;
40
-
41
- const environmentSlug =
42
- envType === "review" && commitInfo
43
- ? `${env}-${commitInfo.reviewSlug}-${componentName}`
44
- : `${env}-${componentName}`;
45
-
46
- let predefinedVariables: Record<string, string>;
47
- let host: string;
48
- let url: string;
49
- const fullName = `${config.customerName}-${config.appName}-${environmentSlug}`;
50
-
51
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
52
- const envVarContext: EnvVarContext<any> = {
53
- deployConfig: envConfig.deploy,
54
- fullName,
55
- envType,
56
- commitInfo,
57
- componentName,
16
+ const envContext = getEnvironmentContext(
17
+ config,
58
18
  env,
59
- fullConfig: config,
60
- };
61
-
62
- if (envType === "local") {
63
- const devLocalConfig: DevLocalEnvConfig = envConfig;
64
- const port = devLocalConfig.port ?? 3000;
65
- host = "localhost:" + port;
66
- url = "http://" + host;
67
- predefinedVariables = {
68
- ENV_SHORT: "local",
69
- ROOT_URL: url,
70
- PORT: port.toString(),
71
- };
72
- } else {
73
- const additionalEnvVars = envConfig.deploy
74
- ? DEPLOY_TYPES[envConfig.deploy.type].getAdditionalEnvVars(envVarContext)
75
- : {};
76
-
77
- host =
78
- envConfig?.host ??
79
- additionalEnvVars.HOST_CANONICAL ??
80
- "unknown-host.example.com";
81
- url = `https://${host}`;
82
-
83
- predefinedVariables = {
84
- ...basePredefinedVariables,
85
- HOST: host,
86
- ROOT_URL: url,
87
- ...additionalEnvVars,
88
- };
89
- }
90
- const publicEnvVarsRaw = envConfig.vars?.public ?? {};
91
-
92
- const additionalSecretKeys = envConfig.deploy
93
- ? DEPLOY_TYPES[envConfig.deploy.type].additionalSecretKeys(envVarContext)
94
- : [];
95
-
96
- const secretEnvVarKeys = [
97
- ...(envConfig.vars?.secret ?? []),
98
- ...additionalSecretKeys,
99
- ];
100
- const secretEnvVars = Object.fromEntries(
101
- secretEnvVarKeys.map((key) => [
102
- key,
103
- `$${getSecretVarName(env, componentName, key)}`,
104
- ])
105
- );
106
-
107
- // this is deprecated, we now support: $componentname:FOO
108
- const legacyFromComponents = envConfig.vars?.fromComponents ?? {};
109
- const publicEnvVarsRawWithLegasyFromComponents = merge(
110
- {},
111
- translateLegacyFromComponents(legacyFromComponents),
112
- publicEnvVarsRaw
113
- );
114
-
115
- const publicEnvVarsRawSanitized = Object.fromEntries(
116
- Object.entries(publicEnvVarsRawWithLegasyFromComponents).map(
117
- ([key, value]) => [
118
- key,
119
- isObject(value) ? JSON.stringify(value) : `${value}`,
120
- ]
121
- )
19
+ componentName,
20
+ commitInfo
122
21
  );
123
22
 
124
- const envVarsRaw = addIndexVar({
125
- ...predefinedVariables,
126
- ...secretEnvVars,
127
- ...publicEnvVarsRawSanitized,
128
- });
23
+ const envType = envContext.envType;
129
24
 
130
- const envVars = await resolveReferences(
131
- envVarsRaw,
132
- async (componentName, variableName, alreadyVisited) => {
133
- const { envVars } = await getEnvironment(
134
- config,
135
- componentName,
136
- env,
137
- commitInfo,
138
- alreadyVisited
139
- );
140
- return envVars[variableName];
141
- },
142
- alreadyVisited
143
- );
144
25
  return {
145
26
  envType,
146
27
  host,
147
28
  url,
148
29
  gitlabEnvironment: {
149
- name: gitlabEnvironmentName,
30
+ name: envContext.gitlabEnvironmentName,
150
31
  url,
151
32
  },
152
- fullName,
153
- slug: environmentSlug,
33
+ fullName: envContext.fullName,
34
+ slug: envContext.environmentSlug,
154
35
  shortName: env,
155
36
  envVars,
156
37
  secretEnvVarKeys,
157
38
  };
158
39
  };
159
-
160
- const sanitizeForEnVar = (s: string) => s.replace(/-/g, "_");
161
- export const getSecretVarName = (
162
- env: string,
163
- componentName: string,
164
- key: string
165
- ) => `CL_${sanitizeForEnVar(env)}_${sanitizeForEnVar(componentName)}_${key}`; // remove dash from component name
166
-
167
- const addIndexVar = (vars: Record<string, unknown>) => ({
168
- ...vars,
169
- _ALL_ENV_VAR_KEYS: JSON.stringify(Object.keys(vars)),
170
- });
171
-
172
- export const getSecretVarNameForContext = (context: Context, key: string) =>
173
- getSecretVarName(context.environment.shortName, context.componentName, key);
174
-
175
- const getEnvConfig = (config: Config, componentName: string, env: string) => {
176
- const defaultConfig = config.components[componentName];
177
- if (!defaultConfig) {
178
- throw new Error("unknown component " + componentName);
179
- }
180
-
181
- const envCustomizations = defaultConfig.env?.[env] ?? {};
182
- if (envCustomizations === false) {
183
- throw new Error("env is disabled: " + env);
184
- }
185
-
186
- return mergeWithMergingArrays(defaultConfig, envCustomizations);
187
- };
@@ -0,0 +1,57 @@
1
+ import type { Config, EnvConfigWithComponent } from "../types/config";
2
+
3
+ import type { CommitInfo } from "../types/context";
4
+ import type { EnvironmentContext } from "../types/environmentContext";
5
+ import { getEnvConfig } from "./getEnvConfig";
6
+ import { getEnvType } from "./getEnvType";
7
+
8
+ const getEnvironmentSlug = (
9
+ envConfig: EnvConfigWithComponent,
10
+ env: string,
11
+ componentName: string,
12
+ commitInfo?: CommitInfo
13
+ ) => {
14
+ const envType = getEnvType(env, envConfig);
15
+
16
+ return envType === "review" && commitInfo
17
+ ? `${env}-${commitInfo.reviewSlug}-${componentName}`
18
+ : `${env}-${componentName}`;
19
+ };
20
+
21
+ export const getEnvironmentContext = (
22
+ config: Config,
23
+ env: string,
24
+ componentName: string,
25
+ commitInfo?: CommitInfo
26
+ ): EnvironmentContext<any, any> => {
27
+ const envConfigRaw = getEnvConfig(config, componentName, env);
28
+ const envType = getEnvType(env, envConfigRaw);
29
+
30
+ const environmentSlug = getEnvironmentSlug(
31
+ envConfigRaw,
32
+ env,
33
+ componentName,
34
+ commitInfo
35
+ );
36
+
37
+ const gitlabEnvironmentName =
38
+ envType === "review" && commitInfo
39
+ ? `${env}/${commitInfo.refName}/${componentName}`
40
+ : `${env}/${componentName}`;
41
+
42
+ const fullName = `${config.customerName}-${config.appName}-${environmentSlug}`;
43
+
44
+ return {
45
+ envConfigRaw,
46
+ deployConfigRaw: envConfigRaw.deploy,
47
+ buildConfigRaw: envConfigRaw.build,
48
+ environmentSlug,
49
+ gitlabEnvironmentName,
50
+ fullName,
51
+ envType,
52
+ commitInfo,
53
+ componentName,
54
+ env,
55
+ fullConfig: config,
56
+ };
57
+ };
@@ -0,0 +1,152 @@
1
+ import { isObject, merge } from "lodash";
2
+ import { DEPLOY_TYPES } from "../deploy";
3
+ import type { CommitInfo, Context } from "../types";
4
+ import type { Config, DevLocalEnvConfig } from "../types/config";
5
+
6
+ import { getEnvironmentContext } from "./getEnvironmentContext";
7
+ import {
8
+ resolveReferences,
9
+ translateLegacyFromComponents,
10
+ } from "./resolveReferences";
11
+
12
+ export const getEnvironmentVariables = async (
13
+ config: Config,
14
+ componentName: string,
15
+ env: string,
16
+ commitInfo?: CommitInfo,
17
+ alreadyVisited: Record<string, Record<string, boolean>> = {} // to prevent endless loop
18
+ ): Promise<{
19
+ envVars: Record<string, string>;
20
+ secretEnvVarKeys: string[];
21
+ host: string;
22
+ url: string;
23
+ }> => {
24
+ const environmentContext = getEnvironmentContext(
25
+ config,
26
+ env,
27
+ componentName,
28
+ commitInfo
29
+ );
30
+
31
+ const { envConfigRaw, deployConfigRaw, envType } = environmentContext;
32
+
33
+ const basePredefinedVariables = {
34
+ ENV_SHORT: env,
35
+ APP_DIR: envConfigRaw.dir,
36
+ ENV_TYPE: envType,
37
+ };
38
+
39
+ let predefinedVariables: Record<string, string>;
40
+ let host: string;
41
+ let url: string;
42
+
43
+ if (envType === "local") {
44
+ const devLocalConfig: DevLocalEnvConfig = envConfigRaw;
45
+ const port = devLocalConfig.port ?? 3000;
46
+ host = "localhost:" + port;
47
+ url = "http://" + host;
48
+ predefinedVariables = {
49
+ ENV_SHORT: "local",
50
+ ROOT_URL: url,
51
+ PORT: port.toString(),
52
+ };
53
+ } else {
54
+ const additionalEnvVars = deployConfigRaw
55
+ ? DEPLOY_TYPES[deployConfigRaw.type].getAdditionalEnvVars(
56
+ environmentContext
57
+ )
58
+ : {};
59
+
60
+ host =
61
+ envConfigRaw?.host ??
62
+ additionalEnvVars.HOST_CANONICAL ??
63
+ "unknown-host.example.com";
64
+ url = `https://${host}`;
65
+
66
+ predefinedVariables = {
67
+ ...basePredefinedVariables,
68
+ HOST: host,
69
+ ROOT_URL: url,
70
+ ...additionalEnvVars,
71
+ };
72
+ }
73
+ const publicEnvVarsRaw = envConfigRaw.vars?.public ?? {};
74
+
75
+ const additionalSecretKeys = deployConfigRaw
76
+ ? DEPLOY_TYPES[deployConfigRaw.type].additionalSecretKeys(
77
+ environmentContext
78
+ )
79
+ : [];
80
+
81
+ const secretEnvVarKeys = [
82
+ ...(envConfigRaw.vars?.secret ?? []),
83
+ ...additionalSecretKeys,
84
+ ];
85
+ const secretEnvVars = Object.fromEntries(
86
+ secretEnvVarKeys.map((key) => [
87
+ key,
88
+ `$${getSecretVarName(env, componentName, key)}`,
89
+ ])
90
+ );
91
+
92
+ // this is deprecated, we now support: $componentname:FOO
93
+ const legacyFromComponents = envConfigRaw.vars?.fromComponents ?? {};
94
+ const publicEnvVarsRawWithLegasyFromComponents = merge(
95
+ {},
96
+ translateLegacyFromComponents(legacyFromComponents),
97
+ publicEnvVarsRaw
98
+ );
99
+
100
+ const publicEnvVarsRawSanitized = Object.fromEntries(
101
+ Object.entries(publicEnvVarsRawWithLegasyFromComponents).map(
102
+ ([key, value]) => [
103
+ key,
104
+ isObject(value) ? JSON.stringify(value) : `${value}`,
105
+ ]
106
+ )
107
+ );
108
+
109
+ const envVarsRaw = addIndexVar({
110
+ ...predefinedVariables,
111
+ ...secretEnvVars,
112
+ ...publicEnvVarsRawSanitized,
113
+ });
114
+
115
+ const envVars = await resolveReferences(
116
+ envVarsRaw,
117
+ async (otherComponentName, variableName, alreadyVisited) => {
118
+ const { envVars: otherEnvVars } = await getEnvironmentVariables(
119
+ config,
120
+ otherComponentName,
121
+ env,
122
+ commitInfo,
123
+ alreadyVisited
124
+ );
125
+ return otherEnvVars[variableName];
126
+ },
127
+ alreadyVisited
128
+ );
129
+
130
+ return {
131
+ envVars,
132
+ secretEnvVarKeys,
133
+ host,
134
+ url,
135
+ };
136
+ };
137
+
138
+ const sanitizeForEnVar = (s: string) => s.replace(/-/g, "_");
139
+
140
+ export const getSecretVarName = (
141
+ env: string,
142
+ componentName: string,
143
+ key: string
144
+ ) => `CL_${sanitizeForEnVar(env)}_${sanitizeForEnVar(componentName)}_${key}`; // remove dash from component name
145
+
146
+ const addIndexVar = (vars: Record<string, unknown>) => ({
147
+ ...vars,
148
+ _ALL_ENV_VAR_KEYS: JSON.stringify(Object.keys(vars)),
149
+ });
150
+
151
+ export const getSecretVarNameForContext = (context: Context, key: string) =>
152
+ getSecretVarName(context.environment.shortName, context.componentName, key);
@@ -1,13 +1,15 @@
1
1
  import { BUILD_TYPES } from "../build";
2
- import type { BuildConfig } from "../build/types";
2
+ import type { BuildConfig, BuildConfigType } from "../build/types";
3
3
  import { DEPLOY_TYPES } from "../deploy";
4
- import type { DeployConfig } from "../deploy/types";
4
+ import type { DeployConfig, DeployConfigType } from "../deploy/types";
5
5
  import type { Config } from "../types/config";
6
6
  import type { CommitInfo, Context, PackageManagerInfo } from "../types/context";
7
7
  import { mergeWithMergingArrays } from "../utils";
8
8
  import { getEnvironment } from "./getEnvironment";
9
+ import { getEnvironmentContext } from "./getEnvironmentContext";
9
10
 
10
11
  export * from "./getEnvironment";
12
+ export * from "./getEnvironmentVariables";
11
13
 
12
14
  export const createContext = async (
13
15
  config: Config,
@@ -21,27 +23,28 @@ export const createContext = async (
21
23
  "componentName may only contain lower case letters, numbers and -"
22
24
  );
23
25
  }
24
- const rawConfig = config.components[componentName];
25
- if (!rawConfig) {
26
- throw new Error("unknown component " + componentName);
27
- }
28
- // envs can override the config
29
- const envConfig = rawConfig.env?.[env] ?? {};
30
- const componentConfigWithoutDefaults = mergeWithMergingArrays(
31
- rawConfig,
32
- envConfig
26
+
27
+ const envContext = getEnvironmentContext(
28
+ config,
29
+ env,
30
+ componentName,
31
+ commitInfo
33
32
  );
34
33
 
35
- // fill in defaults of build and deploy
34
+ const componentConfigWithoutDefaults = envContext.envConfigRaw;
36
35
  const defaults: {
37
36
  build: Partial<BuildConfig>;
38
37
  deploy: Partial<DeployConfig>;
39
38
  } = componentConfigWithoutDefaults.deploy
40
39
  ? {
41
40
  build:
42
- BUILD_TYPES[componentConfigWithoutDefaults.build.type].defaults(),
41
+ BUILD_TYPES[
42
+ componentConfigWithoutDefaults.build.type as BuildConfigType
43
+ ].defaults(envContext),
43
44
  deploy:
44
- DEPLOY_TYPES[componentConfigWithoutDefaults.deploy.type].defaults(),
45
+ DEPLOY_TYPES[
46
+ componentConfigWithoutDefaults.deploy.type as DeployConfigType
47
+ ].defaults(envContext),
45
48
  }
46
49
  : {
47
50
  build: {},
@@ -7,6 +7,10 @@ import { getRunnerImage } from "../../runner";
7
7
  import type { Context } from "../../types/context";
8
8
  import type { CatladderJob } from "../../types/jobs";
9
9
  import { getBaseDeploymentJob, getBaseDeploymentStopJob } from "../base";
10
+ import type {
11
+ DeployConfigCloudRunJob,
12
+ DeployConfigCloudRunService,
13
+ } from "../types";
10
14
  import { isOfDeployType } from "../types";
11
15
  import { gcloudServiceAccountLoginCommands } from "./utils/gcloudServiceAccountLoginCommands";
12
16
 
@@ -17,7 +21,7 @@ export const createGoogleCloudRunDeployJobs = (
17
21
  if (deployConfig === false) {
18
22
  return [];
19
23
  }
20
- if (!isOfDeployType(deployConfig, "google-cloudrun", "google-cloudrun-job")) {
24
+ if (!isOfDeployType(deployConfig, "google-cloudrun")) {
21
25
  // should not happen
22
26
  throw new Error("deploy config is wrong");
23
27
  }
@@ -46,46 +50,87 @@ export const createGoogleCloudRunDeployJobs = (
46
50
  .join(",");
47
51
 
48
52
  const commonArgs = `--project ${deployConfig.projectId} --region=${deployConfig.region}`;
49
- const getDeployCommand = () => {
50
- const name = context.environment.fullName.toLowerCase();
53
+
54
+ const commonDeployArgs = `--image ${gcloudImageName} ${commonArgs} --labels ${labelsString}`;
55
+ const serviceName = context.environment.fullName.toLowerCase();
56
+
57
+ const getServiceDeployScript = (
58
+ service?: DeployConfigCloudRunService | true
59
+ ) => {
51
60
  const command =
52
- deployConfig.command ?? context.componentConfig.build.startCommand;
61
+ service !== true
62
+ ? service?.command ?? context.componentConfig.build.startCommand
63
+ : undefined;
64
+
53
65
  const commandArg = command
54
66
  ? `--command="${command.split(" ").join(",")}"`
55
67
  : "";
56
68
 
57
- const commonDeployArgs = `${commandArg} --image ${gcloudImageName} ${commonArgs} --env-vars-file=____envvars.yaml --labels ${labelsString}`;
58
- if (deployConfig.type === "google-cloudrun") {
59
- return `gcloud run deploy ${name} ${commonDeployArgs} --allow-unauthenticated`;
60
- }
61
- if (deployConfig.type === "google-cloudrun-job") {
62
- return `gcloud beta run jobs create ${name} ${commonDeployArgs}`;
63
- }
69
+ return `gcloud run deploy ${serviceName} ${commandArg} ${commonDeployArgs} --env-vars-file=____envvars.yaml --allow-unauthenticated`;
70
+ };
71
+
72
+ const getJobDeployScripts = (
73
+ jobName: string,
74
+ job: DeployConfigCloudRunJob
75
+ ) => {
76
+ // due to some oversight from google, jobs create does not accept `--env-vars-file` 🤦
77
+ // lucky, update on the other hand accepts it... so let's just imediatly update it
78
+
79
+ // also we cannot upsert a job, so we have to create it and catch the error and then update
80
+ const args = `${jobName} --command="${job.command
81
+ .split(" ")
82
+ .join(",")}" ${commonDeployArgs}`;
83
+ return [
84
+ "set +e", // disable fail job on error
85
+ `gcloud beta run jobs create ${args}`,
86
+ "set -e", // reenable
87
+ `gcloud beta run jobs update ${args} --env-vars-file=____envvars.yaml`,
88
+ ];
64
89
  };
65
90
 
66
- const getStopCommand = () => {
67
- const name = context.environment.fullName.toLowerCase();
68
- const commonStopArgs = `${commonArgs} --quiet`;
69
- if (deployConfig.type === "google-cloudrun") {
70
- return `gcloud run services delete ${name} ${commonStopArgs}`;
71
- }
72
- if (deployConfig.type === "google-cloudrun-job") {
73
- return `gcloud beta run jobs delete ${name} ${commonStopArgs}`;
74
- }
91
+ const getJobRunScript = (jobName: string) => {
92
+ return `gcloud beta run jobs execute ${jobName} ${commonArgs}`;
75
93
  };
76
94
 
77
- const cloudRunDeploy = [
95
+ const getFullJobName = (name: string) =>
96
+ context.environment.fullName.toLowerCase() + "-" + name;
97
+
98
+ const jobsWithNames = Object.entries(deployConfig.jobs ?? {}).map(
99
+ ([name, job]) => [getFullJobName(name), job] as const
100
+ );
101
+ const cloudRunDeployScripts = [
78
102
  `echo "$ENV_VARS" > ____envvars.yaml`, // TODO: split secrets out
79
- getDeployCommand(),
103
+
104
+ ...jobsWithNames
105
+ .map(([name, job]) => getJobDeployScripts(name, job))
106
+ .flat(),
107
+
108
+ ...(deployConfig.service !== false
109
+ ? [getServiceDeployScript(deployConfig.service)]
110
+ : []),
111
+
112
+ ...jobsWithNames
113
+ .filter(([name, job]) => job.when === "postDeploy")
114
+ .map(([name, job]) => getJobRunScript(name)),
80
115
  `docker image rm ${gcloudImageName}`,
81
116
  ];
82
117
 
118
+ const cloudRunStopScripts = [
119
+ ...(deployConfig.service !== false
120
+ ? [`gcloud run services delete ${serviceName}`]
121
+ : []),
122
+ ...Object.entries(deployConfig.jobs ?? {}).map(
123
+ ([jobName, job]) => `gcloud beta run jobs delete ${jobName}`
124
+ ),
125
+ ];
126
+
83
127
  const baseStopJob = getBaseDeploymentStopJob(context);
84
128
 
85
129
  return [
86
130
  merge({}, baseDeploymentJob, getDockerJobBaseProps(context), {
87
131
  artifacts: { paths: ["____envvars.yaml"] },
88
132
  variables: {
133
+ CLOUDSDK_CORE_DISABLE_PROMPTS: "1",
89
134
  ENV_VARS: dump(allEnvVars, {
90
135
  lineWidth: -1,
91
136
  quotingType: "'",
@@ -93,12 +138,18 @@ export const createGoogleCloudRunDeployJobs = (
93
138
  }),
94
139
  },
95
140
  image: getRunnerImage("gcloud"),
96
- script: [...pushImageToArtifactsRegistry, ...cloudRunDeploy],
141
+ script: [...pushImageToArtifactsRegistry, ...cloudRunDeployScripts],
97
142
  }),
98
143
 
99
144
  merge({}, baseStopJob, {
100
145
  image: getRunnerImage("gcloud"),
101
- script: [...gcloudServiceAccountLoginCommands(context), getStopCommand()],
146
+ variables: {
147
+ CLOUDSDK_CORE_DISABLE_PROMPTS: "1",
148
+ },
149
+ script: [
150
+ ...gcloudServiceAccountLoginCommands(context),
151
+ ...cloudRunStopScripts,
152
+ ],
102
153
  }),
103
154
  ];
104
155
  };
@@ -11,7 +11,7 @@ export const GCLOUD_RUN_DEPLOY_TYPE: DeployTypeDefinition<"google-cloudrun"> = {
11
11
  jobs: createGoogleCloudRunDeployJobs,
12
12
  defaults: () => ({}),
13
13
  additionalSecretKeys: () => [GCLOUD_DEPLOY_CREDENTIALS_KEY],
14
- getAdditionalEnvVars: ({ fullName, env, componentName }) => {
14
+ getAdditionalEnvVars: ({ fullName, env, componentName, deployConfigRaw }) => {
15
15
  const HOST_CANONICAL =
16
16
  fullName.toLowerCase() +
17
17
  "-" +
@@ -19,30 +19,19 @@ export const GCLOUD_RUN_DEPLOY_TYPE: DeployTypeDefinition<"google-cloudrun"> = {
19
19
  getSecretVarName(env, componentName, GCLOUD_RUN_CANONICAL_HOST_SUFFIX)
20
20
  ];
21
21
 
22
+ const jobTriggers =
23
+ deployConfigRaw && deployConfigRaw.jobs
24
+ ? Object.fromEntries(
25
+ Object.entries(deployConfigRaw.jobs).map(([name, job]) => [
26
+ "CLOUD_RUN_JOB_TRIGGER_URL_" + name,
27
+ `https://${deployConfigRaw.region}-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/${deployConfigRaw.projectId}/jobs/${name}:run`,
28
+ ])
29
+ )
30
+ : {};
31
+
22
32
  return {
23
33
  HOST_CANONICAL,
34
+ ...jobTriggers,
24
35
  };
25
36
  },
26
37
  };
27
-
28
- export const GCLOUD_RUN_JOB_DEPLOY_TYPE: DeployTypeDefinition<"google-cloudrun-job"> =
29
- {
30
- jobs: createGoogleCloudRunDeployJobs,
31
- defaults: () => ({}),
32
- additionalSecretKeys: () => [GCLOUD_DEPLOY_CREDENTIALS_KEY],
33
- getAdditionalEnvVars: ({ deployConfig, fullName }) => {
34
- if (!deployConfig) {
35
- return {};
36
- }
37
-
38
- const jobName = fullName.toLowerCase();
39
- const CLOUD_RUN_JOB_TRIGGER_URL = `https://${deployConfig.region}-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/${deployConfig.projectId}/jobs/${jobName}:run`;
40
-
41
- return { CLOUD_RUN_JOB_TRIGGER_URL };
42
- },
43
- };
44
-
45
- export const GCLOUD_RUN_DEPLOY_TYPES = {
46
- "google-cloudrun": GCLOUD_RUN_DEPLOY_TYPE,
47
- "google-cloudrun-job": GCLOUD_RUN_JOB_DEPLOY_TYPE,
48
- };