@catladder/pipeline 3.7.0 → 3.8.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.
@@ -0,0 +1,11 @@
1
+ import { createYamlLocalPipeline } from "./__utils__/helpers";
2
+ import config from "./cloud-run-health-check-defaults";
3
+
4
+ /**
5
+ * This test is auto-generated.
6
+ * Modifications will be overwritten on every `yarn test` run!
7
+ */
8
+
9
+ it("matches snapshot for cloud-run-health-check-defaults local pipeline YAML", async () => {
10
+ expect(await createYamlLocalPipeline(config)).toMatchSnapshot();
11
+ });
@@ -0,0 +1,28 @@
1
+ import type { Config } from "../src";
2
+
3
+ const config = {
4
+ appName: "test-app",
5
+ customerName: "pan",
6
+ components: {
7
+ www: {
8
+ dir: "www",
9
+ build: {
10
+ type: "node",
11
+ },
12
+ deploy: {
13
+ type: "google-cloudrun",
14
+ projectId: "google-project-id",
15
+ region: "europe-west6",
16
+ service: {
17
+ healthCheck: true,
18
+ },
19
+ },
20
+ },
21
+ },
22
+ } satisfies Config;
23
+
24
+ export default config;
25
+
26
+ export const information = {
27
+ title: "Cloud Run: Health Check",
28
+ };
@@ -0,0 +1,11 @@
1
+ import { createYamlLocalPipeline } from "./__utils__/helpers";
2
+ import config from "./cloud-run-health-check-only-startup";
3
+
4
+ /**
5
+ * This test is auto-generated.
6
+ * Modifications will be overwritten on every `yarn test` run!
7
+ */
8
+
9
+ it("matches snapshot for cloud-run-health-check-only-startup local pipeline YAML", async () => {
10
+ expect(await createYamlLocalPipeline(config)).toMatchSnapshot();
11
+ });
@@ -0,0 +1,38 @@
1
+ import type { Config } from "../src";
2
+
3
+ const config = {
4
+ appName: "test-app",
5
+ customerName: "pan",
6
+ components: {
7
+ www: {
8
+ dir: "www",
9
+ build: {
10
+ type: "node",
11
+ },
12
+ deploy: {
13
+ type: "google-cloudrun",
14
+ projectId: "google-project-id",
15
+ region: "europe-west6",
16
+ service: {
17
+ healthCheck: {
18
+ livenessProbe: false,
19
+ startupProbe: {
20
+ type: "http1",
21
+ failureThreshold: 43,
22
+ initialDelaySeconds: 4,
23
+ path: "/something2",
24
+ periodSeconds: 5,
25
+ timeoutSeconds: 6,
26
+ },
27
+ },
28
+ },
29
+ },
30
+ },
31
+ },
32
+ } satisfies Config;
33
+
34
+ export default config;
35
+
36
+ export const information = {
37
+ title: "Cloud Run: Health Check",
38
+ };
@@ -0,0 +1,11 @@
1
+ import { createYamlLocalPipeline } from "./__utils__/helpers";
2
+ import config from "./cloud-run-health-check";
3
+
4
+ /**
5
+ * This test is auto-generated.
6
+ * Modifications will be overwritten on every `yarn test` run!
7
+ */
8
+
9
+ it("matches snapshot for cloud-run-health-check local pipeline YAML", async () => {
10
+ expect(await createYamlLocalPipeline(config)).toMatchSnapshot();
11
+ });
@@ -0,0 +1,45 @@
1
+ import type { Config } from "../src";
2
+
3
+ const config = {
4
+ appName: "test-app",
5
+ customerName: "pan",
6
+ components: {
7
+ www: {
8
+ dir: "www",
9
+ build: {
10
+ type: "node",
11
+ },
12
+ deploy: {
13
+ type: "google-cloudrun",
14
+ projectId: "google-project-id",
15
+ region: "europe-west6",
16
+ service: {
17
+ healthCheck: {
18
+ livenessProbe: {
19
+ type: "http1",
20
+ failureThreshold: 42,
21
+ initialDelaySeconds: 1,
22
+ path: "/something",
23
+ periodSeconds: 2,
24
+ timeoutSeconds: 3,
25
+ },
26
+ startupProbe: {
27
+ type: "http1",
28
+ failureThreshold: 43,
29
+ initialDelaySeconds: 4,
30
+ path: "/something2",
31
+ periodSeconds: 5,
32
+ timeoutSeconds: 6,
33
+ },
34
+ },
35
+ },
36
+ },
37
+ },
38
+ },
39
+ } satisfies Config;
40
+
41
+ export default config;
42
+
43
+ export const information = {
44
+ title: "Cloud Run: Health Check",
45
+ };
package/package.json CHANGED
@@ -53,7 +53,7 @@
53
53
  }
54
54
  ],
55
55
  "license": "MIT",
56
- "version": "3.7.0",
56
+ "version": "3.8.0",
57
57
  "scripts": {
58
58
  "build:tsc": "yarn tsc",
59
59
  "build": "yarn build:compile && yarn build:inline-variables",
@@ -12,6 +12,7 @@ import {
12
12
  makeLabelString,
13
13
  } from "./common";
14
14
  import { ENV_VARS_FILENAME } from "./constants";
15
+ import { healthCheckCliArgs } from "./healthCheck";
15
16
  import { createVolumeConfig } from "./volumes";
16
17
 
17
18
  export const getServiceDeployScript = (
@@ -38,6 +39,7 @@ export const getServiceDeployScript = (
38
39
  : command.split(" ")
39
40
  : undefined;
40
41
  const fullServiceName = serviceName.concat(nameSuffix ?? "");
42
+
41
43
  const argsString = createArgsString(
42
44
  {
43
45
  // command as empty string resets it to default (uses the image's entrypoint)
@@ -67,6 +69,7 @@ export const getServiceDeployScript = (
67
69
  "execution-environment": customConfig?.executionEnvironment,
68
70
  gpu: customConfig?.gpu,
69
71
  "gpu-type": customConfig?.gpuType,
72
+ ...healthCheckCliArgs(customConfig?.healthCheck),
70
73
  },
71
74
  ...createVolumeConfig(customConfig?.volumes, "service"),
72
75
  );
@@ -103,5 +106,8 @@ const requiresBeta = (config: DeployConfigCloudRunService | undefined) => {
103
106
  if (config.gpu && config.gpu > 0) {
104
107
  return true;
105
108
  }
109
+ if (config.healthCheck !== undefined) {
110
+ return true;
111
+ }
106
112
  return false;
107
113
  };
@@ -0,0 +1,64 @@
1
+ import type { DeployConfigCloudRunProbeShared } from "../../types";
2
+ import {
3
+ defaultLivenessProbe,
4
+ defaultStartupProbe,
5
+ type DeployConfigCloudRunProbe,
6
+ type DeployConfigCloudRunService,
7
+ } from "../../types";
8
+
9
+ const PORT = 8080;
10
+
11
+ export function healthCheckCliArgs(
12
+ healthCheck: DeployConfigCloudRunService["healthCheck"],
13
+ ) {
14
+ const shouldNotSetHealthCheck = healthCheck === undefined;
15
+ if (shouldNotSetHealthCheck) {
16
+ return undefined;
17
+ }
18
+
19
+ const shouldUseDefaultProbe = healthCheck === true;
20
+
21
+ if (shouldUseDefaultProbe) {
22
+ return {
23
+ "startup-probe": toArgValue(probeToKeyValuePairs(defaultStartupProbe)),
24
+ "liveness-probe": toArgValue(probeToKeyValuePairs(defaultLivenessProbe)),
25
+ };
26
+ }
27
+
28
+ return {
29
+ "startup-probe": toArgValue(probeToKeyValuePairs(healthCheck.startupProbe)),
30
+ "liveness-probe": healthCheck.livenessProbe
31
+ ? toArgValue(probeToKeyValuePairs(healthCheck.livenessProbe))
32
+ : "", // NOTE: empty string ("") removes liveness probe
33
+ };
34
+ }
35
+
36
+ function probeToKeyValuePairs(
37
+ probe: DeployConfigCloudRunProbe,
38
+ ): [string, unknown][] {
39
+ const sharedArgs = Object.entries({
40
+ initialDelaySeconds: probe.initialDelaySeconds,
41
+ timeoutSeconds: probe.timeoutSeconds,
42
+ periodSeconds: probe.periodSeconds,
43
+ failureThreshold: probe.failureThreshold,
44
+ } satisfies DeployConfigCloudRunProbeShared);
45
+
46
+ switch (probe.type) {
47
+ case "tcp":
48
+ return [...sharedArgs, ["tcpSocket.port", PORT]];
49
+ case "http1":
50
+ return [
51
+ ...sharedArgs,
52
+ ["httpGet.port", PORT],
53
+ ["httpGet.path", probe.path],
54
+ // NOTE: headers are not supported by "gcloud beta" at the moment
55
+ ];
56
+ default:
57
+ probe satisfies never;
58
+ return [];
59
+ }
60
+ }
61
+
62
+ function toArgValue(keyValues: [string, unknown][]) {
63
+ return keyValues.map(([key, value]) => `${key}=${value}`).join(",");
64
+ }
@@ -191,9 +191,110 @@ export type DeployConfigCloudRunService = {
191
191
  * args to pass to the command
192
192
  */
193
193
  args?: string[];
194
+
195
+ /**
196
+ * Configuration of the health check.
197
+ *
198
+ * When set to `true`, startup and liveness probes will be
199
+ * configured to `defaultStartupProbe` and `defaultLivenessProbe`.
200
+ *
201
+ * When not set, default Cloud Run's health check
202
+ * configuration is used (startup TCP probe and no liveness probe).
203
+ */
204
+ healthCheck?:
205
+ | true
206
+ | {
207
+ /**
208
+ * Startup probe configuration.
209
+ */
210
+ startupProbe: DeployConfigCloudRunProbe;
211
+
212
+ /**
213
+ * Liveness probe configuration.
214
+ * `false` disables the liveness probe.
215
+ */
216
+ livenessProbe: false | DeployConfigCloudRunProbe;
217
+ };
194
218
  } & DeployConfigCloudRunWithVolumes &
195
219
  DeployConfigCloudRunNetworkConfig;
196
220
 
221
+ export const defaultStartupProbe: DeployConfigCloudRunProbe = {
222
+ type: "http1",
223
+ path: "/__health",
224
+
225
+ initialDelaySeconds: 5,
226
+ timeoutSeconds: 1,
227
+ periodSeconds: 30,
228
+ failureThreshold: 3,
229
+ };
230
+
231
+ export const defaultLivenessProbe: DeployConfigCloudRunProbe = {
232
+ ...defaultStartupProbe,
233
+
234
+ initialDelaySeconds: 0,
235
+ timeoutSeconds: 10,
236
+ periodSeconds: 30,
237
+ failureThreshold: 3,
238
+ };
239
+
240
+ export type DeployConfigCloudRunProbe =
241
+ | DeployConfigCloudRunHttp1Probe
242
+ | DeployConfigCloudRunTcpProbe;
243
+
244
+ export type DeployConfigCloudRunProbeShared = {
245
+ /**
246
+ * The period in seconds at which to perform the probe.
247
+ * For example 2 to perform the probe every 2 seconds.
248
+ * Specify a value **from 1 second to 240** seconds.
249
+ */
250
+ periodSeconds: number;
251
+
252
+ /**
253
+ * The number of seconds to wait after the container has started before performing the first probe.
254
+ * Specify a value **from 0 seconds to 240** seconds.
255
+ */
256
+ initialDelaySeconds: number;
257
+
258
+ /**
259
+ * The number of seconds to wait until the probe times out.
260
+ * This value cannot exceed the value specified for `period`.
261
+ * Specify a value **from 1 to 240**.
262
+ */
263
+ timeoutSeconds: number;
264
+
265
+ /**
266
+ * The number of times to retry the probe before shutting down the container.
267
+ */
268
+ failureThreshold: number;
269
+ };
270
+
271
+ export type DeployConfigCloudRunTcpProbe = DeployConfigCloudRunProbeShared & {
272
+ /**
273
+ * Cloud Run makes a TCP connection to open the TCP Socket on the specified port.
274
+ * If Cloud Run is unable to establish a connection, it indicates a failure.
275
+ */
276
+ type: "tcp";
277
+ };
278
+
279
+ export type DeployConfigCloudRunHttp1Probe = DeployConfigCloudRunProbeShared & {
280
+ /**
281
+ * **This will NOT work with http2 enabled services**
282
+ *
283
+ * Cloud Run makes an HTTP GET request to the service health check endpoint (for example, /ready).
284
+ * Any response between 200 and 400 is a success, everything else indicates failure.
285
+ *
286
+ * If a startup probe does not succeed within the specified time (failureThreshold * period), which cannot exceed 240 seconds, the container is shut down.
287
+ *
288
+ * If the HTTP startup probe succeeds within the specified time, and you have enabled liveness probe, the HTTP liveness probe is started.
289
+ */
290
+ type: "http1";
291
+
292
+ /**
293
+ * the route path to check for health status of the service starting with a `/`.
294
+ */
295
+ path: string;
296
+ };
297
+
197
298
  export type DeployConfigCloudRunNetworkConfig = {
198
299
  /* the vpc network, see https://cloud.google.com/sdk/gcloud/reference/run/deploy#--network */
199
300
  network?: string;