@vaharoni/devops 1.1.6 → 1.1.8

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 (50) hide show
  1. package/README.md +5 -1
  2. package/dist/cli/cloudrun.d.ts +11 -0
  3. package/dist/cli/cloudrun.d.ts.map +1 -0
  4. package/dist/cli/cloudrun.js +121 -0
  5. package/dist/cli/common.d.ts +10 -12
  6. package/dist/cli/common.d.ts.map +1 -1
  7. package/dist/cli/common.js +28 -22
  8. package/dist/cli/env.js +2 -2
  9. package/dist/cli/prep-build.d.ts.map +1 -1
  10. package/dist/cli/prep-build.js +35 -6
  11. package/dist/cli/registry.d.ts.map +1 -1
  12. package/dist/cli/registry.js +12 -3
  13. package/dist/devops.js +3 -1
  14. package/dist/libs/cloudrun-helpers.d.ts +16 -0
  15. package/dist/libs/cloudrun-helpers.d.ts.map +1 -0
  16. package/dist/libs/cloudrun-helpers.js +79 -0
  17. package/dist/libs/discovery/process-common.js +1 -1
  18. package/dist/libs/k8s-constants.d.ts +1 -0
  19. package/dist/libs/k8s-constants.d.ts.map +1 -1
  20. package/dist/libs/k8s-constants.js +35 -10
  21. package/dist/libs/k8s-generate.d.ts +1 -1
  22. package/dist/libs/k8s-generate.d.ts.map +1 -1
  23. package/dist/libs/k8s-generate.js +4 -2
  24. package/dist/libs/k8s-secrets-manager.d.ts +2 -1
  25. package/dist/libs/k8s-secrets-manager.d.ts.map +1 -1
  26. package/dist/libs/k8s-secrets-manager.js +8 -5
  27. package/dist/types/index.d.ts +19 -8
  28. package/dist/types/index.d.ts.map +1 -1
  29. package/dist/types/index.js +3 -1
  30. package/package.json +1 -1
  31. package/src/cli/cloudrun.ts +133 -0
  32. package/src/cli/common.ts +46 -38
  33. package/src/cli/db.ts +1 -1
  34. package/src/cli/dml.ts +1 -1
  35. package/src/cli/env.ts +2 -2
  36. package/src/cli/exec.ts +1 -1
  37. package/src/cli/job.ts +1 -1
  38. package/src/cli/prep-build.ts +34 -6
  39. package/src/cli/redis.ts +1 -1
  40. package/src/cli/registry.ts +12 -3
  41. package/src/devops.ts +3 -1
  42. package/src/libs/cloudrun-helpers.ts +118 -0
  43. package/src/libs/discovery/process-common.ts +1 -1
  44. package/src/libs/k8s-constants.ts +36 -12
  45. package/src/libs/k8s-generate.ts +3 -2
  46. package/src/libs/k8s-secrets-manager.ts +9 -5
  47. package/src/target-templates/lang-variants-common/python/.devops/config/images.yaml +3 -1
  48. package/src/target-templates/lang-variants-common/typescript/.devops/docker-images/cloudrun.Dockerfile +31 -0
  49. package/src/target-templates/lang-variants-common/typescript/.github/actions/deploy-image@v1/action.yaml +4 -0
  50. package/src/types/index.ts +3 -1
@@ -1,7 +1,7 @@
1
1
  import type { PackageData, TemplateDbMigrateObject, TemplateDebugObject, TemplateDeploymentObject, TemplateSharedContext } from "../types";
2
2
  export declare function generateImageDeployments(monorepoEnv: string, image: string, gitSha: string): string;
3
3
  export declare function generateWorkspaceDeployment(packageData: PackageData, monorepoEnv: string, image: string, gitSha: string): string;
4
- export declare function generateDebugDeployment(monorepoEnv: string, image: string, gitSha: string): string;
4
+ export declare function generateDebugDeployment(monorepoEnv: string, image: string, gitSha: string): string | undefined;
5
5
  export declare function generateDbMigrateJob(monorepoEnv: string, image: string, gitSha: string): string;
6
6
  export declare class ImageContextGenerator {
7
7
  monorepoEnv: string;
@@ -1 +1 @@
1
- {"version":3,"file":"k8s-generate.d.ts","sourceRoot":"","sources":["../../src/libs/k8s-generate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAqB3I,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,UAaf;AAED,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAMvH;AAED,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,UAOf;AAED,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,UAMf;AA6FD,qBAAa,qBAAqB;IAIb,WAAW,EAAE,MAAM;IAAS,KAAK,EAAE,MAAM;IAAS,MAAM,EAAE,MAAM;IAHnF,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,YAAY,EAAE,IAAI,CAAC,qBAAqB,EAAE,cAAc,CAAC,CAAC;gBAEvC,WAAW,EAAE,MAAM,EAAS,KAAK,EAAE,MAAM,EAAS,MAAM,EAAE,MAAM;IAYnF,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,wBAAwB;IAmB7D,YAAY,IAAI,uBAAuB;IAOvC,QAAQ,IAAI,mBAAmB;CAMhC"}
1
+ {"version":3,"file":"k8s-generate.d.ts","sourceRoot":"","sources":["../../src/libs/k8s-generate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAqB3I,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,UAaf;AAED,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAMvH;AAED,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,sBAQf;AAED,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,UAMf;AA6FD,qBAAa,qBAAqB;IAIb,WAAW,EAAE,MAAM;IAAS,KAAK,EAAE,MAAM;IAAS,MAAM,EAAE,MAAM;IAHnF,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,YAAY,EAAE,IAAI,CAAC,qBAAqB,EAAE,cAAc,CAAC,CAAC;gBAEvC,WAAW,EAAE,MAAM,EAAS,KAAK,EAAE,MAAM,EAAS,MAAM,EAAE,MAAM;IAYnF,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,wBAAwB;IAmB7D,YAAY,IAAI,uBAAuB;IAOvC,QAAQ,IAAI,mBAAmB;CAMhC"}
@@ -5,7 +5,7 @@ import path from "path";
5
5
  import yaml from "yaml";
6
6
  import fs from 'fs';
7
7
  import { globSync } from "glob";
8
- import _, { template } from 'lodash';
8
+ import _ from 'lodash';
9
9
  import Handlebars from "handlebars";
10
10
  import { getImageData } from "./config";
11
11
  import { getImageDescendentData } from "./discovery/images";
@@ -23,7 +23,7 @@ export function generateImageDeployments(monorepoEnv, image, gitSha) {
23
23
  return generateManifestForDeployment(projectData.rootPath, projectData.deployment.template, renderFn);
24
24
  });
25
25
  const debug = generateDebugDeployment(monorepoEnv, image, gitSha);
26
- const manifest = [debug, ...apps].join("\n---\n");
26
+ const manifest = [debug, ...apps].filter(Boolean).join("\n---\n");
27
27
  return ensureProperDomainsPresent(manifest, monorepoEnv, image);
28
28
  }
29
29
  export function generateWorkspaceDeployment(packageData, monorepoEnv, image, gitSha) {
@@ -38,6 +38,8 @@ export function generateDebugDeployment(monorepoEnv, image, gitSha) {
38
38
  const context = generator.getDebug();
39
39
  const renderFn = (template) => Handlebars.compile(template)(context);
40
40
  const debugTemplate = getImageData(image)["debug-template"];
41
+ if (!debugTemplate)
42
+ return;
41
43
  return generateManifestsFromTemplateName(debugTemplate, renderFn).map(x => yaml.stringify(x)).join("\n---\n");
42
44
  }
43
45
  export function generateDbMigrateJob(monorepoEnv, image, gitSha) {
@@ -1,4 +1,5 @@
1
- export declare function getMonorepoSecret(monorepoEnv: string, keys?: string[]): string;
1
+ export declare function getMonorepoSecretObject(monorepoEnv: string, keys?: string[]): Record<string, string>;
2
+ export declare function getMonorepoSecretStr(monorepoEnv: string, keys?: string[]): string;
2
3
  /** E.g.: setMonorepoSecret('staging', ['KEY1=val1', 'KEY2=val2']) */
3
4
  export declare function setMonorepoSecret(monorepoEnv: string, pairs?: string[]): void;
4
5
  export declare function deleteMonorepoSecret(monorepoEnv: string, keys?: string[]): void;
@@ -1 +1 @@
1
- {"version":3,"file":"k8s-secrets-manager.d.ts","sourceRoot":"","sources":["../../src/libs/k8s-secrets-manager.ts"],"names":[],"mappings":"AA0DA,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,EAAO,UAKzE;AAED,qEAAqE;AACrE,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,GAAE,MAAM,EAAO,QAQ1E;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,EAAO,QAE5E"}
1
+ {"version":3,"file":"k8s-secrets-manager.d.ts","sourceRoot":"","sources":["../../src/libs/k8s-secrets-manager.ts"],"names":[],"mappings":"AAkBA,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,EAAO,0BAY/E;AA4BD,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,EAAO,UAS5E;AAED,qEAAqE;AACrE,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,GAAE,MAAM,EAAO,QAQ1E;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,EAAO,QAE5E"}
@@ -9,7 +9,7 @@ function execUpdateSecret(monorepoEnv, secretValue) {
9
9
  const { fullCommand, redactedCommand } = patchSecretKeyCommand(monorepoEnv, secretName(), SECRET_FILE_NAME, JSON.stringify(secretValue));
10
10
  new CommandExecutor(fullCommand, { quiet: true, redactedCommand }).exec();
11
11
  }
12
- function getSecret(monorepoEnv, keys = []) {
12
+ export function getMonorepoSecretObject(monorepoEnv, keys = []) {
13
13
  // Dots in jsonpath can only be accessed with a \ prefix
14
14
  const escapedSecretFileName = SECRET_FILE_NAME.replaceAll(".", "\\.");
15
15
  // prettier-ignore
@@ -28,7 +28,7 @@ function updateSecret(monorepoEnv, vars) {
28
28
  console.error("Keys-value pairs to set must be provided, e.g. KEY1=val1 KEY2=val2");
29
29
  process.exit(1);
30
30
  }
31
- const current = getSecret(monorepoEnv);
31
+ const current = getMonorepoSecretObject(monorepoEnv);
32
32
  const newVars = { ...current, ...vars };
33
33
  execUpdateSecret(monorepoEnv, newVars);
34
34
  }
@@ -37,13 +37,16 @@ function deleteSecretKeys(monorepoEnv, keys = []) {
37
37
  console.error("Keys to delete must be provided");
38
38
  process.exit(1);
39
39
  }
40
- const secretValue = getSecret(monorepoEnv);
40
+ const secretValue = getMonorepoSecretObject(monorepoEnv);
41
41
  keys.forEach((key) => delete secretValue[key]);
42
42
  execUpdateSecret(monorepoEnv, secretValue);
43
43
  }
44
44
  //= Interface (L3)
45
- export function getMonorepoSecret(monorepoEnv, keys = []) {
46
- const value = getSecret(monorepoEnv, keys);
45
+ export function getMonorepoSecretStr(monorepoEnv, keys = []) {
46
+ const value = getMonorepoSecretObject(monorepoEnv, keys);
47
+ if (Object.keys(value).length === 1) {
48
+ return Object.values(value)[0];
49
+ }
47
50
  return Object.entries(value)
48
51
  .map((pair) => pair.join("="))
49
52
  .join("\n");
@@ -7,6 +7,7 @@ export declare const constFileSchema: z.ZodObject<{
7
7
  "image-versions-to-keep": z.ZodOptional<z.ZodNumber>;
8
8
  "registry-base-url": z.ZodString;
9
9
  "registry-image-path-prefix": z.ZodOptional<z.ZodString>;
10
+ "cloudrun-artifact-registry-repo-path": z.ZodOptional<z.ZodString>;
10
11
  "extra-remote-environments": z.ZodArray<z.ZodString, "many">;
11
12
  "extra-local-environments": z.ZodArray<z.ZodString, "many">;
12
13
  }, "strip", z.ZodTypeAny, {
@@ -17,6 +18,7 @@ export declare const constFileSchema: z.ZodObject<{
17
18
  "extra-local-environments": string[];
18
19
  "image-versions-to-keep"?: number | undefined;
19
20
  "registry-image-path-prefix"?: string | undefined;
21
+ "cloudrun-artifact-registry-repo-path"?: string | undefined;
20
22
  }, {
21
23
  "project-name": string;
22
24
  infra: "hetzner" | "digitalocean" | "gcloud";
@@ -25,6 +27,7 @@ export declare const constFileSchema: z.ZodObject<{
25
27
  "extra-local-environments": string[];
26
28
  "image-versions-to-keep"?: number | undefined;
27
29
  "registry-image-path-prefix"?: string | undefined;
30
+ "cloudrun-artifact-registry-repo-path"?: string | undefined;
28
31
  }>;
29
32
  export type ConstFileSchema = z.infer<typeof constFileSchema>;
30
33
  declare const singleTemplateSchema: z.ZodObject<{
@@ -42,22 +45,25 @@ declare const singleImageSchema: z.ZodObject<{
42
45
  "image-template": z.ZodString;
43
46
  language: z.ZodEnum<["python", "node"]>;
44
47
  domains: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
45
- "debug-template": z.ZodString;
48
+ "debug-template": z.ZodOptional<z.ZodString>;
49
+ cloudrun: z.ZodOptional<z.ZodBoolean>;
46
50
  "can-db-migrate": z.ZodOptional<z.ZodBoolean>;
47
51
  applications: z.ZodArray<z.ZodString, "many">;
48
52
  }, "strip", z.ZodTypeAny, {
49
53
  "image-template": string;
50
54
  language: "python" | "node";
51
- "debug-template": string;
52
55
  applications: string[];
53
56
  domains?: Record<string, string> | undefined;
57
+ "debug-template"?: string | undefined;
58
+ cloudrun?: boolean | undefined;
54
59
  "can-db-migrate"?: boolean | undefined;
55
60
  }, {
56
61
  "image-template": string;
57
62
  language: "python" | "node";
58
- "debug-template": string;
59
63
  applications: string[];
60
64
  domains?: Record<string, string> | undefined;
65
+ "debug-template"?: string | undefined;
66
+ cloudrun?: boolean | undefined;
61
67
  "can-db-migrate"?: boolean | undefined;
62
68
  }>;
63
69
  export type SingleImageSchema = z.infer<typeof singleImageSchema>;
@@ -76,22 +82,25 @@ export declare const imageFileSchema: z.ZodObject<{
76
82
  "image-template": z.ZodString;
77
83
  language: z.ZodEnum<["python", "node"]>;
78
84
  domains: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
79
- "debug-template": z.ZodString;
85
+ "debug-template": z.ZodOptional<z.ZodString>;
86
+ cloudrun: z.ZodOptional<z.ZodBoolean>;
80
87
  "can-db-migrate": z.ZodOptional<z.ZodBoolean>;
81
88
  applications: z.ZodArray<z.ZodString, "many">;
82
89
  }, "strip", z.ZodTypeAny, {
83
90
  "image-template": string;
84
91
  language: "python" | "node";
85
- "debug-template": string;
86
92
  applications: string[];
87
93
  domains?: Record<string, string> | undefined;
94
+ "debug-template"?: string | undefined;
95
+ cloudrun?: boolean | undefined;
88
96
  "can-db-migrate"?: boolean | undefined;
89
97
  }, {
90
98
  "image-template": string;
91
99
  language: "python" | "node";
92
- "debug-template": string;
93
100
  applications: string[];
94
101
  domains?: Record<string, string> | undefined;
102
+ "debug-template"?: string | undefined;
103
+ cloudrun?: boolean | undefined;
95
104
  "can-db-migrate"?: boolean | undefined;
96
105
  }>>;
97
106
  }, "strip", z.ZodTypeAny, {
@@ -102,9 +111,10 @@ export declare const imageFileSchema: z.ZodObject<{
102
111
  images: Record<string, {
103
112
  "image-template": string;
104
113
  language: "python" | "node";
105
- "debug-template": string;
106
114
  applications: string[];
107
115
  domains?: Record<string, string> | undefined;
116
+ "debug-template"?: string | undefined;
117
+ cloudrun?: boolean | undefined;
108
118
  "can-db-migrate"?: boolean | undefined;
109
119
  }>;
110
120
  }, {
@@ -115,9 +125,10 @@ export declare const imageFileSchema: z.ZodObject<{
115
125
  images: Record<string, {
116
126
  "image-template": string;
117
127
  language: "python" | "node";
118
- "debug-template": string;
119
128
  applications: string[];
120
129
  domains?: Record<string, string> | undefined;
130
+ "debug-template"?: string | undefined;
131
+ cloudrun?: boolean | undefined;
121
132
  "can-db-migrate"?: boolean | undefined;
122
133
  }>;
123
134
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,7 @@ export const constFileSchema = z.object({
7
7
  "image-versions-to-keep": z.number().optional(),
8
8
  "registry-base-url": z.string(),
9
9
  "registry-image-path-prefix": z.string().optional(),
10
+ "cloudrun-artifact-registry-repo-path": z.string().optional(),
10
11
  "extra-remote-environments": z.array(z.string()),
11
12
  "extra-local-environments": z.array(z.string()),
12
13
  });
@@ -18,7 +19,8 @@ const singleImageSchema = z.object({
18
19
  "image-template": z.string(),
19
20
  "language": z.enum(SUPPORTED_LANGUAGES),
20
21
  "domains": z.record(z.string()).optional(),
21
- "debug-template": z.string(),
22
+ "debug-template": z.string().optional(),
23
+ "cloudrun": z.boolean().optional(),
22
24
  "can-db-migrate": z.boolean().optional(),
23
25
  applications: z.array(z.string()),
24
26
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vaharoni/devops",
3
3
  "type": "module",
4
- "version": "1.1.6",
4
+ "version": "1.1.8",
5
5
  "description": "Devops utility",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
@@ -0,0 +1,133 @@
1
+ import { CLICommandParser, printUsageAndExit, StrongParams } from "./common";
2
+ import { buildDev, deploy } from "../libs/cloudrun-helpers";
3
+
4
+ const oneLiner =
5
+ "Supports cloudrun images";
6
+ const keyExamples = `
7
+ $ devops cloudrun deploy cloudrun-image SHA --env staging --region us-central1 [--forward-env ENV1,ENV2 --allow-unauthenticated]
8
+ $ devops cloudrun build-dev cloudrun-image
9
+ `.trim();
10
+
11
+ const usage = `
12
+ ${oneLiner}
13
+
14
+ USAGE
15
+ Configuration prerequisites:
16
+ - The image should be defined in images.yaml with:
17
+ cloudrun: true
18
+ - The artifact registry URL should be set in config/constants.yaml:
19
+ cloudrun-artifact-registry-repo-path: REGION-docker.pkg.dev/PROJECT_ID/REPO
20
+
21
+ Deploy a cloudrun image to Cloud Run:
22
+ devops cloudrun deploy <image> <sha> --env <env> --region <region> [options]
23
+
24
+ Options:
25
+ --forward-env ENV1,ENV2 Comma-separated env var names to forward into the service
26
+ --allow-unauthenticated Allow unauthenticated access
27
+ --cpu <cpu> CPU, e.g. 0.25, 0.5, 1
28
+ --memory <mem> Memory, e.g. 256Mi, 512Mi, 1Gi
29
+ --min-instances <n> Minimum instances
30
+ --max-instances <n> Maximum instances
31
+ --timeout <time> Request timeout, e.g. 60s
32
+ -- Pass through additional args to gcloud (e.g. -- --ingress internal)
33
+
34
+ Notes:
35
+ - The image must already be pushed to the artifact registry.
36
+ - <env> also supports local environments (e.g. development).
37
+ - For remote monorepo environments, variables specified in --forward-env that
38
+ are not present in the current process's env are fetched from the cluster.
39
+
40
+ Build a cloudrun image locally in development environment:
41
+ devops cloudrun build-dev cloudrun-image
42
+
43
+ This command builds the image locally with a random SHA and pushes it to the artifact registry.
44
+
45
+ EXAMPLES
46
+ ${keyExamples}
47
+ `;
48
+
49
+ const handlers = {
50
+ "build-dev": (opts: StrongParams) => {
51
+ buildDev(opts.required("image"));
52
+ },
53
+ _deploy: (opts: StrongParams) => {
54
+ const rawForwardEnv = opts.optional("forwardEnv");
55
+ const forwardEnv = rawForwardEnv
56
+ ? rawForwardEnv.split(",").map(v => v.trim()).filter(Boolean)
57
+ : [];
58
+ const minInstancesStr = opts.optional("minInstances");
59
+ const maxInstancesStr = opts.optional("maxInstances");
60
+
61
+ deploy({
62
+ image: opts.required("image"),
63
+ env: opts.required("env"),
64
+ sha: opts.required("sha"),
65
+ region: opts.required("region"),
66
+ forwardEnv,
67
+ allowUnauthenticated: opts.optional("allowUnauthenticated") === "true",
68
+ cpu: opts.optional("cpu"),
69
+ memory: opts.optional("memory"),
70
+ minInstances: minInstancesStr ? Number(minInstancesStr) : undefined,
71
+ maxInstances: maxInstancesStr ? Number(maxInstancesStr) : undefined,
72
+ timeout: opts.optional("timeout"),
73
+ extraArgs: opts.optional("extraArgs"),
74
+ });
75
+ },
76
+ } as const;
77
+
78
+ async function run(cmdObj: CLICommandParser) {
79
+ if (cmdObj.help || cmdObj.args.length === 0) printUsageAndExit(usage);
80
+ const parsed = cmdObj.parseOptions({
81
+ params: [
82
+ "--keep-last",
83
+ "--forward-env",
84
+ "--region",
85
+ "--cpu",
86
+ "--memory",
87
+ "--min-instances",
88
+ "--max-instances",
89
+ "--timeout",
90
+ "--sha",
91
+ ],
92
+ booleans: ["--allow-unauthenticated"],
93
+ passthroughArgs: true,
94
+ });
95
+ const [subcommand, image, sha] = parsed.args;
96
+
97
+ // Inject env variables as forwarding is needed
98
+ if (subcommand === "deploy") {
99
+ cmdObj.executorFromEnv(
100
+ `devops cloudrun _deploy ${cmdObj.args.slice(1).join(" ")}`,
101
+ { checkEnvYaml: false }
102
+ ).spawn();
103
+ return;
104
+ }
105
+
106
+ const handler = handlers[subcommand as keyof typeof handlers];
107
+ if (!handler) {
108
+ console.error(`Unknown subcommand: ${subcommand}`);
109
+ printUsageAndExit(usage);
110
+ }
111
+
112
+ const params = new StrongParams(usage, {
113
+ env: cmdObj.env,
114
+ subcommand,
115
+ image,
116
+ sha,
117
+ keepLast: parsed.options["--keep-last"],
118
+ forwardEnv: parsed.options["--forward-env"],
119
+ region: parsed.options["--region"],
120
+ allowUnauthenticated: parsed.options["--allow-unauthenticated"] ? "true" : undefined,
121
+ cpu: parsed.options["--cpu"],
122
+ memory: parsed.options["--memory"],
123
+ minInstances: parsed.options["--min-instances"],
124
+ maxInstances: parsed.options["--max-instances"],
125
+ timeout: parsed.options["--timeout"],
126
+ extraArgs: parsed.passthrough ? parsed.passthrough.join(" ") : undefined,
127
+ });
128
+ handler(params);
129
+ }
130
+
131
+ export default {
132
+ cloudrun: { oneLiner, keyExamples, run },
133
+ };
package/src/cli/common.ts CHANGED
@@ -4,10 +4,10 @@ import fs from "fs";
4
4
  import { globSync } from "glob";
5
5
  import { allSupportedEnvs } from "../libs/k8s-constants";
6
6
 
7
- type ParsedArgs = {
7
+ type ParsedArgs<TBoolKeys extends readonly string[], TParamKeys extends readonly string[]> = {
8
8
  args: string[];
9
9
  argsStr: string;
10
- options: { [key: string]: string | boolean };
10
+ options: Partial<Record<TBoolKeys[number], true>> & Partial<Record<TParamKeys[number], string>>;
11
11
  passthrough?: string[];
12
12
  };
13
13
 
@@ -27,8 +27,8 @@ export class CLICommandParser {
27
27
 
28
28
  constructor(cmdArray: string[]) {
29
29
  const parsedArgs = this._separateOptions(cmdArray.filter(Boolean), {
30
- params: ["--env"],
31
- booleans: ["--help", "--skip-env-check"],
30
+ params: ["--env"] as const,
31
+ booleans: ["--help", "--skip-env-check"] as const,
32
32
  });
33
33
  const [command, ...args] = parsedArgs.args;
34
34
  this.command = command;
@@ -67,18 +67,18 @@ export class CLICommandParser {
67
67
  // # => { args: ['arg1'], options: { '--some-flag': true, '--in': 'workspace' } }
68
68
  //
69
69
  // Note that the global param --env is already extracted and can be accessed with cmd.env
70
- parseOptions({
71
- params = [],
72
- booleans = [],
70
+ parseOptions<const TBoolKeys extends readonly string[], const TParamKeys extends readonly string[]>({
71
+ params,
72
+ booleans,
73
73
  passthroughArgs = false,
74
74
  }: {
75
75
  /** Param is used like so: --param value */
76
- params?: string[];
76
+ params?: TParamKeys
77
77
  /** Boolean flag is used like so: --flag */
78
- booleans?: string[];
78
+ booleans?: TBoolKeys;
79
79
  /** Pass through args are used like so: -- arg1 arg2 */
80
80
  passthroughArgs?: boolean;
81
- } = {}): ParsedArgs {
81
+ } = {}): ParsedArgs<TBoolKeys, TParamKeys> {
82
82
  return this._separateOptions(this.args, {
83
83
  params,
84
84
  booleans,
@@ -97,46 +97,54 @@ export class CLICommandParser {
97
97
  return true;
98
98
  }
99
99
 
100
- _separateOptions(
100
+ _separateOptions<const TBoolKeys extends readonly string[], const TParamKeys extends readonly string[]>(
101
101
  args: string[],
102
102
  {
103
- params = [],
104
- booleans = [],
103
+ params,
104
+ booleans,
105
105
  passthroughArgs = false,
106
106
  }: {
107
- params?: string[];
108
- booleans?: string[];
107
+ params?: TParamKeys;
108
+ booleans?: TBoolKeys;
109
109
  passthroughArgs?: boolean;
110
110
  } = {}
111
- ): ParsedArgs {
112
- const results: ParsedArgs = {
113
- args: [],
114
- argsStr: "",
115
- options: {},
116
- ...(passthroughArgs ? { passthrough: [] } : {}),
117
- };
118
- const paramsLookup = Object.fromEntries(params.map((x) => [x, true]));
119
- const booleansLookup = Object.fromEntries(booleans.map((x) => [x, true]));
111
+ ): ParsedArgs<TBoolKeys, TParamKeys> {
112
+ const paramsLookup = new Set<TParamKeys[number]>(params ?? []);
113
+ const booleansLookup = new Set<TBoolKeys[number]>(booleans ?? []);
114
+ const isParam = (arg: string): arg is TParamKeys[number] => paramsLookup.has(arg);
115
+ const isBoolean = (arg: string): arg is TBoolKeys[number] => booleansLookup.has(arg);
116
+
120
117
  const passthroughArgsStart = passthroughArgs ? args.indexOf("--") : -1;
121
- const numArgsToProcess =
122
- passthroughArgsStart === -1 ? args.length : passthroughArgsStart;
118
+ // prettier-ignore
119
+ const numArgsToProcess = passthroughArgsStart === -1 ? args.length : passthroughArgsStart;
120
+
121
+ const getResPassthrough = () => {
122
+ if (!passthroughArgs || passthroughArgsStart < 0) return { passthrough: []};
123
+ return { passthrough: args.slice(passthroughArgsStart + 1) };
124
+ }
125
+
126
+ const resArgs: string[] = [];
127
+ const resParams: Partial<Record<TParamKeys[number], string>> = {};
128
+ const resOptions: Partial<Record<TBoolKeys[number], true>> = {};
129
+
123
130
  for (let i = 0; i < numArgsToProcess; ++i) {
124
131
  const curr = args[i];
125
- if (paramsLookup[curr]) {
132
+ if (isParam(curr)) {
126
133
  const next = args[i + 1];
127
- results.options[curr] = next;
134
+ resParams[curr] = next;
128
135
  ++i;
129
- } else if (booleansLookup[curr]) {
130
- results.options[curr] = true;
136
+ } else if (isBoolean(curr)) {
137
+ resOptions[curr] = true;
131
138
  } else {
132
- results.args.push(curr);
139
+ resArgs.push(curr);
133
140
  }
134
141
  }
135
- results.argsStr = results.args.join(" ");
136
- if (passthroughArgs && passthroughArgsStart >= 0) {
137
- results.passthrough = args.slice(passthroughArgsStart + 1);
138
- }
139
- return results;
142
+ return {
143
+ args: resArgs,
144
+ argsStr: resArgs.join(" "),
145
+ options: { ...resOptions, ...resParams },
146
+ ...getResPassthrough(),
147
+ };
140
148
  }
141
149
  }
142
150
 
@@ -220,10 +228,10 @@ export class CommandExecutor {
220
228
  const envToUse = this._getProcessEnv(env);
221
229
  return new Promise((resolve) => {
222
230
  try {
223
- const [cmd, ...args] = fullCommand.split(" ").filter(Boolean);
224
- const childProcess = spawn(cmd, args, {
231
+ const childProcess = spawn(fullCommand, {
225
232
  stdio: "inherit",
226
233
  env: envToUse,
234
+ shell: true,
227
235
  });
228
236
 
229
237
  childProcess.on("close", (code) => {
package/src/cli/db.ts CHANGED
@@ -114,7 +114,7 @@ function run(cmdObj: CLICommandParser) {
114
114
  const parsed = cmdObj.parseOptions({ params: ["-p"] });
115
115
 
116
116
  const [command, namespace] = parsed.args;
117
- const port = parsed.options["-p"] as string;
117
+ const port = parsed.options["-p"];
118
118
  // @ts-expect-error left as an exercise for the reader
119
119
  const handler = handlers[command];
120
120
  if (!handler) {
package/src/cli/dml.ts CHANGED
@@ -107,7 +107,7 @@ function run(cmdObj: CLICommandParser) {
107
107
  });
108
108
  switch (parsed.args[0]) {
109
109
  case "create": {
110
- const name = parsed.options["--name"] as string;
110
+ const name = parsed.options["--name"];
111
111
  if (!name) printUsageAndExit(usage);
112
112
  return createDml(name);
113
113
  }
package/src/cli/env.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { globSync } from "glob";
2
2
  import {
3
3
  deleteMonorepoSecret,
4
- getMonorepoSecret,
4
+ getMonorepoSecretStr,
5
5
  setMonorepoSecret,
6
6
  } from "../libs/k8s-secrets-manager";
7
7
  import { CombinedEnvValidator } from "../libs/validate-env";
@@ -62,7 +62,7 @@ function run(cmdObj: CLICommandParser) {
62
62
  }
63
63
 
64
64
  case "get": {
65
- console.log(getMonorepoSecret(cmdObj.env, rest));
65
+ console.log(getMonorepoSecretStr(cmdObj.env, rest));
66
66
  break;
67
67
  }
68
68
 
package/src/cli/exec.ts CHANGED
@@ -32,7 +32,7 @@ function run(cmdObj: CLICommandParser) {
32
32
  params: ["--in"],
33
33
  booleans: ["--interactive"],
34
34
  });
35
- const workspace = parsed.options["--in"] as string | undefined;
35
+ const workspace = parsed.options["--in"];
36
36
  let executor: CommandExecutor;
37
37
  if (workspace) {
38
38
  const rootPath = getWorkspace(workspace).rootPath;
package/src/cli/job.ts CHANGED
@@ -65,7 +65,7 @@ function run(cmdObj: CLICommandParser) {
65
65
  printUsageAndExit(usage);
66
66
  }
67
67
 
68
- const timeout = parsedArgs.options["--timeout"] as string | undefined;
68
+ const timeout = parsedArgs.options["--timeout"];
69
69
  const params = new StrongParams(usage, {
70
70
  env: cmdObj.env,
71
71
  image,