@vaharoni/devops 1.0.52 → 1.1.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.
@@ -1,6 +1,6 @@
1
1
  import { getConst, getImageData } from "../libs/config";
2
2
  import { prune } from "../libs/digital-ocean/container-reg";
3
- import { containerRegistryPath, containerRegistryRepoName, containerRegistryRepoPath, } from "../libs/k8s-constants";
3
+ import { containerRegistryPath, containerRegistryImageName, containerRegistryRepoPath, } from "../libs/k8s-constants";
4
4
  import { CLICommandParser, StrongParams, printUsageAndExit } from "./common";
5
5
  const oneLiner = "Manage container repositories";
6
6
  const keyExamples = `
@@ -36,7 +36,7 @@ const handlers = {
36
36
  },
37
37
  prune: (opts) => {
38
38
  const regName = containerRegistryPath();
39
- const repoName = containerRegistryRepoName(opts.required("image"), opts.required("env"));
39
+ const repoName = containerRegistryImageName(opts.required("image"), opts.required("env"));
40
40
  prune(regName, repoName);
41
41
  },
42
42
  };
@@ -4,7 +4,7 @@ export declare function envToNamespace(monorepoEnv?: string): string;
4
4
  export declare function secretName(): string;
5
5
  export declare function imageDebugName(image: string): string;
6
6
  export declare function imageConfigMap(image: string): string;
7
- export declare function containerRegistryRepoName(image: string, monorepoEnv: string): string;
7
+ export declare function containerRegistryImageName(image: string, monorepoEnv: string): string;
8
8
  export declare function containerRegistryPath(): string;
9
9
  export declare function containerRegistryRepoPath(image: string, monorepoEnv: string, gitSha: string): string;
10
10
  export declare function domainNameForEnv(image: string, monorepoEnv: string): string;
@@ -1 +1 @@
1
- {"version":3,"file":"k8s-constants.d.ts","sourceRoot":"","sources":["../../src/libs/k8s-constants.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,wBAAwB,6BAA6B,CAAA;AAoBlE,wBAAgB,gBAAgB,aAE/B;AAYD,wBAAgB,cAAc,CAAC,WAAW,CAAC,EAAE,MAAM,UAGlD;AAED,wBAAgB,UAAU,WAEzB;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,UAE3C;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,UAE3C;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,UAG3E;AAED,wBAAgB,qBAAqB,WAEpC;AAED,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,UAOf;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,UAIlE;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,UAE9C"}
1
+ {"version":3,"file":"k8s-constants.d.ts","sourceRoot":"","sources":["../../src/libs/k8s-constants.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,wBAAwB,6BAA6B,CAAA;AAoBlE,wBAAgB,gBAAgB,aAE/B;AAYD,wBAAgB,cAAc,CAAC,WAAW,CAAC,EAAE,MAAM,UAGlD;AAED,wBAAgB,UAAU,WAEzB;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,UAE3C;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,UAE3C;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,UAG5E;AAED,wBAAgB,qBAAqB,WAEpC;AAED,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,UAOf;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,UAIlE;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,UAE9C"}
@@ -42,19 +42,19 @@ export function imageDebugName(image) {
42
42
  export function imageConfigMap(image) {
43
43
  return `image-config-${image}`;
44
44
  }
45
- export function containerRegistryRepoName(image, monorepoEnv) {
45
+ export function containerRegistryImageName(image, monorepoEnv) {
46
46
  validateEnv(monorepoEnv);
47
47
  return `${getConst("project-name")}-${monorepoEnv}-${image}`;
48
48
  }
49
49
  export function containerRegistryPath() {
50
- return [getConst("registry-base-url"), getConst("registry-name")].join("/");
50
+ return [getConst("registry-base-url"), getConst("registry-image-path-prefix", { ignoreIfInvalid: true })].filter(Boolean).join("/");
51
51
  }
52
52
  export function containerRegistryRepoPath(image, monorepoEnv, gitSha) {
53
53
  return [
54
54
  getConst("registry-base-url"),
55
- getConst("registry-name"),
56
- [containerRegistryRepoName(image, monorepoEnv), gitSha].join(":"),
57
- ].join("/");
55
+ getConst("registry-image-path-prefix", { ignoreIfInvalid: true }),
56
+ [containerRegistryImageName(image, monorepoEnv), gitSha].join(":"),
57
+ ].filter(Boolean).join("/");
58
58
  }
59
59
  export function domainNameForEnv(image, monorepoEnv) {
60
60
  const imageData = getImageData(image);
@@ -3,28 +3,28 @@ export declare const SUPPORTED_LANGUAGES: readonly ["python", "node"];
3
3
  export type SupportedLanguages = typeof SUPPORTED_LANGUAGES[number];
4
4
  export declare const constFileSchema: z.ZodObject<{
5
5
  "project-name": z.ZodString;
6
- infra: z.ZodEnum<["hetzner", "digitalocean"]>;
7
- "image-versions-to-keep": z.ZodNumber;
6
+ infra: z.ZodEnum<["hetzner", "digitalocean", "gcloud"]>;
7
+ "image-versions-to-keep": z.ZodOptional<z.ZodNumber>;
8
8
  "registry-base-url": z.ZodString;
9
- "registry-name": z.ZodString;
9
+ "registry-image-path-prefix": z.ZodOptional<z.ZodString>;
10
10
  "extra-remote-environments": z.ZodArray<z.ZodString, "many">;
11
11
  "extra-local-environments": z.ZodArray<z.ZodString, "many">;
12
12
  }, "strip", z.ZodTypeAny, {
13
13
  "project-name": string;
14
- infra: "hetzner" | "digitalocean";
15
- "image-versions-to-keep": number;
14
+ infra: "hetzner" | "digitalocean" | "gcloud";
16
15
  "registry-base-url": string;
17
- "registry-name": string;
18
16
  "extra-remote-environments": string[];
19
17
  "extra-local-environments": string[];
18
+ "image-versions-to-keep"?: number | undefined;
19
+ "registry-image-path-prefix"?: string | undefined;
20
20
  }, {
21
21
  "project-name": string;
22
- infra: "hetzner" | "digitalocean";
23
- "image-versions-to-keep": number;
22
+ infra: "hetzner" | "digitalocean" | "gcloud";
24
23
  "registry-base-url": string;
25
- "registry-name": string;
26
24
  "extra-remote-environments": string[];
27
25
  "extra-local-environments": string[];
26
+ "image-versions-to-keep"?: number | undefined;
27
+ "registry-image-path-prefix"?: string | undefined;
28
28
  }>;
29
29
  export type ConstFileSchema = z.infer<typeof constFileSchema>;
30
30
  declare const singleTemplateSchema: z.ZodObject<{
@@ -3,10 +3,10 @@ export const SUPPORTED_LANGUAGES = ["python", "node"];
3
3
  // Config files
4
4
  export const constFileSchema = z.object({
5
5
  "project-name": z.string(),
6
- "infra": z.enum(["hetzner", "digitalocean"]),
7
- "image-versions-to-keep": z.number(),
6
+ "infra": z.enum(["hetzner", "digitalocean", "gcloud"]),
7
+ "image-versions-to-keep": z.number().optional(),
8
8
  "registry-base-url": z.string(),
9
- "registry-name": z.string(),
9
+ "registry-image-path-prefix": z.string().optional(),
10
10
  "extra-remote-environments": z.array(z.string()),
11
11
  "extra-local-environments": z.array(z.string()),
12
12
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vaharoni/devops",
3
3
  "type": "module",
4
- "version": "1.0.52",
4
+ "version": "1.1.1",
5
5
  "description": "Devops utility",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
@@ -2,7 +2,7 @@ import { getConst, getImageData } from "../libs/config";
2
2
  import { prune } from "../libs/digital-ocean/container-reg";
3
3
  import {
4
4
  containerRegistryPath,
5
- containerRegistryRepoName,
5
+ containerRegistryImageName,
6
6
  containerRegistryRepoPath,
7
7
  } from "../libs/k8s-constants";
8
8
  import { CLICommandParser, StrongParams, printUsageAndExit } from "./common";
@@ -49,7 +49,7 @@ const handlers = {
49
49
  },
50
50
  prune: (opts: StrongParams) => {
51
51
  const regName = containerRegistryPath();
52
- const repoName = containerRegistryRepoName(
52
+ const repoName = containerRegistryImageName(
53
53
  opts.required("image"),
54
54
  opts.required("env")
55
55
  );
@@ -51,13 +51,13 @@ export function imageConfigMap(image: string) {
51
51
  return `image-config-${image}`;
52
52
  }
53
53
 
54
- export function containerRegistryRepoName(image: string, monorepoEnv: string) {
54
+ export function containerRegistryImageName(image: string, monorepoEnv: string) {
55
55
  validateEnv(monorepoEnv);
56
56
  return `${getConst("project-name")}-${monorepoEnv}-${image}`;
57
57
  }
58
58
 
59
59
  export function containerRegistryPath() {
60
- return [getConst("registry-base-url"), getConst("registry-name")].join("/");
60
+ return [getConst("registry-base-url"), getConst("registry-image-path-prefix", { ignoreIfInvalid: true })].filter(Boolean).join("/");
61
61
  }
62
62
 
63
63
  export function containerRegistryRepoPath(
@@ -67,9 +67,9 @@ export function containerRegistryRepoPath(
67
67
  ) {
68
68
  return [
69
69
  getConst("registry-base-url"),
70
- getConst("registry-name"),
71
- [containerRegistryRepoName(image, monorepoEnv), gitSha].join(":"),
72
- ].join("/");
70
+ getConst("registry-image-path-prefix", { ignoreIfInvalid: true }),
71
+ [containerRegistryImageName(image, monorepoEnv), gitSha].join(":"),
72
+ ].filter(Boolean).join("/");
73
73
  }
74
74
 
75
75
  export function domainNameForEnv(image: string, monorepoEnv: string) {
@@ -1,14 +1,15 @@
1
1
  # These will be used when generating kubernetes entities
2
2
  project-name: changeme
3
3
 
4
- # Supported: hetzner or digitalocean
4
+ # Supported: hetzner, digitalocean, or gcloud
5
5
  infra: hetzner
6
6
 
7
7
  # Only relevant for Digital Ocean. Determines the number of versions to keep for each docker image.
8
8
  image-versions-to-keep: 5
9
9
 
10
10
  registry-base-url: registry.staging.com
11
- registry-name: changeme
11
+ # What comes before <image-name>:<tag>. Can be empty.
12
+ registry-image-path-prefix: changeme
12
13
 
13
14
  # production and staging are supported by default
14
15
  extra-remote-environments: []
@@ -48,6 +48,7 @@ spec:
48
48
  resources:
49
49
  requests:
50
50
  memory: 250Mi
51
+ cpu: 100m
51
52
  restartPolicy: Never
52
53
  {{#unless @last}}
53
54
  ---
@@ -37,6 +37,7 @@ spec:
37
37
  resources:
38
38
  requests:
39
39
  memory: 100Mi
40
+ cpu: 250m
40
41
  restartPolicy: Never
41
42
  backoffLimit: 0
42
43
  ttlSecondsAfterFinished: 3600
@@ -42,3 +42,4 @@ spec:
42
42
  resources:
43
43
  requests:
44
44
  memory: 250Mi
45
+ cpu: 100m
@@ -45,3 +45,4 @@ spec:
45
45
  resources:
46
46
  requests:
47
47
  memory: 250Mi
48
+ cpu: 250m
@@ -51,3 +51,4 @@ spec:
51
51
  resources:
52
52
  requests:
53
53
  memory: 250Mi
54
+ cpu: 250m
@@ -56,6 +56,7 @@ spec:
56
56
  resources:
57
57
  requests:
58
58
  memory: 250Mi
59
+ cpu: 250m
59
60
  {{#unless @last}}
60
61
  ---
61
62
  {{/unless}}
@@ -0,0 +1,43 @@
1
+ name: "Connect to Google Cloud GKE"
2
+ description: "Sets up kubernetes connection to Google Cloud and ensures connection"
3
+ inputs:
4
+ project_id:
5
+ description: "Google Cloud project ID"
6
+ required: true
7
+ zone:
8
+ description: "Google Cloud GKE zone (e.g., us-central1)"
9
+ required: true
10
+ cluster_name:
11
+ description: "Google Cloud GKE cluster name"
12
+ required: true
13
+ service_account_key:
14
+ description: "Google Cloud service account key in JSON format"
15
+ required: true
16
+ runs:
17
+ using: "composite"
18
+ steps:
19
+ - name: Authenticate to Google Cloud
20
+ uses: google-github-actions/auth@v2
21
+ with:
22
+ project_id: ${{ inputs.project_id }}
23
+ credentials_json: ${{ inputs.service_account_key }}
24
+
25
+ - name: Install gcloud
26
+ uses: google-github-actions/setup-gcloud@v2
27
+ with:
28
+ project_id: ${{ inputs.project_id }}
29
+
30
+ - name: Configure Docker auth
31
+ shell: bash
32
+ run: gcloud --quiet auth configure-docker
33
+
34
+ - name: Fetch GKE credentials
35
+ uses: google-github-actions/get-gke-credentials@v2
36
+ with:
37
+ cluster_name: ${{ inputs.cluster_name }}
38
+ location: ${{ inputs.zone }}
39
+ project_id: ${{ inputs.project_id }}
40
+
41
+ - name: verify namepsace exists
42
+ run: devops namespace check --env ${{ github.ref_name }}
43
+ shell: bash
@@ -16,6 +16,18 @@ inputs:
16
16
  harbor_password:
17
17
  description: "The password for the harbor registry"
18
18
  required: false
19
+ gcloud_project_id:
20
+ description: "Google Cloud project ID"
21
+ required: false
22
+ gcloud_zone:
23
+ description: "Google Cloud GKE zone (e.g., us-central1)"
24
+ required: false
25
+ gcloud_cluster_name:
26
+ description: "Google Cloud GKE cluster name"
27
+ required: false
28
+ service_account_key:
29
+ description: "Google Cloud service account key in JSON format"
30
+ required: false
19
31
  outputs:
20
32
  infra:
21
33
  description: "Which infrastructure is being used"
@@ -43,4 +55,13 @@ runs:
43
55
  with:
44
56
  kubeconfig: ${{ inputs.hetzner_kubeconfig }}
45
57
  harbor_user: ${{ inputs.harbor_user }}
46
- harbor_password: ${{ inputs.harbor_password }}
58
+ harbor_password: ${{ inputs.harbor_password }}
59
+
60
+ - name: Connect to Google Cloud GKE
61
+ if: steps.determine_infrastructure.outputs.infra == 'gcloud'
62
+ uses: ./.github/actions/connect-to-gke@v1
63
+ with:
64
+ project_id: ${{ inputs.gcloud_project_id }}
65
+ zone: ${{ inputs.gcloud_zone }}
66
+ cluster_name: ${{ inputs.gcloud_cluster_name }}
67
+ service_account_key: ${{ inputs.service_account_key }}
@@ -37,6 +37,10 @@ jobs:
37
37
  hetzner_kubeconfig: ${{ secrets.HCLOUD_KUBECONFIG }}
38
38
  harbor_user: ${{ secrets.HARBOR_USER }}
39
39
  harbor_password: ${{ secrets.HARBOR_PASSWORD }}
40
+ gcloud_project_id: ${{ secrets.GCLOUD_PROJECT_ID }}
41
+ gcloud_zone: ${{ secrets.GCLOUD_ZONE }}
42
+ gcloud_cluster_name: ${{ secrets.GCLOUD_CLUSTER_NAME }}
43
+ service_account_key: ${{ secrets.GCLOUD_SA_KEY }}
40
44
 
41
45
  - name: Build image
42
46
  uses: ./.github/actions/build-image@v1
@@ -65,6 +69,10 @@ jobs:
65
69
  hetzner_kubeconfig: ${{ secrets.HCLOUD_KUBECONFIG }}
66
70
  harbor_user: ${{ secrets.HARBOR_USER }}
67
71
  harbor_password: ${{ secrets.HARBOR_PASSWORD }}
72
+ gcloud_project_id: ${{ secrets.GCLOUD_PROJECT_ID }}
73
+ gcloud_zone: ${{ secrets.GCLOUD_ZONE }}
74
+ gcloud_cluster_name: ${{ secrets.GCLOUD_CLUSTER_NAME }}
75
+ service_account_key: ${{ secrets.GCLOUD_SA_KEY }}
68
76
 
69
77
  - name: Run DB Migrate
70
78
  uses: ./.github/actions/db-migrate@v1
@@ -7,10 +7,10 @@ export type SupportedLanguages = typeof SUPPORTED_LANGUAGES[number];
7
7
 
8
8
  export const constFileSchema = z.object({
9
9
  "project-name": z.string(),
10
- "infra": z.enum(["hetzner", "digitalocean"]),
11
- "image-versions-to-keep": z.number(),
10
+ "infra": z.enum(["hetzner", "digitalocean", "gcloud"]),
11
+ "image-versions-to-keep": z.number().optional(),
12
12
  "registry-base-url": z.string(),
13
- "registry-name": z.string(),
13
+ "registry-image-path-prefix": z.string().optional(),
14
14
  "extra-remote-environments": z.array(z.string()),
15
15
  "extra-local-environments": z.array(z.string()),
16
16
  })