@vaharoni/devops 1.2.17 → 1.3.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.
- package/dist/{chunk-RZ46YYZZ.js → chunk-HXGGJIAS.js} +1 -1
- package/dist/{chunk-N7EX3HJH.js → chunk-N2NFRGJO.js} +1 -1
- package/dist/{chunk-WKP7EQNU.js → chunk-OFUEFG64.js} +1 -1
- package/dist/devops.js +22 -22
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/plugins.js +2 -2
- package/dist/src/target-templates/infra-variants/digitalocean/.devops/config/constants.yaml +2 -2
- package/dist/src/target-templates/infra-variants/digitalocean/.github/workflows/k8s-build.yaml +14 -4
- package/dist/src/target-templates/infra-variants/gcloud/.devops/config/constants.yaml +2 -2
- package/dist/src/target-templates/infra-variants/gcloud/.github/workflows/k8s-build.yaml +18 -4
- package/dist/src/target-templates/infra-variants/hetzner/.devops/config/constants.yaml +2 -2
- package/dist/src/target-templates/infra-variants/hetzner/.github/workflows/k8s-build.yaml +12 -4
- package/{src/target-templates/lang-variants-common/typescript/.github/actions/connect-to-digital-ocean@v1 → dist/src/target-templates/lang-variants-common/typescript/.github/actions/k8s/connect-to-digitalocean-k8s@v1}/action.yaml +4 -8
- package/dist/src/target-templates/lang-variants-common/typescript/.github/actions/{connect-to-gke@v1 → k8s/connect-to-gke@v1}/action.yaml +5 -9
- package/dist/src/target-templates/lang-variants-common/typescript/.github/actions/k8s/connect-to-hetzner-k8s@v1/action.yaml +19 -0
- package/dist/src/target-templates/lang-variants-common/typescript/.github/actions/registry/connect-to-artifact-registry@v1/action.yaml +29 -0
- package/dist/src/target-templates/lang-variants-common/typescript/.github/actions/registry/connect-to-docr@v1/action.yaml +17 -0
- package/dist/src/target-templates/lang-variants-common/typescript/.github/actions/registry/connect-to-harbor@v1/action.yaml +24 -0
- package/package.json +1 -1
- package/src/cli/core/constant.ts +1 -1
- package/src/cli/core/init.ts +16 -15
- package/src/cli/core/registry.ts +1 -1
- package/src/libs/digital-ocean/container-reg.ts +2 -2
- package/src/libs/hetzner/reg-secret.ts +2 -2
- package/src/target-templates/infra-variants/digitalocean/.devops/config/constants.yaml +2 -2
- package/src/target-templates/infra-variants/digitalocean/.github/workflows/k8s-build.yaml +14 -4
- package/src/target-templates/infra-variants/gcloud/.devops/config/constants.yaml +2 -2
- package/src/target-templates/infra-variants/gcloud/.github/workflows/k8s-build.yaml +18 -4
- package/src/target-templates/infra-variants/hetzner/.devops/config/constants.yaml +2 -2
- package/src/target-templates/infra-variants/hetzner/.github/workflows/k8s-build.yaml +12 -4
- package/{dist/src/target-templates/lang-variants-common/typescript/.github/actions/connect-to-digital-ocean@v1 → src/target-templates/lang-variants-common/typescript/.github/actions/k8s/connect-to-digitalocean-k8s@v1}/action.yaml +4 -8
- package/src/target-templates/lang-variants-common/typescript/.github/actions/{connect-to-gke@v1 → k8s/connect-to-gke@v1}/action.yaml +5 -9
- package/src/target-templates/lang-variants-common/typescript/.github/actions/k8s/connect-to-hetzner-k8s@v1/action.yaml +19 -0
- package/src/target-templates/lang-variants-common/typescript/.github/actions/registry/connect-to-artifact-registry@v1/action.yaml +29 -0
- package/src/target-templates/lang-variants-common/typescript/.github/actions/registry/connect-to-docr@v1/action.yaml +17 -0
- package/src/target-templates/lang-variants-common/typescript/.github/actions/registry/connect-to-harbor@v1/action.yaml +24 -0
- package/src/types/index.ts +1 -1
- package/dist/src/target-templates/lang-variants-common/typescript/.github/actions/connect-to-hetzner@v1/action.yaml +0 -31
- package/src/target-templates/lang-variants-common/typescript/.github/actions/connect-to-hetzner@v1/action.yaml +0 -31
|
@@ -9,7 +9,7 @@ import { z } from "zod";
|
|
|
9
9
|
var SUPPORTED_LANGUAGES = ["python", "node"];
|
|
10
10
|
var constFileSchema = z.object({
|
|
11
11
|
"project-name": z.string(),
|
|
12
|
-
"infra": z.enum(["
|
|
12
|
+
"registry-infra": z.enum(["digitalocean", "gcp", "harbor"]),
|
|
13
13
|
"image-versions-to-keep": z.number().optional(),
|
|
14
14
|
"registry-base-url": z.string(),
|
|
15
15
|
"registry-image-path-prefix": z.string().optional(),
|
package/dist/devops.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
import {
|
|
3
3
|
InternalToken
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-N2NFRGJO.js";
|
|
5
5
|
import {
|
|
6
6
|
CLICommandParser,
|
|
7
7
|
CommandExecutor,
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
printUsageAndExit,
|
|
25
25
|
secretName,
|
|
26
26
|
upsertConfigMapCommand
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-OFUEFG64.js";
|
|
28
28
|
import {
|
|
29
29
|
IGNORED_PATHS,
|
|
30
30
|
__export,
|
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
getWorkspace,
|
|
37
37
|
globEnvYamlFiles,
|
|
38
38
|
workspaceDirectoryForLanguage
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-HXGGJIAS.js";
|
|
40
40
|
|
|
41
41
|
// src/devops.ts
|
|
42
42
|
import { globSync as globSync2 } from "glob";
|
|
@@ -1103,7 +1103,7 @@ var consoleCommand = { command: "console", oneLiner: oneLiner6, keyExamples: key
|
|
|
1103
1103
|
|
|
1104
1104
|
// src/cli/core/constant.ts
|
|
1105
1105
|
var oneLiner7 = "Prints to stdout a constant from constant.yaml";
|
|
1106
|
-
var keyExamples7 = `$ devops constant infra`;
|
|
1106
|
+
var keyExamples7 = `$ devops constant registry-infra`;
|
|
1107
1107
|
var usage7 = `
|
|
1108
1108
|
${oneLiner7}
|
|
1109
1109
|
|
|
@@ -1741,12 +1741,12 @@ async function createFiles() {
|
|
|
1741
1741
|
}
|
|
1742
1742
|
tc.enableSubtitution(".devops/config/images.yaml");
|
|
1743
1743
|
tc.setMessageGenerator(".envrc", envrcMessage);
|
|
1744
|
-
const gitIgnore = gitIgnoreContent(userChoices.
|
|
1744
|
+
const gitIgnore = gitIgnoreContent(userChoices.infraPreset, userChoices.usePython);
|
|
1745
1745
|
tc.addGeneratedFile(".gitignore", gitIgnore);
|
|
1746
1746
|
tc.setMessageGenerator(".gitignore", gitignoreMessageGen(gitIgnore));
|
|
1747
|
-
tc.addCopiedFolder(`infra-variants/${userChoices.
|
|
1747
|
+
tc.addCopiedFolder(`infra-variants/${userChoices.infraPreset}`, ".");
|
|
1748
1748
|
tc.enableSubtitution(".devops/config/constants.yaml");
|
|
1749
|
-
if (userChoices.
|
|
1749
|
+
if (userChoices.infraPreset === "hetzner") {
|
|
1750
1750
|
tc.enableSubtitution(".devops/infra/hetzner/harbor-cert.yaml");
|
|
1751
1751
|
tc.enableSubtitution(".devops/infra/hetzner/harbor-values.yaml");
|
|
1752
1752
|
tc.enableSubtitution(".devops/infra/hetzner/hcloud-config.yaml");
|
|
@@ -1804,12 +1804,12 @@ function packageJsonMessage(usePrisma) {
|
|
|
1804
1804
|
"applications/**"${prismaMessage}
|
|
1805
1805
|
],`)}`;
|
|
1806
1806
|
}
|
|
1807
|
-
function gitIgnoreContent(
|
|
1807
|
+
function gitIgnoreContent(infraPreset, usePython) {
|
|
1808
1808
|
const common = `**/.env*
|
|
1809
1809
|
config/kubeconfig
|
|
1810
1810
|
tmp/**
|
|
1811
1811
|
!tmp/**/.gitkeep`;
|
|
1812
|
-
const gcloud =
|
|
1812
|
+
const gcloud = infraPreset === "gcloud" ? "config/gke_gcloud_auth_plugin_cache" : null;
|
|
1813
1813
|
const python = usePython ? `venv/
|
|
1814
1814
|
**/__pycache__` : null;
|
|
1815
1815
|
return [common, gcloud, python].filter(Boolean).join("\n");
|
|
@@ -1854,12 +1854,12 @@ function getUserChoices(projectName) {
|
|
|
1854
1854
|
},
|
|
1855
1855
|
{
|
|
1856
1856
|
type: "list",
|
|
1857
|
-
name: "
|
|
1858
|
-
message: "
|
|
1857
|
+
name: "infraPreset",
|
|
1858
|
+
message: "Select your infrastructure preset:",
|
|
1859
1859
|
choices: [
|
|
1860
|
-
{ name: "Google Cloud", value: "gcloud" },
|
|
1861
|
-
{ name: "Digital Ocean", value: "digitalocean" },
|
|
1862
|
-
{ name: "Hetzner", value: "hetzner" }
|
|
1860
|
+
{ name: "Google Cloud (GKE + GCP Registry)", value: "gcloud" },
|
|
1861
|
+
{ name: "Digital Ocean (DO K8s + DO Registry)", value: "digitalocean" },
|
|
1862
|
+
{ name: "Hetzner (Hetzner K8s + Harbor)", value: "hetzner" }
|
|
1863
1863
|
]
|
|
1864
1864
|
},
|
|
1865
1865
|
{
|
|
@@ -1867,21 +1867,21 @@ function getUserChoices(projectName) {
|
|
|
1867
1867
|
name: "gcloudProjectId",
|
|
1868
1868
|
message: "Enter the GCP project ID (default: 'changeme')",
|
|
1869
1869
|
default: "changeme",
|
|
1870
|
-
when: (answers) => answers.
|
|
1870
|
+
when: (answers) => answers.infraPreset === "gcloud"
|
|
1871
1871
|
},
|
|
1872
1872
|
{
|
|
1873
1873
|
type: "input",
|
|
1874
1874
|
name: "registryImagePathPrefix",
|
|
1875
1875
|
message: (answers) => `Enter your Digital Ocean container registry name (default: '${answers.projectName}')`,
|
|
1876
1876
|
default: (answers) => answers.projectName,
|
|
1877
|
-
when: (answers) => answers.
|
|
1877
|
+
when: (answers) => answers.infraPreset === "digitalocean"
|
|
1878
1878
|
},
|
|
1879
1879
|
{
|
|
1880
1880
|
type: "input",
|
|
1881
1881
|
name: "registryBaseUrl",
|
|
1882
1882
|
message: (answers) => `Enter your registry base URL (default: 'registry.${answers.stagingDomain}')`,
|
|
1883
1883
|
default: (answers) => `registry.${answers.stagingDomain}`,
|
|
1884
|
-
when: (answers) => answers.
|
|
1884
|
+
when: (answers) => answers.infraPreset === "hetzner"
|
|
1885
1885
|
},
|
|
1886
1886
|
{
|
|
1887
1887
|
type: "confirm",
|
|
@@ -2069,8 +2069,8 @@ var job = { oneLiner: oneLiner11, keyExamples: keyExamples11, run: run11 };
|
|
|
2069
2069
|
|
|
2070
2070
|
// src/libs/hetzner/reg-secret.ts
|
|
2071
2071
|
function isApplicable() {
|
|
2072
|
-
const
|
|
2073
|
-
if (
|
|
2072
|
+
const registryInfra = getConst("registry-infra");
|
|
2073
|
+
if (registryInfra !== "harbor") {
|
|
2074
2074
|
console.warn(
|
|
2075
2075
|
"Setting up registry permissions is only needed for Harbor in a Hetzner setup"
|
|
2076
2076
|
);
|
|
@@ -2322,8 +2322,8 @@ function stargGarbageCollection(registryName) {
|
|
|
2322
2322
|
new CommandExecutor(cmd).exec();
|
|
2323
2323
|
}
|
|
2324
2324
|
function prune(registryFullName, repoName, image2) {
|
|
2325
|
-
const
|
|
2326
|
-
if (
|
|
2325
|
+
const registryInfra = getConst("registry-infra");
|
|
2326
|
+
if (registryInfra !== "digitalocean") {
|
|
2327
2327
|
console.warn(
|
|
2328
2328
|
"Pruning is only supported for the DigitalOcean container registry"
|
|
2329
2329
|
);
|
|
@@ -2375,7 +2375,7 @@ USAGE
|
|
|
2375
2375
|
Prunes the repository of old images to enforce the "image-versions-to-keep" constant in config/constants.yaml:
|
|
2376
2376
|
devops registry prune <image> --env <env>
|
|
2377
2377
|
|
|
2378
|
-
This is only relevant when the "infra" constant is set to "digitalocean".
|
|
2378
|
+
This is only relevant when the "registry-infra" constant is set to "digitalocean".
|
|
2379
2379
|
|
|
2380
2380
|
EXAMPLES
|
|
2381
2381
|
${keyExamples14}
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ declare const SUPPORTED_LANGUAGES: readonly ["python", "node"];
|
|
|
4
4
|
type SupportedLanguages = typeof SUPPORTED_LANGUAGES[number];
|
|
5
5
|
declare const constFileSchema: z.ZodObject<{
|
|
6
6
|
"project-name": z.ZodString;
|
|
7
|
-
infra: z.ZodEnum<["
|
|
7
|
+
"registry-infra": z.ZodEnum<["digitalocean", "gcp", "harbor"]>;
|
|
8
8
|
"image-versions-to-keep": z.ZodOptional<z.ZodNumber>;
|
|
9
9
|
"registry-base-url": z.ZodString;
|
|
10
10
|
"registry-image-path-prefix": z.ZodOptional<z.ZodString>;
|
|
@@ -14,7 +14,7 @@ declare const constFileSchema: z.ZodObject<{
|
|
|
14
14
|
extensions: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
15
15
|
}, "strip", z.ZodTypeAny, {
|
|
16
16
|
"project-name": string;
|
|
17
|
-
infra: "
|
|
17
|
+
"registry-infra": "digitalocean" | "gcp" | "harbor";
|
|
18
18
|
"registry-base-url": string;
|
|
19
19
|
"extra-remote-environments": string[];
|
|
20
20
|
"extra-local-environments": string[];
|
|
@@ -24,7 +24,7 @@ declare const constFileSchema: z.ZodObject<{
|
|
|
24
24
|
extensions?: string[] | undefined;
|
|
25
25
|
}, {
|
|
26
26
|
"project-name": string;
|
|
27
|
-
infra: "
|
|
27
|
+
"registry-infra": "digitalocean" | "gcp" | "harbor";
|
|
28
28
|
"registry-base-url": string;
|
|
29
29
|
"extra-remote-environments": string[];
|
|
30
30
|
"extra-local-environments": string[];
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
InternalToken,
|
|
3
3
|
decryptAes256Gcm,
|
|
4
4
|
encryptAes256Gcm
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-N2NFRGJO.js";
|
|
6
6
|
import {
|
|
7
7
|
SUPPORTED_LANGUAGES,
|
|
8
8
|
constFileSchema,
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
packageFileNodeSchema,
|
|
11
11
|
packageFilePythonSchema,
|
|
12
12
|
workspaces
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-HXGGJIAS.js";
|
|
14
14
|
|
|
15
15
|
// src/app-support/discovery/dev-discovery-loader.ts
|
|
16
16
|
var _portLookupByServiceName = null;
|
package/dist/plugins.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# These will be used when generating kubernetes entities
|
|
2
2
|
project-name: $PROJECT_NAME
|
|
3
3
|
|
|
4
|
-
#
|
|
5
|
-
infra: digitalocean
|
|
4
|
+
# Registry infrastructure: digitalocean, gcp, or harbor
|
|
5
|
+
registry-infra: digitalocean
|
|
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
|
package/dist/src/target-templates/infra-variants/digitalocean/.github/workflows/k8s-build.yaml
CHANGED
|
@@ -31,12 +31,17 @@ jobs:
|
|
|
31
31
|
- name: Setup prerequesites
|
|
32
32
|
uses: ./.github/actions/setup-prereq@v1
|
|
33
33
|
|
|
34
|
-
- name: Connect to
|
|
35
|
-
uses: ./.github/actions/connect-to-
|
|
34
|
+
- name: Connect to DigitalOcean K8s
|
|
35
|
+
uses: ./.github/actions/k8s/connect-to-digitalocean-k8s@v1
|
|
36
36
|
with:
|
|
37
37
|
access_token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
|
|
38
38
|
cluster_name: ${{ secrets.DIGITALOCEAN_CLUSTER_NAME }}
|
|
39
39
|
|
|
40
|
+
- name: Connect to DOCR
|
|
41
|
+
uses: ./.github/actions/registry/connect-to-docr@v1
|
|
42
|
+
with:
|
|
43
|
+
access_token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
|
|
44
|
+
|
|
40
45
|
# For deploying images to Cloud Run
|
|
41
46
|
# - name: Connect to Cloud Run
|
|
42
47
|
# uses: ./.github/actions/connect-to-cloud-run@v1
|
|
@@ -64,12 +69,17 @@ jobs:
|
|
|
64
69
|
- name: Setup prerequesites
|
|
65
70
|
uses: ./.github/actions/setup-prereq@v1
|
|
66
71
|
|
|
67
|
-
- name: Connect to
|
|
68
|
-
uses: ./.github/actions/connect-to-
|
|
72
|
+
- name: Connect to DigitalOcean K8s
|
|
73
|
+
uses: ./.github/actions/k8s/connect-to-digitalocean-k8s@v1
|
|
69
74
|
with:
|
|
70
75
|
access_token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
|
|
71
76
|
cluster_name: ${{ secrets.DIGITALOCEAN_CLUSTER_NAME }}
|
|
72
77
|
|
|
78
|
+
- name: Connect to DOCR
|
|
79
|
+
uses: ./.github/actions/registry/connect-to-docr@v1
|
|
80
|
+
with:
|
|
81
|
+
access_token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
|
|
82
|
+
|
|
73
83
|
# For deploying images to Cloud Run
|
|
74
84
|
# - name: Connect to Cloud Run
|
|
75
85
|
# uses: ./.github/actions/connect-to-cloud-run@v1
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# These will be used when generating kubernetes entities
|
|
2
2
|
project-name: $PROJECT_NAME
|
|
3
3
|
|
|
4
|
-
#
|
|
5
|
-
infra:
|
|
4
|
+
# Registry infrastructure: digitalocean, gcp, or harbor
|
|
5
|
+
registry-infra: gcp
|
|
6
6
|
|
|
7
7
|
registry-base-url: gcr.io
|
|
8
8
|
# What comes before <image-name>:<tag>. Can be empty.
|
|
@@ -31,14 +31,21 @@ jobs:
|
|
|
31
31
|
- name: Setup prerequesites
|
|
32
32
|
uses: ./.github/actions/setup-prereq@v1
|
|
33
33
|
|
|
34
|
-
- name: Connect to
|
|
35
|
-
uses: ./.github/actions/connect-to-gke@v1
|
|
34
|
+
- name: Connect to GKE
|
|
35
|
+
uses: ./.github/actions/k8s/connect-to-gke@v1
|
|
36
36
|
with:
|
|
37
37
|
project_id: ${{ secrets.GCLOUD_PROJECT_ID }}
|
|
38
38
|
zone: ${{ secrets.GCLOUD_ZONE }}
|
|
39
39
|
cluster_name: ${{ secrets.GCLOUD_CLUSTER_NAME }}
|
|
40
40
|
service_account_key: ${{ secrets.GCLOUD_SA_KEY }}
|
|
41
41
|
|
|
42
|
+
- name: Connect to Artifact Registry
|
|
43
|
+
uses: ./.github/actions/registry/connect-to-artifact-registry@v1
|
|
44
|
+
with:
|
|
45
|
+
service_account_key: ${{ secrets.GCLOUD_SA_KEY }}
|
|
46
|
+
project_id: ${{ secrets.GCLOUD_PROJECT_ID }}
|
|
47
|
+
region: ${{ secrets.GCLOUD_ARTIFACT_REGISTRY_REGION }}
|
|
48
|
+
|
|
42
49
|
# For deploying images to Cloud Run
|
|
43
50
|
# - name: Connect to Cloud Run
|
|
44
51
|
# uses: ./.github/actions/connect-to-cloud-run@v1
|
|
@@ -66,14 +73,21 @@ jobs:
|
|
|
66
73
|
- name: Setup prerequesites
|
|
67
74
|
uses: ./.github/actions/setup-prereq@v1
|
|
68
75
|
|
|
69
|
-
- name: Connect to
|
|
70
|
-
uses: ./.github/actions/connect-to-gke@v1
|
|
76
|
+
- name: Connect to GKE
|
|
77
|
+
uses: ./.github/actions/k8s/connect-to-gke@v1
|
|
71
78
|
with:
|
|
72
79
|
project_id: ${{ secrets.GCLOUD_PROJECT_ID }}
|
|
73
80
|
zone: ${{ secrets.GCLOUD_ZONE }}
|
|
74
81
|
cluster_name: ${{ secrets.GCLOUD_CLUSTER_NAME }}
|
|
75
82
|
service_account_key: ${{ secrets.GCLOUD_SA_KEY }}
|
|
76
83
|
|
|
84
|
+
- name: Connect to Artifact Registry
|
|
85
|
+
uses: ./.github/actions/registry/connect-to-artifact-registry@v1
|
|
86
|
+
with:
|
|
87
|
+
service_account_key: ${{ secrets.GCLOUD_SA_KEY }}
|
|
88
|
+
project_id: ${{ secrets.GCLOUD_PROJECT_ID }}
|
|
89
|
+
region: ${{ secrets.GCLOUD_ARTIFACT_REGISTRY_REGION }}
|
|
90
|
+
|
|
77
91
|
# For deploying images to Cloud Run
|
|
78
92
|
# - name: Connect to Cloud Run
|
|
79
93
|
# uses: ./.github/actions/connect-to-cloud-run@v1
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# These will be used when generating kubernetes entities
|
|
2
2
|
project-name: $PROJECT_NAME
|
|
3
3
|
|
|
4
|
-
#
|
|
5
|
-
infra:
|
|
4
|
+
# Registry infrastructure: digitalocean, gcp, or harbor
|
|
5
|
+
registry-infra: harbor
|
|
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
|
|
@@ -31,10 +31,14 @@ jobs:
|
|
|
31
31
|
- name: Setup prerequesites
|
|
32
32
|
uses: ./.github/actions/setup-prereq@v1
|
|
33
33
|
|
|
34
|
-
- name: Connect to Hetzner
|
|
35
|
-
uses: ./.github/actions/connect-to-hetzner@v1
|
|
34
|
+
- name: Connect to Hetzner K8s
|
|
35
|
+
uses: ./.github/actions/k8s/connect-to-hetzner-k8s@v1
|
|
36
36
|
with:
|
|
37
37
|
kubeconfig: ${{ secrets.HCLOUD_KUBECONFIG }}
|
|
38
|
+
|
|
39
|
+
- name: Connect to Harbor Registry
|
|
40
|
+
uses: ./.github/actions/registry/connect-to-harbor@v1
|
|
41
|
+
with:
|
|
38
42
|
harbor_user: ${{ secrets.HARBOR_USER }}
|
|
39
43
|
harbor_password: ${{ secrets.HARBOR_PASSWORD }}
|
|
40
44
|
|
|
@@ -65,10 +69,14 @@ jobs:
|
|
|
65
69
|
- name: Setup prerequesites
|
|
66
70
|
uses: ./.github/actions/setup-prereq@v1
|
|
67
71
|
|
|
68
|
-
- name: Connect to Hetzner
|
|
69
|
-
uses: ./.github/actions/connect-to-hetzner@v1
|
|
72
|
+
- name: Connect to Hetzner K8s
|
|
73
|
+
uses: ./.github/actions/k8s/connect-to-hetzner-k8s@v1
|
|
70
74
|
with:
|
|
71
75
|
kubeconfig: ${{ secrets.HCLOUD_KUBECONFIG }}
|
|
76
|
+
|
|
77
|
+
- name: Connect to Harbor Registry
|
|
78
|
+
uses: ./.github/actions/registry/connect-to-harbor@v1
|
|
79
|
+
with:
|
|
72
80
|
harbor_user: ${{ secrets.HARBOR_USER }}
|
|
73
81
|
harbor_password: ${{ secrets.HARBOR_PASSWORD }}
|
|
74
82
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
name: "Connect to
|
|
2
|
-
description: "Sets up kubernetes connection to
|
|
1
|
+
name: "Connect to DigitalOcean K8s"
|
|
2
|
+
description: "Sets up kubernetes connection to DigitalOcean cluster"
|
|
3
3
|
inputs:
|
|
4
4
|
access_token:
|
|
5
5
|
description: "DigitalOcean access token"
|
|
@@ -15,15 +15,11 @@ runs:
|
|
|
15
15
|
with:
|
|
16
16
|
token: ${{ inputs.access_token }}
|
|
17
17
|
|
|
18
|
-
- name: Log in to DigitalOcean Container Registry with short-lived credentials
|
|
19
|
-
run: doctl registry login --expiry-seconds 1200
|
|
20
|
-
shell: bash
|
|
21
|
-
|
|
22
18
|
- name: Save DigitalOcean kubeconfig with short-lived credentials
|
|
23
|
-
run: |
|
|
19
|
+
run: |
|
|
24
20
|
doctl kubernetes cluster kubeconfig save --expiry-seconds 1200 ${{ inputs.cluster_name }}
|
|
25
21
|
shell: bash
|
|
26
22
|
|
|
27
|
-
- name:
|
|
23
|
+
- name: Verify namespace exists
|
|
28
24
|
run: devops namespace check --env ${{ github.ref_name }}
|
|
29
25
|
shell: bash
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
name: "Connect to
|
|
2
|
-
description: "Sets up kubernetes connection to Google
|
|
1
|
+
name: "Connect to GKE"
|
|
2
|
+
description: "Sets up kubernetes connection to Google Kubernetes Engine cluster"
|
|
3
3
|
inputs:
|
|
4
4
|
project_id:
|
|
5
5
|
description: "Google Cloud project ID"
|
|
@@ -25,19 +25,15 @@ runs:
|
|
|
25
25
|
- name: Install gcloud
|
|
26
26
|
uses: google-github-actions/setup-gcloud@v2
|
|
27
27
|
with:
|
|
28
|
-
project_id: ${{ inputs.project_id }}
|
|
29
|
-
|
|
30
|
-
- name: Configure Docker auth
|
|
31
|
-
shell: bash
|
|
32
|
-
run: gcloud --quiet auth configure-docker
|
|
28
|
+
project_id: ${{ inputs.project_id }}
|
|
33
29
|
|
|
34
30
|
- name: Fetch GKE credentials
|
|
35
31
|
uses: google-github-actions/get-gke-credentials@v2
|
|
36
32
|
with:
|
|
37
33
|
cluster_name: ${{ inputs.cluster_name }}
|
|
38
34
|
location: ${{ inputs.zone }}
|
|
39
|
-
project_id: ${{ inputs.project_id }}
|
|
35
|
+
project_id: ${{ inputs.project_id }}
|
|
40
36
|
|
|
41
|
-
- name:
|
|
37
|
+
- name: Verify namespace exists
|
|
42
38
|
run: devops namespace check --env ${{ github.ref_name }}
|
|
43
39
|
shell: bash
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
name: "Connect to Hetzner K8s"
|
|
2
|
+
description: "Sets up kubernetes connection to Hetzner cluster"
|
|
3
|
+
inputs:
|
|
4
|
+
kubeconfig:
|
|
5
|
+
description: "The Hetzner kubeconfig file"
|
|
6
|
+
required: true
|
|
7
|
+
runs:
|
|
8
|
+
using: "composite"
|
|
9
|
+
steps:
|
|
10
|
+
- name: Create a kubeconfig file
|
|
11
|
+
run: |
|
|
12
|
+
mkdir -p ~/.kube
|
|
13
|
+
echo "${{ inputs.kubeconfig }}" > ~/.kube/config
|
|
14
|
+
chmod 600 ~/.kube/config
|
|
15
|
+
shell: bash
|
|
16
|
+
|
|
17
|
+
- name: Verify cluster connection and that namespace exists
|
|
18
|
+
run: devops namespace check --env ${{ github.ref_name }}
|
|
19
|
+
shell: bash
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: "Connect to Artifact Registry"
|
|
2
|
+
description: "Authenticates to Google Artifact Registry"
|
|
3
|
+
inputs:
|
|
4
|
+
service_account_key:
|
|
5
|
+
description: "Google Cloud service account key in JSON format"
|
|
6
|
+
required: true
|
|
7
|
+
project_id:
|
|
8
|
+
description: "Google Cloud project ID"
|
|
9
|
+
required: true
|
|
10
|
+
region:
|
|
11
|
+
description: "Google Cloud Artifact Registry region (e.g., us-central1)"
|
|
12
|
+
required: true
|
|
13
|
+
runs:
|
|
14
|
+
using: "composite"
|
|
15
|
+
steps:
|
|
16
|
+
- name: Authenticate to Google Cloud
|
|
17
|
+
uses: google-github-actions/auth@v2
|
|
18
|
+
with:
|
|
19
|
+
project_id: ${{ inputs.project_id }}
|
|
20
|
+
credentials_json: ${{ inputs.service_account_key }}
|
|
21
|
+
|
|
22
|
+
- name: Install gcloud
|
|
23
|
+
uses: google-github-actions/setup-gcloud@v2
|
|
24
|
+
with:
|
|
25
|
+
project_id: ${{ inputs.project_id }}
|
|
26
|
+
|
|
27
|
+
- name: Configure Docker auth for Artifact Registry
|
|
28
|
+
shell: bash
|
|
29
|
+
run: gcloud --quiet auth configure-docker ${{ inputs.region }}-docker.pkg.dev
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
name: "Connect to DOCR"
|
|
2
|
+
description: "Authenticates to DigitalOcean Container Registry"
|
|
3
|
+
inputs:
|
|
4
|
+
access_token:
|
|
5
|
+
description: "DigitalOcean access token"
|
|
6
|
+
required: true
|
|
7
|
+
runs:
|
|
8
|
+
using: "composite"
|
|
9
|
+
steps:
|
|
10
|
+
- name: Install doctl
|
|
11
|
+
uses: digitalocean/action-doctl@v2
|
|
12
|
+
with:
|
|
13
|
+
token: ${{ inputs.access_token }}
|
|
14
|
+
|
|
15
|
+
- name: Log in to DigitalOcean Container Registry with short-lived credentials
|
|
16
|
+
run: doctl registry login --expiry-seconds 1200
|
|
17
|
+
shell: bash
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: "Connect to Harbor Registry"
|
|
2
|
+
description: "Authenticates to Harbor container registry"
|
|
3
|
+
inputs:
|
|
4
|
+
harbor_user:
|
|
5
|
+
description: "The user name for the harbor registry"
|
|
6
|
+
required: true
|
|
7
|
+
harbor_password:
|
|
8
|
+
description: "The password for the harbor registry"
|
|
9
|
+
required: true
|
|
10
|
+
harbor_url:
|
|
11
|
+
description: "The harbor registry URL (optional, uses devops registry server-url if not provided)"
|
|
12
|
+
required: false
|
|
13
|
+
runs:
|
|
14
|
+
using: "composite"
|
|
15
|
+
steps:
|
|
16
|
+
- name: Connect to the registry
|
|
17
|
+
run: |
|
|
18
|
+
if [ -n "${{ inputs.harbor_url }}" ]; then
|
|
19
|
+
server_url="${{ inputs.harbor_url }}"
|
|
20
|
+
else
|
|
21
|
+
server_url=$(devops registry server-url)
|
|
22
|
+
fi
|
|
23
|
+
docker login $server_url -u '${{ inputs.harbor_user }}' -p ${{ inputs.harbor_password }}
|
|
24
|
+
shell: bash
|
package/package.json
CHANGED
package/src/cli/core/constant.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { getConst } from "../../libs/config";
|
|
|
2
2
|
import { CLICommandParser, printUsageAndExit } from "../common";
|
|
3
3
|
|
|
4
4
|
const oneLiner = "Prints to stdout a constant from constant.yaml";
|
|
5
|
-
const keyExamples = `$ devops constant infra`;
|
|
5
|
+
const keyExamples = `$ devops constant registry-infra`;
|
|
6
6
|
|
|
7
7
|
const usage = `
|
|
8
8
|
${oneLiner}
|
package/src/cli/core/init.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { InitGenerator, type InitGeneratorFileInfo } from "../../libs/init-gener
|
|
|
3
3
|
import { CLICommandParser, printUsageAndExit } from "../common";
|
|
4
4
|
import chalk from "chalk";
|
|
5
5
|
import fs from 'fs-extra';
|
|
6
|
-
import type { ConstFileSchema } from "../../types";
|
|
7
6
|
|
|
8
7
|
const oneLiner =
|
|
9
8
|
"Initializes the devops utility by copying template files to the current folder";
|
|
@@ -40,14 +39,14 @@ async function createFiles() {
|
|
|
40
39
|
tc.setMessageGenerator(".envrc", envrcMessage);
|
|
41
40
|
|
|
42
41
|
// gitignore
|
|
43
|
-
const gitIgnore = gitIgnoreContent(userChoices.
|
|
42
|
+
const gitIgnore = gitIgnoreContent(userChoices.infraPreset, userChoices.usePython)
|
|
44
43
|
tc.addGeneratedFile(".gitignore", gitIgnore);
|
|
45
44
|
tc.setMessageGenerator(".gitignore", gitignoreMessageGen(gitIgnore));
|
|
46
45
|
|
|
47
46
|
// Infra variants
|
|
48
|
-
tc.addCopiedFolder(`infra-variants/${userChoices.
|
|
47
|
+
tc.addCopiedFolder(`infra-variants/${userChoices.infraPreset}`, ".");
|
|
49
48
|
tc.enableSubtitution(".devops/config/constants.yaml");
|
|
50
|
-
if (userChoices.
|
|
49
|
+
if (userChoices.infraPreset === "hetzner") {
|
|
51
50
|
tc.enableSubtitution(".devops/infra/hetzner/harbor-cert.yaml");
|
|
52
51
|
tc.enableSubtitution(".devops/infra/hetzner/harbor-values.yaml");
|
|
53
52
|
tc.enableSubtitution(".devops/infra/hetzner/hcloud-config.yaml");
|
|
@@ -119,13 +118,13 @@ function packageJsonMessage(usePrisma: boolean) {
|
|
|
119
118
|
],`)}`
|
|
120
119
|
}
|
|
121
120
|
|
|
122
|
-
function gitIgnoreContent(
|
|
121
|
+
function gitIgnoreContent(infraPreset: InfraPreset, usePython: boolean) {
|
|
123
122
|
const common = `**/.env*
|
|
124
123
|
config/kubeconfig
|
|
125
124
|
tmp/**
|
|
126
125
|
!tmp/**/.gitkeep`;
|
|
127
126
|
|
|
128
|
-
const gcloud =
|
|
127
|
+
const gcloud = infraPreset === 'gcloud'
|
|
129
128
|
? 'config/gke_gcloud_auth_plugin_cache'
|
|
130
129
|
: null;
|
|
131
130
|
|
|
@@ -156,11 +155,13 @@ ${chalk.yellow(content)}`;
|
|
|
156
155
|
}
|
|
157
156
|
}
|
|
158
157
|
|
|
158
|
+
type InfraPreset = "gcloud" | "digitalocean" | "hetzner";
|
|
159
|
+
|
|
159
160
|
type UserChoices = {
|
|
160
161
|
projectName: string;
|
|
161
162
|
stagingDomain: string;
|
|
162
163
|
productionDomain: string;
|
|
163
|
-
|
|
164
|
+
infraPreset: InfraPreset;
|
|
164
165
|
gcloudProjectId?: string;
|
|
165
166
|
registryImagePathPrefix?: string;
|
|
166
167
|
registryBaseUrl?: string;
|
|
@@ -193,12 +194,12 @@ function getUserChoices(projectName: string | undefined): Promise<UserChoices> {
|
|
|
193
194
|
},
|
|
194
195
|
{
|
|
195
196
|
type: "list",
|
|
196
|
-
name: "
|
|
197
|
-
message: "
|
|
197
|
+
name: "infraPreset",
|
|
198
|
+
message: "Select your infrastructure preset:",
|
|
198
199
|
choices: [
|
|
199
|
-
{ name: "Google Cloud", value: "gcloud" },
|
|
200
|
-
{ name: "Digital Ocean", value: "digitalocean" },
|
|
201
|
-
{ name: "Hetzner", value: "hetzner" },
|
|
200
|
+
{ name: "Google Cloud (GKE + GCP Registry)", value: "gcloud" },
|
|
201
|
+
{ name: "Digital Ocean (DO K8s + DO Registry)", value: "digitalocean" },
|
|
202
|
+
{ name: "Hetzner (Hetzner K8s + Harbor)", value: "hetzner" },
|
|
202
203
|
],
|
|
203
204
|
},
|
|
204
205
|
{
|
|
@@ -206,21 +207,21 @@ function getUserChoices(projectName: string | undefined): Promise<UserChoices> {
|
|
|
206
207
|
name: "gcloudProjectId",
|
|
207
208
|
message: "Enter the GCP project ID (default: 'changeme')",
|
|
208
209
|
default: "changeme",
|
|
209
|
-
when: (answers) => answers.
|
|
210
|
+
when: (answers) => answers.infraPreset === "gcloud",
|
|
210
211
|
},
|
|
211
212
|
{
|
|
212
213
|
type: "input",
|
|
213
214
|
name: "registryImagePathPrefix",
|
|
214
215
|
message: (answers) => `Enter your Digital Ocean container registry name (default: '${answers.projectName}')`,
|
|
215
216
|
default: (answers) => answers.projectName,
|
|
216
|
-
when: (answers) => answers.
|
|
217
|
+
when: (answers) => answers.infraPreset === "digitalocean",
|
|
217
218
|
},
|
|
218
219
|
{
|
|
219
220
|
type: "input",
|
|
220
221
|
name: "registryBaseUrl",
|
|
221
222
|
message: (answers) => `Enter your registry base URL (default: 'registry.${answers.stagingDomain}')`,
|
|
222
223
|
default: (answers) => `registry.${answers.stagingDomain}`,
|
|
223
|
-
when: (answers) => answers.
|
|
224
|
+
when: (answers) => answers.infraPreset === "hetzner",
|
|
224
225
|
},
|
|
225
226
|
{
|
|
226
227
|
type: "confirm",
|
package/src/cli/core/registry.ts
CHANGED
|
@@ -35,7 +35,7 @@ USAGE
|
|
|
35
35
|
Prunes the repository of old images to enforce the "image-versions-to-keep" constant in config/constants.yaml:
|
|
36
36
|
devops registry prune <image> --env <env>
|
|
37
37
|
|
|
38
|
-
This is only relevant when the "infra" constant is set to "digitalocean".
|
|
38
|
+
This is only relevant when the "registry-infra" constant is set to "digitalocean".
|
|
39
39
|
|
|
40
40
|
EXAMPLES
|
|
41
41
|
${keyExamples}
|
|
@@ -63,8 +63,8 @@ export function prune(
|
|
|
63
63
|
repoName: string,
|
|
64
64
|
image: string
|
|
65
65
|
) {
|
|
66
|
-
const
|
|
67
|
-
if (
|
|
66
|
+
const registryInfra = getConst("registry-infra");
|
|
67
|
+
if (registryInfra !== "digitalocean") {
|
|
68
68
|
console.warn(
|
|
69
69
|
"Pruning is only supported for the DigitalOcean container registry"
|
|
70
70
|
);
|
|
@@ -4,8 +4,8 @@ import { envToNamespace } from "../k8s-constants";
|
|
|
4
4
|
import { kubectlCommand } from "../k8s-helpers";
|
|
5
5
|
|
|
6
6
|
function isApplicable() {
|
|
7
|
-
const
|
|
8
|
-
if (
|
|
7
|
+
const registryInfra = getConst("registry-infra");
|
|
8
|
+
if (registryInfra !== "harbor") {
|
|
9
9
|
console.warn(
|
|
10
10
|
"Setting up registry permissions is only needed for Harbor in a Hetzner setup"
|
|
11
11
|
);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# These will be used when generating kubernetes entities
|
|
2
2
|
project-name: $PROJECT_NAME
|
|
3
3
|
|
|
4
|
-
#
|
|
5
|
-
infra: digitalocean
|
|
4
|
+
# Registry infrastructure: digitalocean, gcp, or harbor
|
|
5
|
+
registry-infra: digitalocean
|
|
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
|
|
@@ -31,12 +31,17 @@ jobs:
|
|
|
31
31
|
- name: Setup prerequesites
|
|
32
32
|
uses: ./.github/actions/setup-prereq@v1
|
|
33
33
|
|
|
34
|
-
- name: Connect to
|
|
35
|
-
uses: ./.github/actions/connect-to-
|
|
34
|
+
- name: Connect to DigitalOcean K8s
|
|
35
|
+
uses: ./.github/actions/k8s/connect-to-digitalocean-k8s@v1
|
|
36
36
|
with:
|
|
37
37
|
access_token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
|
|
38
38
|
cluster_name: ${{ secrets.DIGITALOCEAN_CLUSTER_NAME }}
|
|
39
39
|
|
|
40
|
+
- name: Connect to DOCR
|
|
41
|
+
uses: ./.github/actions/registry/connect-to-docr@v1
|
|
42
|
+
with:
|
|
43
|
+
access_token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
|
|
44
|
+
|
|
40
45
|
# For deploying images to Cloud Run
|
|
41
46
|
# - name: Connect to Cloud Run
|
|
42
47
|
# uses: ./.github/actions/connect-to-cloud-run@v1
|
|
@@ -64,12 +69,17 @@ jobs:
|
|
|
64
69
|
- name: Setup prerequesites
|
|
65
70
|
uses: ./.github/actions/setup-prereq@v1
|
|
66
71
|
|
|
67
|
-
- name: Connect to
|
|
68
|
-
uses: ./.github/actions/connect-to-
|
|
72
|
+
- name: Connect to DigitalOcean K8s
|
|
73
|
+
uses: ./.github/actions/k8s/connect-to-digitalocean-k8s@v1
|
|
69
74
|
with:
|
|
70
75
|
access_token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
|
|
71
76
|
cluster_name: ${{ secrets.DIGITALOCEAN_CLUSTER_NAME }}
|
|
72
77
|
|
|
78
|
+
- name: Connect to DOCR
|
|
79
|
+
uses: ./.github/actions/registry/connect-to-docr@v1
|
|
80
|
+
with:
|
|
81
|
+
access_token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
|
|
82
|
+
|
|
73
83
|
# For deploying images to Cloud Run
|
|
74
84
|
# - name: Connect to Cloud Run
|
|
75
85
|
# uses: ./.github/actions/connect-to-cloud-run@v1
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# These will be used when generating kubernetes entities
|
|
2
2
|
project-name: $PROJECT_NAME
|
|
3
3
|
|
|
4
|
-
#
|
|
5
|
-
infra:
|
|
4
|
+
# Registry infrastructure: digitalocean, gcp, or harbor
|
|
5
|
+
registry-infra: gcp
|
|
6
6
|
|
|
7
7
|
registry-base-url: gcr.io
|
|
8
8
|
# What comes before <image-name>:<tag>. Can be empty.
|
|
@@ -31,14 +31,21 @@ jobs:
|
|
|
31
31
|
- name: Setup prerequesites
|
|
32
32
|
uses: ./.github/actions/setup-prereq@v1
|
|
33
33
|
|
|
34
|
-
- name: Connect to
|
|
35
|
-
uses: ./.github/actions/connect-to-gke@v1
|
|
34
|
+
- name: Connect to GKE
|
|
35
|
+
uses: ./.github/actions/k8s/connect-to-gke@v1
|
|
36
36
|
with:
|
|
37
37
|
project_id: ${{ secrets.GCLOUD_PROJECT_ID }}
|
|
38
38
|
zone: ${{ secrets.GCLOUD_ZONE }}
|
|
39
39
|
cluster_name: ${{ secrets.GCLOUD_CLUSTER_NAME }}
|
|
40
40
|
service_account_key: ${{ secrets.GCLOUD_SA_KEY }}
|
|
41
41
|
|
|
42
|
+
- name: Connect to Artifact Registry
|
|
43
|
+
uses: ./.github/actions/registry/connect-to-artifact-registry@v1
|
|
44
|
+
with:
|
|
45
|
+
service_account_key: ${{ secrets.GCLOUD_SA_KEY }}
|
|
46
|
+
project_id: ${{ secrets.GCLOUD_PROJECT_ID }}
|
|
47
|
+
region: ${{ secrets.GCLOUD_ARTIFACT_REGISTRY_REGION }}
|
|
48
|
+
|
|
42
49
|
# For deploying images to Cloud Run
|
|
43
50
|
# - name: Connect to Cloud Run
|
|
44
51
|
# uses: ./.github/actions/connect-to-cloud-run@v1
|
|
@@ -66,14 +73,21 @@ jobs:
|
|
|
66
73
|
- name: Setup prerequesites
|
|
67
74
|
uses: ./.github/actions/setup-prereq@v1
|
|
68
75
|
|
|
69
|
-
- name: Connect to
|
|
70
|
-
uses: ./.github/actions/connect-to-gke@v1
|
|
76
|
+
- name: Connect to GKE
|
|
77
|
+
uses: ./.github/actions/k8s/connect-to-gke@v1
|
|
71
78
|
with:
|
|
72
79
|
project_id: ${{ secrets.GCLOUD_PROJECT_ID }}
|
|
73
80
|
zone: ${{ secrets.GCLOUD_ZONE }}
|
|
74
81
|
cluster_name: ${{ secrets.GCLOUD_CLUSTER_NAME }}
|
|
75
82
|
service_account_key: ${{ secrets.GCLOUD_SA_KEY }}
|
|
76
83
|
|
|
84
|
+
- name: Connect to Artifact Registry
|
|
85
|
+
uses: ./.github/actions/registry/connect-to-artifact-registry@v1
|
|
86
|
+
with:
|
|
87
|
+
service_account_key: ${{ secrets.GCLOUD_SA_KEY }}
|
|
88
|
+
project_id: ${{ secrets.GCLOUD_PROJECT_ID }}
|
|
89
|
+
region: ${{ secrets.GCLOUD_ARTIFACT_REGISTRY_REGION }}
|
|
90
|
+
|
|
77
91
|
# For deploying images to Cloud Run
|
|
78
92
|
# - name: Connect to Cloud Run
|
|
79
93
|
# uses: ./.github/actions/connect-to-cloud-run@v1
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# These will be used when generating kubernetes entities
|
|
2
2
|
project-name: $PROJECT_NAME
|
|
3
3
|
|
|
4
|
-
#
|
|
5
|
-
infra:
|
|
4
|
+
# Registry infrastructure: digitalocean, gcp, or harbor
|
|
5
|
+
registry-infra: harbor
|
|
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
|
|
@@ -31,10 +31,14 @@ jobs:
|
|
|
31
31
|
- name: Setup prerequesites
|
|
32
32
|
uses: ./.github/actions/setup-prereq@v1
|
|
33
33
|
|
|
34
|
-
- name: Connect to Hetzner
|
|
35
|
-
uses: ./.github/actions/connect-to-hetzner@v1
|
|
34
|
+
- name: Connect to Hetzner K8s
|
|
35
|
+
uses: ./.github/actions/k8s/connect-to-hetzner-k8s@v1
|
|
36
36
|
with:
|
|
37
37
|
kubeconfig: ${{ secrets.HCLOUD_KUBECONFIG }}
|
|
38
|
+
|
|
39
|
+
- name: Connect to Harbor Registry
|
|
40
|
+
uses: ./.github/actions/registry/connect-to-harbor@v1
|
|
41
|
+
with:
|
|
38
42
|
harbor_user: ${{ secrets.HARBOR_USER }}
|
|
39
43
|
harbor_password: ${{ secrets.HARBOR_PASSWORD }}
|
|
40
44
|
|
|
@@ -65,10 +69,14 @@ jobs:
|
|
|
65
69
|
- name: Setup prerequesites
|
|
66
70
|
uses: ./.github/actions/setup-prereq@v1
|
|
67
71
|
|
|
68
|
-
- name: Connect to Hetzner
|
|
69
|
-
uses: ./.github/actions/connect-to-hetzner@v1
|
|
72
|
+
- name: Connect to Hetzner K8s
|
|
73
|
+
uses: ./.github/actions/k8s/connect-to-hetzner-k8s@v1
|
|
70
74
|
with:
|
|
71
75
|
kubeconfig: ${{ secrets.HCLOUD_KUBECONFIG }}
|
|
76
|
+
|
|
77
|
+
- name: Connect to Harbor Registry
|
|
78
|
+
uses: ./.github/actions/registry/connect-to-harbor@v1
|
|
79
|
+
with:
|
|
72
80
|
harbor_user: ${{ secrets.HARBOR_USER }}
|
|
73
81
|
harbor_password: ${{ secrets.HARBOR_PASSWORD }}
|
|
74
82
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
name: "Connect to
|
|
2
|
-
description: "Sets up kubernetes connection to
|
|
1
|
+
name: "Connect to DigitalOcean K8s"
|
|
2
|
+
description: "Sets up kubernetes connection to DigitalOcean cluster"
|
|
3
3
|
inputs:
|
|
4
4
|
access_token:
|
|
5
5
|
description: "DigitalOcean access token"
|
|
@@ -15,15 +15,11 @@ runs:
|
|
|
15
15
|
with:
|
|
16
16
|
token: ${{ inputs.access_token }}
|
|
17
17
|
|
|
18
|
-
- name: Log in to DigitalOcean Container Registry with short-lived credentials
|
|
19
|
-
run: doctl registry login --expiry-seconds 1200
|
|
20
|
-
shell: bash
|
|
21
|
-
|
|
22
18
|
- name: Save DigitalOcean kubeconfig with short-lived credentials
|
|
23
|
-
run: |
|
|
19
|
+
run: |
|
|
24
20
|
doctl kubernetes cluster kubeconfig save --expiry-seconds 1200 ${{ inputs.cluster_name }}
|
|
25
21
|
shell: bash
|
|
26
22
|
|
|
27
|
-
- name:
|
|
23
|
+
- name: Verify namespace exists
|
|
28
24
|
run: devops namespace check --env ${{ github.ref_name }}
|
|
29
25
|
shell: bash
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
name: "Connect to
|
|
2
|
-
description: "Sets up kubernetes connection to Google
|
|
1
|
+
name: "Connect to GKE"
|
|
2
|
+
description: "Sets up kubernetes connection to Google Kubernetes Engine cluster"
|
|
3
3
|
inputs:
|
|
4
4
|
project_id:
|
|
5
5
|
description: "Google Cloud project ID"
|
|
@@ -25,19 +25,15 @@ runs:
|
|
|
25
25
|
- name: Install gcloud
|
|
26
26
|
uses: google-github-actions/setup-gcloud@v2
|
|
27
27
|
with:
|
|
28
|
-
project_id: ${{ inputs.project_id }}
|
|
29
|
-
|
|
30
|
-
- name: Configure Docker auth
|
|
31
|
-
shell: bash
|
|
32
|
-
run: gcloud --quiet auth configure-docker
|
|
28
|
+
project_id: ${{ inputs.project_id }}
|
|
33
29
|
|
|
34
30
|
- name: Fetch GKE credentials
|
|
35
31
|
uses: google-github-actions/get-gke-credentials@v2
|
|
36
32
|
with:
|
|
37
33
|
cluster_name: ${{ inputs.cluster_name }}
|
|
38
34
|
location: ${{ inputs.zone }}
|
|
39
|
-
project_id: ${{ inputs.project_id }}
|
|
35
|
+
project_id: ${{ inputs.project_id }}
|
|
40
36
|
|
|
41
|
-
- name:
|
|
37
|
+
- name: Verify namespace exists
|
|
42
38
|
run: devops namespace check --env ${{ github.ref_name }}
|
|
43
39
|
shell: bash
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
name: "Connect to Hetzner K8s"
|
|
2
|
+
description: "Sets up kubernetes connection to Hetzner cluster"
|
|
3
|
+
inputs:
|
|
4
|
+
kubeconfig:
|
|
5
|
+
description: "The Hetzner kubeconfig file"
|
|
6
|
+
required: true
|
|
7
|
+
runs:
|
|
8
|
+
using: "composite"
|
|
9
|
+
steps:
|
|
10
|
+
- name: Create a kubeconfig file
|
|
11
|
+
run: |
|
|
12
|
+
mkdir -p ~/.kube
|
|
13
|
+
echo "${{ inputs.kubeconfig }}" > ~/.kube/config
|
|
14
|
+
chmod 600 ~/.kube/config
|
|
15
|
+
shell: bash
|
|
16
|
+
|
|
17
|
+
- name: Verify cluster connection and that namespace exists
|
|
18
|
+
run: devops namespace check --env ${{ github.ref_name }}
|
|
19
|
+
shell: bash
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: "Connect to Artifact Registry"
|
|
2
|
+
description: "Authenticates to Google Artifact Registry"
|
|
3
|
+
inputs:
|
|
4
|
+
service_account_key:
|
|
5
|
+
description: "Google Cloud service account key in JSON format"
|
|
6
|
+
required: true
|
|
7
|
+
project_id:
|
|
8
|
+
description: "Google Cloud project ID"
|
|
9
|
+
required: true
|
|
10
|
+
region:
|
|
11
|
+
description: "Google Cloud Artifact Registry region (e.g., us-central1)"
|
|
12
|
+
required: true
|
|
13
|
+
runs:
|
|
14
|
+
using: "composite"
|
|
15
|
+
steps:
|
|
16
|
+
- name: Authenticate to Google Cloud
|
|
17
|
+
uses: google-github-actions/auth@v2
|
|
18
|
+
with:
|
|
19
|
+
project_id: ${{ inputs.project_id }}
|
|
20
|
+
credentials_json: ${{ inputs.service_account_key }}
|
|
21
|
+
|
|
22
|
+
- name: Install gcloud
|
|
23
|
+
uses: google-github-actions/setup-gcloud@v2
|
|
24
|
+
with:
|
|
25
|
+
project_id: ${{ inputs.project_id }}
|
|
26
|
+
|
|
27
|
+
- name: Configure Docker auth for Artifact Registry
|
|
28
|
+
shell: bash
|
|
29
|
+
run: gcloud --quiet auth configure-docker ${{ inputs.region }}-docker.pkg.dev
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
name: "Connect to DOCR"
|
|
2
|
+
description: "Authenticates to DigitalOcean Container Registry"
|
|
3
|
+
inputs:
|
|
4
|
+
access_token:
|
|
5
|
+
description: "DigitalOcean access token"
|
|
6
|
+
required: true
|
|
7
|
+
runs:
|
|
8
|
+
using: "composite"
|
|
9
|
+
steps:
|
|
10
|
+
- name: Install doctl
|
|
11
|
+
uses: digitalocean/action-doctl@v2
|
|
12
|
+
with:
|
|
13
|
+
token: ${{ inputs.access_token }}
|
|
14
|
+
|
|
15
|
+
- name: Log in to DigitalOcean Container Registry with short-lived credentials
|
|
16
|
+
run: doctl registry login --expiry-seconds 1200
|
|
17
|
+
shell: bash
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: "Connect to Harbor Registry"
|
|
2
|
+
description: "Authenticates to Harbor container registry"
|
|
3
|
+
inputs:
|
|
4
|
+
harbor_user:
|
|
5
|
+
description: "The user name for the harbor registry"
|
|
6
|
+
required: true
|
|
7
|
+
harbor_password:
|
|
8
|
+
description: "The password for the harbor registry"
|
|
9
|
+
required: true
|
|
10
|
+
harbor_url:
|
|
11
|
+
description: "The harbor registry URL (optional, uses devops registry server-url if not provided)"
|
|
12
|
+
required: false
|
|
13
|
+
runs:
|
|
14
|
+
using: "composite"
|
|
15
|
+
steps:
|
|
16
|
+
- name: Connect to the registry
|
|
17
|
+
run: |
|
|
18
|
+
if [ -n "${{ inputs.harbor_url }}" ]; then
|
|
19
|
+
server_url="${{ inputs.harbor_url }}"
|
|
20
|
+
else
|
|
21
|
+
server_url=$(devops registry server-url)
|
|
22
|
+
fi
|
|
23
|
+
docker login $server_url -u '${{ inputs.harbor_user }}' -p ${{ inputs.harbor_password }}
|
|
24
|
+
shell: bash
|
package/src/types/index.ts
CHANGED
|
@@ -7,7 +7,7 @@ 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(["
|
|
10
|
+
"registry-infra": z.enum(["digitalocean", "gcp", "harbor"]),
|
|
11
11
|
"image-versions-to-keep": z.number().optional(),
|
|
12
12
|
"registry-base-url": z.string(),
|
|
13
13
|
"registry-image-path-prefix": z.string().optional(),
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
name: "Connect to Hetzner"
|
|
2
|
-
description: "Sets up kubernetes connection to Hetzner and ensures connection"
|
|
3
|
-
inputs:
|
|
4
|
-
kubeconfig:
|
|
5
|
-
description: "The Hetzner kubeconfig file"
|
|
6
|
-
required: true
|
|
7
|
-
harbor_user:
|
|
8
|
-
description: "The user name for the harbor registry"
|
|
9
|
-
required: true
|
|
10
|
-
harbor_password:
|
|
11
|
-
description: "The password for the harbor registry"
|
|
12
|
-
required: true
|
|
13
|
-
runs:
|
|
14
|
-
using: "composite"
|
|
15
|
-
steps:
|
|
16
|
-
- name: Create a kubeconfig file
|
|
17
|
-
run: |
|
|
18
|
-
mkdir -p ~/.kube
|
|
19
|
-
echo "${{ inputs.kubeconfig }}" > ~/.kube/config
|
|
20
|
-
chmod 600 ~/.kube/config
|
|
21
|
-
shell: bash
|
|
22
|
-
|
|
23
|
-
- name: Verify cluster connection and that namepsace exists
|
|
24
|
-
run: devops namespace check --env ${{ github.ref_name }}
|
|
25
|
-
shell: bash
|
|
26
|
-
|
|
27
|
-
- name: Connect to the registry
|
|
28
|
-
run: |
|
|
29
|
-
server_url=$(devops registry server-url)
|
|
30
|
-
docker login $server_url -u '${{ inputs.harbor_user }}' -p ${{ inputs.harbor_password }}
|
|
31
|
-
shell: bash
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
name: "Connect to Hetzner"
|
|
2
|
-
description: "Sets up kubernetes connection to Hetzner and ensures connection"
|
|
3
|
-
inputs:
|
|
4
|
-
kubeconfig:
|
|
5
|
-
description: "The Hetzner kubeconfig file"
|
|
6
|
-
required: true
|
|
7
|
-
harbor_user:
|
|
8
|
-
description: "The user name for the harbor registry"
|
|
9
|
-
required: true
|
|
10
|
-
harbor_password:
|
|
11
|
-
description: "The password for the harbor registry"
|
|
12
|
-
required: true
|
|
13
|
-
runs:
|
|
14
|
-
using: "composite"
|
|
15
|
-
steps:
|
|
16
|
-
- name: Create a kubeconfig file
|
|
17
|
-
run: |
|
|
18
|
-
mkdir -p ~/.kube
|
|
19
|
-
echo "${{ inputs.kubeconfig }}" > ~/.kube/config
|
|
20
|
-
chmod 600 ~/.kube/config
|
|
21
|
-
shell: bash
|
|
22
|
-
|
|
23
|
-
- name: Verify cluster connection and that namepsace exists
|
|
24
|
-
run: devops namespace check --env ${{ github.ref_name }}
|
|
25
|
-
shell: bash
|
|
26
|
-
|
|
27
|
-
- name: Connect to the registry
|
|
28
|
-
run: |
|
|
29
|
-
server_url=$(devops registry server-url)
|
|
30
|
-
docker login $server_url -u '${{ inputs.harbor_user }}' -p ${{ inputs.harbor_password }}
|
|
31
|
-
shell: bash
|