@catladder/pipeline 1.62.0 → 1.63.0

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.
@@ -8,7 +8,9 @@ import type { Context } from "../../types/context";
8
8
  import type { CatladderJob } from "../../types/jobs";
9
9
  import { getBaseDeploymentJob, getBaseDeploymentStopJob } from "../base";
10
10
  import type {
11
+ DeployConfigCloudRun,
11
12
  DeployConfigCloudRunJob,
13
+ DeployConfigCloudRunJobWithSchedule,
12
14
  DeployConfigCloudRunService,
13
15
  } from "../types";
14
16
  import { isOfDeployType } from "../types";
@@ -19,6 +21,10 @@ import {
19
21
  } from "./utils/database";
20
22
  import { allowFailureInScripts } from "../../utils/gitlab";
21
23
 
24
+ const setExtraVarsScripts = (deployConfig: DeployConfigCloudRun) => [
25
+ `export GCLOUD_PROJECT_NUMBER=$(gcloud projects describe ${deployConfig.projectId} --format="value(projectNumber)")`,
26
+ `echo "GCLOUD_PROJECT_NUMBER: $GCLOUD_PROJECT_NUMBER"`,
27
+ ];
22
28
  export const createGoogleCloudRunDeployJobs = (
23
29
  context: Context
24
30
  ): CatladderJob[] => {
@@ -38,7 +44,6 @@ export const createGoogleCloudRunDeployJobs = (
38
44
 
39
45
  const pushImageToArtifactsRegistry = [
40
46
  gitlabDockerLogin,
41
- ...gcloudServiceAccountLoginCommands(context),
42
47
  `gcloud auth configure-docker ${deployConfig.region}-docker.pkg.dev`,
43
48
  `docker pull $DOCKER_IMAGE:$DOCKER_IMAGE_TAG`,
44
49
  `docker tag $DOCKER_IMAGE:$DOCKER_IMAGE_TAG ${gcloudImageName}`,
@@ -61,6 +66,33 @@ export const createGoogleCloudRunDeployJobs = (
61
66
  const commonDeployArgs = `--image ${gcloudImageName} ${commonArgs} ${cloudRunArgs} --labels ${labelsString}`;
62
67
  const serviceName = context.environment.fullName.toLowerCase();
63
68
 
69
+ const getFullJobName = (name: string) =>
70
+ context.environment.fullName.toLowerCase() + "-" + name.toLowerCase();
71
+
72
+ const jobsWithNames = Object.entries(deployConfig.jobs ?? {})
73
+ // filter out disabled jobs
74
+ .filter((entry): entry is [string, DeployConfigCloudRunJob] =>
75
+ Boolean(entry[1])
76
+ )
77
+ .map(([name, job]) => ({
78
+ jobName: getFullJobName(name),
79
+ job,
80
+ }));
81
+ const jobsWithSchedule = jobsWithNames
82
+ .filter(
83
+ (
84
+ entry
85
+ ): entry is {
86
+ jobName: string;
87
+ job: DeployConfigCloudRunJobWithSchedule;
88
+ } => entry.job.when === "schedule"
89
+ )
90
+ .map(({ job, jobName }) => ({
91
+ job,
92
+ jobName,
93
+ schedulerName: jobName + "-scheduler",
94
+ }));
95
+
64
96
  const getServiceDeployScript = (
65
97
  service?: DeployConfigCloudRunService | true
66
98
  ) => {
@@ -76,7 +108,7 @@ export const createGoogleCloudRunDeployJobs = (
76
108
  return `gcloud run deploy ${serviceName} ${commandArg} ${commonDeployArgs} --env-vars-file=____envvars.yaml --allow-unauthenticated`;
77
109
  };
78
110
 
79
- const getJobCreateScripts = (
111
+ const getJobCreateScriptsForJob = (
80
112
  jobName: string,
81
113
  job: DeployConfigCloudRunJob
82
114
  ) => {
@@ -93,56 +125,86 @@ export const createGoogleCloudRunDeployJobs = (
93
125
  ];
94
126
  };
95
127
 
96
- const getJobRunScript = (jobName: string) => {
128
+ const getJobCreateScripts = () =>
129
+ jobsWithNames
130
+ .map(({ job, jobName }) => getJobCreateScriptsForJob(jobName, job))
131
+ .flat();
132
+
133
+ const getJobRunScriptForJob = (jobName: string) => {
97
134
  return `gcloud beta run jobs execute ${jobName} ${commonArgs}`;
98
135
  };
99
136
 
100
- const getFullJobName = (name: string) =>
101
- context.environment.fullName.toLowerCase() + "-" + name.toLowerCase();
137
+ const getJobRunScripts = (when: DeployConfigCloudRunJob["when"]) =>
138
+ jobsWithNames
139
+ .filter(({ job }) => job.when === when)
140
+ .map(({ jobName }) => getJobRunScriptForJob(jobName));
141
+
142
+ const getCreateScheduleScripts = () => {
143
+ return jobsWithSchedule
144
+ .map(({ job, jobName, schedulerName }) => {
145
+ const commonArgs = `http ${schedulerName} --project=${deployConfig.projectId} --location ${deployConfig.region} \
146
+ --schedule="${job.schedule}" \
147
+ --uri="https://${deployConfig.region}-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/${deployConfig.projectId}/jobs/${jobName}:run" \
148
+ --http-method POST \
149
+ --oauth-service-account-email $GCLOUD_PROJECT_NUMBER-compute@developer.gserviceaccount.com`;
150
+ return [
151
+ ...allowFailureInScripts([
152
+ `gcloud scheduler jobs create ${commonArgs}`,
153
+ ]),
154
+ `gcloud scheduler jobs update ${commonArgs}`,
155
+ ];
156
+ })
157
+ .flat();
158
+ };
102
159
 
103
- const jobsWithNames = Object.entries(deployConfig.jobs ?? {})
104
- // filter out disabled jobs
105
- .filter((entry): entry is [string, DeployConfigCloudRunJob] =>
106
- Boolean(entry[1])
107
- )
108
- .map(([name, job]) => [getFullJobName(name), job] as const);
109
- const cloudRunDeployScripts = [
160
+ const getDeleteSchedulesScripts = () => {
161
+ return jobsWithSchedule
162
+ .map(({ schedulerName }) => {
163
+ return [
164
+ ...allowFailureInScripts([
165
+ `gcloud scheduler jobs delete ${schedulerName} --project=${deployConfig.projectId} --location ${deployConfig.region}`,
166
+ ]),
167
+ ];
168
+ })
169
+ .flat();
170
+ };
171
+
172
+ const getDeleteJobsScripts = () =>
173
+ jobsWithNames.map(
174
+ ({ jobName }) => `gcloud beta run jobs delete ${jobName} ${commonArgs}`
175
+ );
176
+
177
+ const deployScripts = [
178
+ ...gcloudServiceAccountLoginCommands(context),
179
+ ...setExtraVarsScripts(deployConfig),
180
+ ...pushImageToArtifactsRegistry,
110
181
  `echo "$ENV_VARS" > ____envvars.yaml`, // TODO: split secrets out
111
182
  ...(deployConfig.cloudSql
112
183
  ? getDatabaseCreateScript(context, deployConfig) // we create the db, so that we can also delete it afterwards
113
184
  : []),
114
-
115
- ...jobsWithNames
116
- .map(([name, job]) => getJobCreateScripts(name, job))
117
- .flat(),
118
- ...jobsWithNames
119
- .filter(([, job]) => job.when === "preDeploy")
120
- .map(([name]) => getJobRunScript(name)),
185
+ ...getCreateScheduleScripts(),
186
+ ...getJobCreateScripts(),
187
+ ...getJobRunScripts("preDeploy"),
121
188
 
122
189
  ...(deployConfig.service !== false
123
190
  ? [getServiceDeployScript(deployConfig.service)]
124
191
  : []),
192
+ ...getJobRunScripts("postDeploy"),
125
193
 
126
- ...jobsWithNames
127
- .filter(([, job]) => job.when === "postDeploy")
128
- .map(([name]) => getJobRunScript(name)),
129
194
  `docker image rm ${gcloudImageName}`,
130
195
  ];
131
196
 
132
- const cloudRunStopScripts = [
197
+ const stopScripts = [
198
+ ...gcloudServiceAccountLoginCommands(context),
133
199
  ...(deployConfig.service !== false
134
200
  ? [`gcloud run services delete ${serviceName} ${commonArgs}`]
135
201
  : []),
136
- ...jobsWithNames.map(
137
- ([name]) => `gcloud beta run jobs delete ${name} ${commonArgs}`
138
- ),
202
+ ...getDeleteSchedulesScripts(),
203
+ ...getDeleteJobsScripts(),
139
204
  ...(deployConfig.cloudSql && deployConfig.cloudSql.deleteDatabaseOnStop
140
205
  ? getDatabaseDeleteScript(context, deployConfig)
141
206
  : []),
142
207
  ];
143
-
144
- const baseStopJob = getBaseDeploymentStopJob(context);
145
-
146
208
  return [
147
209
  merge({}, baseDeploymentJob, getDockerJobBaseProps(context), {
148
210
  artifacts: { paths: ["____envvars.yaml"] },
@@ -155,18 +217,15 @@ export const createGoogleCloudRunDeployJobs = (
155
217
  }),
156
218
  },
157
219
  image: getRunnerImage("gcloud"),
158
- script: [...pushImageToArtifactsRegistry, ...cloudRunDeployScripts],
220
+ script: deployScripts,
159
221
  }),
160
222
 
161
- merge({}, baseStopJob, {
223
+ merge({}, getBaseDeploymentStopJob(context), {
162
224
  image: getRunnerImage("gcloud"),
163
225
  variables: {
164
226
  CLOUDSDK_CORE_DISABLE_PROMPTS: "1",
165
227
  },
166
- script: [
167
- ...gcloudServiceAccountLoginCommands(context),
168
- ...cloudRunStopScripts,
169
- ],
228
+ script: stopScripts,
170
229
  }),
171
230
  ];
172
231
  };
@@ -59,19 +59,37 @@ export type DeployConfigCloudRunService = {
59
59
  command?: string;
60
60
  };
61
61
 
62
- export type DeployConfigCloudRunJob = {
62
+ export type DeployConfigCloudRunJobBase = {
63
63
  /**
64
64
  * command
65
65
  */
66
66
  command: string;
67
67
 
68
- when: "manual" | "preDeploy" | "postDeploy";
69
-
70
68
  /**
71
69
  * memory limit of the job, defaults to 51Mi
72
70
  */
73
71
  memory?: `${number}${"M" | "G" | "Mi" | "Gi"}`;
74
72
  };
73
+
74
+ type Minute = string;
75
+ type Hour = string;
76
+ type DayOfMonth = string;
77
+ type DayOfWeek = string;
78
+ type Month = string;
79
+ export type DeployConfigCloudRunJobWithSchedule =
80
+ DeployConfigCloudRunJobBase & {
81
+ when: "schedule";
82
+ schedule: `${Minute} ${Hour} ${DayOfMonth} ${Month} ${DayOfWeek}`;
83
+ };
84
+
85
+ export type DeployConfigCloudRunJobNormal = DeployConfigCloudRunJobBase & {
86
+ when: "manual" | "preDeploy" | "postDeploy";
87
+ };
88
+
89
+ export type DeployConfigCloudRunJob =
90
+ | DeployConfigCloudRunJobNormal
91
+ | DeployConfigCloudRunJobWithSchedule;
92
+
75
93
  export type DeployConfigCloudRun = {
76
94
  /**
77
95
  * EXPERIMENTAL cloud run deployment.
@@ -16,9 +16,11 @@ export type Retry = {
16
16
  when: string[];
17
17
  };
18
18
 
19
- export type Service = {
19
+ export type GitlabJobService = {
20
20
  name: string;
21
21
  command: string[];
22
+ entrypoint?: string[];
23
+ alias?: string;
22
24
  };
23
25
 
24
26
  export type GitlabEnvironment = {
@@ -41,7 +43,7 @@ export type GitlabJobDef = {
41
43
  cache?: GitlabJobCache | GitlabJobCache[];
42
44
  artifacts?: Artifacts;
43
45
  retry?: Retry;
44
- services?: Service[];
46
+ services?: GitlabJobService[];
45
47
  image?: string;
46
48
  variables?: GitlabVariables;
47
49
  dependencies?: string[];
package/src/types/jobs.ts CHANGED
@@ -4,7 +4,7 @@ import type {
4
4
  GitlabJobCache,
5
5
  GitlabRule,
6
6
  GitlabVariables,
7
- Service,
7
+ GitlabJobService,
8
8
  } from "./gitlab-types";
9
9
 
10
10
  export const BASE_STAGES = [
@@ -72,7 +72,7 @@ export type CatladderJob<S = BaseStage> = {
72
72
  /**
73
73
  * additional services, mainly used for docker
74
74
  */
75
- services?: Service[];
75
+ services?: GitlabJobService[];
76
76
 
77
77
  /**
78
78
  * image to use