@catladder/cli 0.0.0-refactor-untangle-gitlab-api-requests-from-vorpal-57cf3cf2 → 0.0.0-reference-database-url-1befbbee
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/bundles/catenv/index.js +2146 -23675
- package/dist/bundles/cli/index.js +575 -1032
- package/dist/cli/src/apps/cli/commands/project/commandGitlabCi.d.ts +2 -5
- package/dist/cli/src/apps/cli/commands/project/commandGitlabCi.js +9 -26
- package/dist/cli/src/apps/cli/commands/project/commandGitlabCi.js.map +1 -1
- package/dist/cli/src/apps/cli/commands/project/commandSetup.js +5 -3
- package/dist/cli/src/apps/cli/commands/project/commandSetup.js.map +1 -1
- package/dist/cli/src/apps/cli/commands/project/setup/index.d.ts +1 -1
- package/dist/cli/src/apps/cli/commands/project/setup/index.js +6 -17
- package/dist/cli/src/apps/cli/commands/project/setup/index.js.map +1 -1
- package/dist/cli/src/apps/cli/commands/project/setup/setupAccessTokens.d.ts +1 -4
- package/dist/cli/src/apps/cli/commands/project/setup/setupAccessTokens.js +23 -35
- package/dist/cli/src/apps/cli/commands/project/setup/setupAccessTokens.js.map +1 -1
- package/dist/cli/src/apps/cli/commands/project/setup/setupKubernetes.d.ts +2 -5
- package/dist/cli/src/apps/cli/commands/project/setup/setupKubernetes.js +23 -38
- package/dist/cli/src/apps/cli/commands/project/setup/setupKubernetes.js.map +1 -1
- package/dist/cli/src/apps/cli/commands/project/setup/setupTopic.d.ts +1 -2
- package/dist/cli/src/apps/cli/commands/project/setup/setupTopic.js +4 -5
- package/dist/cli/src/apps/cli/commands/project/setup/setupTopic.js.map +1 -1
- package/dist/cli/src/apps/cli/commands/project/utils/autocompletions.d.ts +1 -0
- package/dist/cli/src/apps/cli/commands/project/utils/autocompletions.js +9 -1
- package/dist/cli/src/apps/cli/commands/project/utils/autocompletions.js.map +1 -1
- package/dist/cli/src/apps/cli/utils/getGoogleAuthUserNumber.d.ts +1 -1
- package/dist/cli/src/apps/cli/utils/getGoogleAuthUserNumber.js +11 -20
- package/dist/cli/src/apps/cli/utils/getGoogleAuthUserNumber.js.map +1 -1
- package/dist/cli/src/apps/cli/verify/index.js +5 -22
- package/dist/cli/src/apps/cli/verify/index.js.map +1 -1
- package/dist/cli/src/config/getProjectConfig.d.ts +1 -1
- package/dist/cli/src/config/getProjectConfig.js +10 -12
- package/dist/cli/src/config/getProjectConfig.js.map +1 -1
- package/dist/cli/src/git/gitProjectInformation.d.ts +1 -14
- package/dist/cli/src/git/gitProjectInformation.js +2 -29
- package/dist/cli/src/git/gitProjectInformation.js.map +1 -1
- package/dist/cli/src/utils/gitlab.d.ts +23 -17
- package/dist/cli/src/utils/gitlab.js +161 -120
- package/dist/cli/src/utils/gitlab.js.map +1 -1
- package/dist/cli/src/utils/log.d.ts +0 -15
- package/dist/cli/src/utils/log.js +1 -23
- package/dist/cli/src/utils/log.js.map +1 -1
- package/dist/cli/src/utils/preferences.d.ts +4 -0
- package/dist/cli/src/utils/preferences.js +58 -0
- package/dist/cli/src/utils/preferences.js.map +1 -0
- package/dist/pipeline/src/build/artifacts/createBuildJobArtifact.js +3 -1
- package/dist/pipeline/src/build/artifacts/createBuildJobArtifact.js.map +1 -1
- package/dist/pipeline/src/build/base/index.d.ts +2 -3
- package/dist/pipeline/src/build/base/index.js.map +1 -1
- package/dist/pipeline/src/build/cache/getAllCacheConfigsFromConfig.js +6 -4
- package/dist/pipeline/src/build/cache/getAllCacheConfigsFromConfig.js.map +1 -1
- package/dist/pipeline/src/build/custom/buildJob.d.ts +2 -2
- package/dist/pipeline/src/build/custom/buildJob.js.map +1 -1
- package/dist/pipeline/src/build/custom/index.d.ts +2 -2
- package/dist/pipeline/src/build/custom/index.js.map +1 -1
- package/dist/pipeline/src/build/custom/testJob.d.ts +2 -2
- package/dist/pipeline/src/build/custom/testJob.js.map +1 -1
- package/dist/pipeline/src/build/docker.d.ts +4 -4
- package/dist/pipeline/src/build/docker.js +1 -1
- package/dist/pipeline/src/build/docker.js.map +1 -1
- package/dist/pipeline/src/build/index.d.ts +2 -2
- package/dist/pipeline/src/build/index.js +2 -3
- package/dist/pipeline/src/build/index.js.map +1 -1
- package/dist/pipeline/src/build/node/buildJob.d.ts +5 -3
- package/dist/pipeline/src/build/node/buildJob.js.map +1 -1
- package/dist/pipeline/src/build/node/index.d.ts +4 -4
- package/dist/pipeline/src/build/node/index.js.map +1 -1
- package/dist/pipeline/src/build/node/meteor.d.ts +2 -2
- package/dist/pipeline/src/build/node/meteor.js.map +1 -1
- package/dist/pipeline/src/build/node/yarn.d.ts +1 -1
- package/dist/pipeline/src/build/node/yarn.js +3 -1
- package/dist/pipeline/src/build/node/yarn.js.map +1 -1
- package/dist/pipeline/src/build/rails/build.d.ts +2 -2
- package/dist/pipeline/src/build/rails/build.js +0 -1
- package/dist/pipeline/src/build/rails/build.js.map +1 -1
- package/dist/pipeline/src/build/rails/index.d.ts +2 -2
- package/dist/pipeline/src/build/rails/index.js.map +1 -1
- package/dist/pipeline/src/build/rails/test.js +18 -1
- package/dist/pipeline/src/build/rails/test.js.map +1 -1
- package/dist/pipeline/src/build/sbom.d.ts +2 -2
- package/dist/pipeline/src/build/sbom.js +4 -1
- package/dist/pipeline/src/build/sbom.js.map +1 -1
- package/dist/pipeline/src/build/types.d.ts +8 -0
- package/dist/pipeline/src/build/types.js.map +1 -1
- package/dist/pipeline/src/context/createComponentContext.js +17 -6
- package/dist/pipeline/src/context/createComponentContext.js.map +1 -1
- package/dist/pipeline/src/context/getLabels.js +3 -1
- package/dist/pipeline/src/context/getLabels.js.map +1 -1
- package/dist/pipeline/src/deploy/cloudRun/createJobs/cloudRunJobs.js +2 -2
- package/dist/pipeline/src/deploy/cloudRun/createJobs/cloudRunJobs.js.map +1 -1
- package/dist/pipeline/src/deploy/cloudRun/createJobs/cloudRunServices.js +32 -7
- package/dist/pipeline/src/deploy/cloudRun/createJobs/cloudRunServices.js.map +1 -1
- package/dist/pipeline/src/deploy/cloudRun/createJobs/execute/onDeploy.d.ts +1 -2
- package/dist/pipeline/src/deploy/cloudRun/createJobs/execute/onDeploy.js +3 -10
- package/dist/pipeline/src/deploy/cloudRun/createJobs/execute/onDeploy.js.map +1 -1
- package/dist/pipeline/src/deploy/cloudRun/createJobs/healthCheck.d.ts +5 -0
- package/dist/pipeline/src/deploy/cloudRun/createJobs/healthCheck.js +51 -0
- package/dist/pipeline/src/deploy/cloudRun/createJobs/healthCheck.js.map +1 -0
- package/dist/pipeline/src/deploy/cloudRun/index.js +7 -4
- package/dist/pipeline/src/deploy/cloudRun/index.js.map +1 -1
- package/dist/pipeline/src/deploy/cloudRun/utils/database.d.ts +21 -2
- package/dist/pipeline/src/deploy/cloudRun/utils/database.js +55 -6
- package/dist/pipeline/src/deploy/cloudRun/utils/database.js.map +1 -1
- package/dist/pipeline/src/deploy/cloudRun/utils/getJobOrServiceArgs.d.ts +2 -0
- package/dist/pipeline/src/deploy/cloudRun/utils/getJobOrServiceArgs.js +12 -0
- package/dist/pipeline/src/deploy/cloudRun/utils/getJobOrServiceArgs.js.map +1 -0
- package/dist/pipeline/src/deploy/kubernetes/kubeValues.d.ts +2 -2
- package/dist/pipeline/src/deploy/kubernetes/kubeValues.js +3 -1
- package/dist/pipeline/src/deploy/kubernetes/kubeValues.js.map +1 -1
- package/dist/pipeline/src/deploy/sbom.js +4 -3
- package/dist/pipeline/src/deploy/sbom.js.map +1 -1
- package/dist/pipeline/src/deploy/types/googleCloudRun.d.ts +100 -0
- package/dist/pipeline/src/deploy/types/googleCloudRun.js +16 -0
- package/dist/pipeline/src/deploy/types/googleCloudRun.js.map +1 -1
- package/dist/pipeline/src/pipeline/createJobsForComponent.js +3 -1
- package/dist/pipeline/src/pipeline/createJobsForComponent.js.map +1 -1
- package/dist/pipeline/src/types/config.d.ts +1 -1
- package/dist/pipeline/src/types/context.d.ts +6 -1
- package/dist/pipeline/src/types/context.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/apps/cli/commands/project/commandGitlabCi.ts +20 -58
- package/src/apps/cli/commands/project/commandSetup.ts +5 -3
- package/src/apps/cli/commands/project/setup/index.ts +9 -19
- package/src/apps/cli/commands/project/setup/setupAccessTokens.ts +45 -62
- package/src/apps/cli/commands/project/setup/setupKubernetes.ts +32 -53
- package/src/apps/cli/commands/project/setup/setupTopic.ts +12 -17
- package/src/apps/cli/commands/project/utils/autocompletions.ts +9 -0
- package/src/apps/cli/utils/getGoogleAuthUserNumber.ts +18 -28
- package/src/apps/cli/verify/index.ts +7 -25
- package/src/config/getProjectConfig.ts +21 -22
- package/src/git/gitProjectInformation.ts +1 -31
- package/src/utils/gitlab.ts +247 -200
- package/src/utils/log.ts +0 -26
- package/src/utils/preferences.ts +60 -0
- package/dist/cli/src/utils/gitlab-without-vorpal/FetchGitLabError.d.ts +0 -18
- package/dist/cli/src/utils/gitlab-without-vorpal/FetchGitLabError.js +0 -32
- package/dist/cli/src/utils/gitlab-without-vorpal/FetchGitLabError.js.map +0 -1
- package/dist/cli/src/utils/gitlab-without-vorpal/FetchMethod.d.ts +0 -1
- package/dist/cli/src/utils/gitlab-without-vorpal/FetchMethod.js +0 -3
- package/dist/cli/src/utils/gitlab-without-vorpal/FetchMethod.js.map +0 -1
- package/dist/cli/src/utils/gitlab-without-vorpal/GitLabApiDataOptional.d.ts +0 -14
- package/dist/cli/src/utils/gitlab-without-vorpal/GitLabApiDataOptional.js +0 -3
- package/dist/cli/src/utils/gitlab-without-vorpal/GitLabApiDataOptional.js.map +0 -1
- package/dist/cli/src/utils/gitlab-without-vorpal/GitLabTokenMissingError.d.ts +0 -4
- package/dist/cli/src/utils/gitlab-without-vorpal/GitLabTokenMissingError.js +0 -12
- package/dist/cli/src/utils/gitlab-without-vorpal/GitLabTokenMissingError.js.map +0 -1
- package/dist/cli/src/utils/gitlab-without-vorpal/fetchGitLabApi.d.ts +0 -8
- package/dist/cli/src/utils/gitlab-without-vorpal/fetchGitLabApi.js +0 -47
- package/dist/cli/src/utils/gitlab-without-vorpal/fetchGitLabApi.js.map +0 -1
- package/dist/cli/src/utils/gitlab-without-vorpal/getGitlabHostPathToken.d.ts +0 -20
- package/dist/cli/src/utils/gitlab-without-vorpal/getGitlabHostPathToken.js +0 -15
- package/dist/cli/src/utils/gitlab-without-vorpal/getGitlabHostPathToken.js.map +0 -1
- package/dist/cli/src/utils/gitlab-without-vorpal/gitLabProjectByGitPath.d.ts +0 -23
- package/dist/cli/src/utils/gitlab-without-vorpal/gitLabProjectByGitPath.js +0 -30
- package/dist/cli/src/utils/gitlab-without-vorpal/gitLabProjectByGitPath.js.map +0 -1
- package/dist/cli/src/utils/gitlab-without-vorpal/gitLabVariables.d.ts +0 -66
- package/dist/cli/src/utils/gitlab-without-vorpal/gitLabVariables.js +0 -129
- package/dist/cli/src/utils/gitlab-without-vorpal/gitLabVariables.js.map +0 -1
- package/dist/cli/src/utils/gitlab-without-vorpal/index.d.ts +0 -12
- package/dist/cli/src/utils/gitlab-without-vorpal/index.js +0 -29
- package/dist/cli/src/utils/gitlab-without-vorpal/index.js.map +0 -1
- package/dist/cli/src/utils/gitlab-without-vorpal/insertProjectTopics.d.ts +0 -5
- package/dist/cli/src/utils/gitlab-without-vorpal/insertProjectTopics.js +0 -23
- package/dist/cli/src/utils/gitlab-without-vorpal/insertProjectTopics.js.map +0 -1
- package/dist/cli/src/utils/gitlab-without-vorpal/loadGitLabToken.d.ts +0 -2
- package/dist/cli/src/utils/gitlab-without-vorpal/loadGitLabToken.js +0 -27
- package/dist/cli/src/utils/gitlab-without-vorpal/loadGitLabToken.js.map +0 -1
- package/dist/cli/src/utils/gitlab-without-vorpal/projectAccessToken.d.ts +0 -29
- package/dist/cli/src/utils/gitlab-without-vorpal/projectAccessToken.js +0 -24
- package/dist/cli/src/utils/gitlab-without-vorpal/projectAccessToken.js.map +0 -1
- package/dist/cli/src/utils/gitlab-without-vorpal/storeGitLabToken.d.ts +0 -3
- package/dist/cli/src/utils/gitlab-without-vorpal/storeGitLabToken.js +0 -19
- package/dist/cli/src/utils/gitlab-without-vorpal/storeGitLabToken.js.map +0 -1
- package/dist/cli/src/utils/preferences/CatladderPreferences.d.ts +0 -27
- package/dist/cli/src/utils/preferences/CatladderPreferences.js +0 -34
- package/dist/cli/src/utils/preferences/CatladderPreferences.js.map +0 -1
- package/dist/cli/src/utils/preferences/index.d.ts +0 -11
- package/dist/cli/src/utils/preferences/index.js +0 -79
- package/dist/cli/src/utils/preferences/index.js.map +0 -1
- package/src/utils/gitlab-without-vorpal/FetchGitLabError.ts +0 -57
- package/src/utils/gitlab-without-vorpal/FetchMethod.ts +0 -1
- package/src/utils/gitlab-without-vorpal/GitLabApiDataOptional.ts +0 -14
- package/src/utils/gitlab-without-vorpal/GitLabTokenMissingError.ts +0 -7
- package/src/utils/gitlab-without-vorpal/fetchGitLabApi.ts +0 -74
- package/src/utils/gitlab-without-vorpal/getGitlabHostPathToken.ts +0 -31
- package/src/utils/gitlab-without-vorpal/gitLabProjectByGitPath.ts +0 -57
- package/src/utils/gitlab-without-vorpal/gitLabVariables.ts +0 -290
- package/src/utils/gitlab-without-vorpal/index.ts +0 -12
- package/src/utils/gitlab-without-vorpal/insertProjectTopics.ts +0 -35
- package/src/utils/gitlab-without-vorpal/loadGitLabToken.ts +0 -29
- package/src/utils/gitlab-without-vorpal/projectAccessToken.ts +0 -86
- package/src/utils/gitlab-without-vorpal/storeGitLabToken.ts +0 -23
- package/src/utils/preferences/CatladderPreferences.ts +0 -51
- package/src/utils/preferences/index.ts +0 -103
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import type {
|
|
2
|
+
Config,
|
|
3
|
+
EnvironmentEnvVars,
|
|
4
|
+
VariableValue,
|
|
5
|
+
} from "@catladder/pipeline";
|
|
3
6
|
import {
|
|
4
7
|
readConfig,
|
|
5
8
|
getAllEnvs,
|
|
@@ -9,14 +12,11 @@ import {
|
|
|
9
12
|
} from "@catladder/pipeline";
|
|
10
13
|
|
|
11
14
|
import type { CommandInstance } from "vorpal";
|
|
12
|
-
import {
|
|
15
|
+
import { getAllVariables, getVariableValueByRawName } from "../utils/gitlab";
|
|
13
16
|
|
|
14
17
|
import { getGitRoot } from "../utils/projects";
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
gitLabVariable,
|
|
18
|
-
type GitLabApiDataOptional,
|
|
19
|
-
} from "../utils/gitlab-without-vorpal";
|
|
18
|
+
|
|
19
|
+
import { watch } from "fs";
|
|
20
20
|
|
|
21
21
|
export { parseChoice } from "./parseChoice";
|
|
22
22
|
|
|
@@ -94,10 +94,21 @@ export const getAllComponentsWithAllEnvsHierarchical = async (): Promise<{
|
|
|
94
94
|
);
|
|
95
95
|
};
|
|
96
96
|
|
|
97
|
-
export const getAllPipelineContexts = async (
|
|
97
|
+
export const getAllPipelineContexts = async (
|
|
98
|
+
onlyComponent?: string | string[],
|
|
99
|
+
) => {
|
|
100
|
+
const onlyComponentsArray = onlyComponent
|
|
101
|
+
? Array.isArray(onlyComponent)
|
|
102
|
+
? onlyComponent
|
|
103
|
+
: [onlyComponent]
|
|
104
|
+
: null;
|
|
98
105
|
return Promise.all(
|
|
99
106
|
(await getAllComponentsWithAllEnvsFlat())
|
|
100
107
|
.filter((c) => c.env !== "local")
|
|
108
|
+
.filter(
|
|
109
|
+
(c) =>
|
|
110
|
+
!onlyComponentsArray || onlyComponentsArray.includes(c.componentName),
|
|
111
|
+
)
|
|
101
112
|
.map(({ env, componentName }) =>
|
|
102
113
|
getPipelineContextByChoice(env, componentName),
|
|
103
114
|
),
|
|
@@ -123,20 +134,8 @@ export const getGitlabVar = async (
|
|
|
123
134
|
const resolveSecrets = async (
|
|
124
135
|
vorpal: CommandInstance | null,
|
|
125
136
|
varSets: EnvironmentEnvVars[],
|
|
126
|
-
existing: GitLabApiDataOptional = {},
|
|
127
137
|
): Promise<Record<string, string>> => {
|
|
128
|
-
const
|
|
129
|
-
host,
|
|
130
|
-
path,
|
|
131
|
-
token: inputToken,
|
|
132
|
-
} = await getGitLabHostPathToken(existing, vorpal);
|
|
133
|
-
const token = inputToken || (await getGitlabToken(vorpal, host));
|
|
134
|
-
const allVariablesInGitlab = await gitLabVariable.getAll({
|
|
135
|
-
logger: vorpal,
|
|
136
|
-
token,
|
|
137
|
-
host,
|
|
138
|
-
path,
|
|
139
|
-
});
|
|
138
|
+
const allVariablesInGitlab = await getAllVariables(vorpal);
|
|
140
139
|
|
|
141
140
|
return Object.fromEntries(
|
|
142
141
|
varSets.flatMap(({ envVars, secretEnvVarKeys }) =>
|
|
@@ -12,16 +12,10 @@ export const getProjectRootPath = async (): Promise<string> => {
|
|
|
12
12
|
/**
|
|
13
13
|
* Get the git remote hostname and project path from the git config.
|
|
14
14
|
*/
|
|
15
|
-
export const getGitRemoteHostAndPath = async ({
|
|
16
|
-
host,
|
|
17
|
-
path,
|
|
18
|
-
}: { host?: string; path?: string } = {}): Promise<{
|
|
15
|
+
export const getGitRemoteHostAndPath = async (): Promise<{
|
|
19
16
|
gitRemoteHost: string;
|
|
20
17
|
gitRemotePath: string;
|
|
21
18
|
}> => {
|
|
22
|
-
if (host?.length && path?.length) {
|
|
23
|
-
return { gitRemoteHost: host, gitRemotePath: path };
|
|
24
|
-
}
|
|
25
19
|
const remoteUrl = await gitConfigGet("remote.origin.url");
|
|
26
20
|
const remoteReg = /(https:\/\/|git@)([^:/]+)[:/]([^.]*)(\.git)?/;
|
|
27
21
|
const match = remoteUrl.match(remoteReg) ?? [];
|
|
@@ -44,27 +38,3 @@ export const gitProjectInformation = async () => {
|
|
|
44
38
|
projectRootPath,
|
|
45
39
|
};
|
|
46
40
|
};
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Get the git remote hostname.
|
|
50
|
-
* Will only run a shell execution when hostnamePresent is nil or empty.
|
|
51
|
-
*/
|
|
52
|
-
export const getGitRemoteHost = async (hostnamePresent?: string) => {
|
|
53
|
-
if (hostnamePresent?.length) {
|
|
54
|
-
return hostnamePresent;
|
|
55
|
-
}
|
|
56
|
-
const { gitRemoteHost } = await getGitRemoteHostAndPath();
|
|
57
|
-
return gitRemoteHost;
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Get the git remote path.
|
|
62
|
-
* Will only run a shell execution when pathPresent is nil or empty.
|
|
63
|
-
*/
|
|
64
|
-
export const getGitRemotePath = async (pathPresent?: string) => {
|
|
65
|
-
if (pathPresent?.length) {
|
|
66
|
-
return pathPresent;
|
|
67
|
-
}
|
|
68
|
-
const { gitRemotePath } = await getGitRemoteHostAndPath();
|
|
69
|
-
return gitRemotePath;
|
|
70
|
-
};
|
package/src/utils/gitlab.ts
CHANGED
|
@@ -1,186 +1,272 @@
|
|
|
1
|
+
import { getSecretVarName } from "@catladder/pipeline";
|
|
1
2
|
import { has, isObject } from "lodash";
|
|
3
|
+
import memoizee from "memoizee";
|
|
4
|
+
import fetch from "node-fetch";
|
|
2
5
|
import open from "open";
|
|
3
6
|
import type { CommandInstance } from "vorpal";
|
|
7
|
+
import { getPreference, hasPreference, setPreference } from "./preferences";
|
|
8
|
+
import { getGitRemoteHostAndPath } from "../git/gitProjectInformation";
|
|
4
9
|
|
|
5
|
-
|
|
6
|
-
import { getGitRemoteHost } from "../git/gitProjectInformation";
|
|
7
|
-
import { logError, logNotice, logLines } from "./log";
|
|
8
|
-
import {
|
|
9
|
-
type FetchMethod,
|
|
10
|
-
type GitLabApiDataOptional,
|
|
11
|
-
fetchGitLabApi,
|
|
12
|
-
GitLabTokenMissingError,
|
|
13
|
-
loadGitLabToken,
|
|
14
|
-
storeGitLabToken,
|
|
15
|
-
gitLabVariable,
|
|
16
|
-
getGitLabHostPathToken,
|
|
17
|
-
getGitLabProjectId,
|
|
18
|
-
} from "./gitlab-without-vorpal";
|
|
19
|
-
|
|
20
|
-
export const setupGitlabToken = async (
|
|
21
|
-
vorpal: CommandInstance,
|
|
22
|
-
host?: string,
|
|
23
|
-
) => {
|
|
24
|
-
logNotice(
|
|
25
|
-
vorpal,
|
|
26
|
-
"In order to access the API, you need your personal access token.",
|
|
27
|
-
"It's best to create a specific token for CatLadder.",
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
const gitRemoteHost = await getGitRemoteHost(host);
|
|
31
|
-
const accessTokenSettingsUrl = `https://${gitRemoteHost}/-/user_settings/personal_access_tokens`;
|
|
32
|
-
logNotice(
|
|
33
|
-
vorpal,
|
|
34
|
-
"We'll open up the GitLab settings page in your browser for you!",
|
|
35
|
-
accessTokenSettingsUrl,
|
|
36
|
-
);
|
|
10
|
+
const TOKEN_KEY = "gitlab-personal-access-token";
|
|
37
11
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
12
|
+
export const hasGitlabToken = async () => await hasPreference(TOKEN_KEY);
|
|
13
|
+
export const setupGitlabToken = async (vorpal: CommandInstance) => {
|
|
14
|
+
vorpal.log("");
|
|
15
|
+
vorpal.log("☝ in order to access the api, we need a personal access token");
|
|
16
|
+
vorpal.log("Its best to create one specifically for catladder");
|
|
17
|
+
vorpal.log("Scopes needed: api");
|
|
18
|
+
vorpal.log("");
|
|
19
|
+
vorpal.log("☝ we open up the settings page for you!");
|
|
20
|
+
vorpal.log("");
|
|
21
|
+
const [{ shouldContinue }, { gitRemoteHost }] = await Promise.all([
|
|
22
|
+
vorpal.prompt({
|
|
23
|
+
default: true,
|
|
24
|
+
message: "Ok",
|
|
25
|
+
name: "shouldContinue",
|
|
26
|
+
type: "prompt",
|
|
27
|
+
}),
|
|
28
|
+
getGitRemoteHostAndPath(),
|
|
29
|
+
]);
|
|
44
30
|
|
|
45
|
-
open(
|
|
31
|
+
open(`https://${gitRemoteHost}/-/user_settings/personal_access_tokens`);
|
|
46
32
|
|
|
47
|
-
|
|
33
|
+
vorpal.log("Please type in gitlab's personal access token");
|
|
48
34
|
|
|
49
|
-
const { personalToken
|
|
35
|
+
const { personalToken } = await vorpal.prompt({
|
|
50
36
|
type: "string",
|
|
51
37
|
name: "personalToken",
|
|
52
38
|
default: "",
|
|
53
39
|
message: "Your personal access token ",
|
|
54
40
|
});
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
|
|
41
|
+
if (personalToken) {
|
|
42
|
+
await setPreference(TOKEN_KEY, personalToken);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
export const getGitlabToken = async (vorpal: CommandInstance | null) => {
|
|
46
|
+
if (!(await hasGitlabToken())) {
|
|
47
|
+
if (!vorpal) {
|
|
48
|
+
console.error(
|
|
49
|
+
"⚠️ gitlab token missing, please run catladder to set it up",
|
|
50
|
+
);
|
|
60
51
|
process.exit(1);
|
|
61
|
-
} else {
|
|
62
|
-
throw error;
|
|
63
52
|
}
|
|
53
|
+
await setupGitlabToken(vorpal);
|
|
64
54
|
}
|
|
55
|
+
return getPreference(TOKEN_KEY);
|
|
65
56
|
};
|
|
66
57
|
|
|
67
|
-
|
|
58
|
+
type Method = "GET" | "PUT" | "POST" | "DELETE";
|
|
59
|
+
export const doGitlabRequest = async <T = any>(
|
|
68
60
|
vorpal: CommandInstance | null,
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
61
|
+
path: string,
|
|
62
|
+
data: any = undefined,
|
|
63
|
+
method: Method = "GET",
|
|
64
|
+
): Promise<T> => {
|
|
65
|
+
const [rootToken, { gitRemoteHost }] = await Promise.all([
|
|
66
|
+
getGitlabToken(vorpal),
|
|
67
|
+
getGitRemoteHostAndPath(),
|
|
68
|
+
]);
|
|
69
|
+
|
|
70
|
+
//const method = data ? (update ? "PUT" : "POST") : "GET";
|
|
71
|
+
|
|
72
|
+
const result = await fetch(`https://${gitRemoteHost}/api/v4/${path}`, {
|
|
73
|
+
method,
|
|
74
|
+
headers: {
|
|
75
|
+
"Content-Type": "application/json",
|
|
76
|
+
"Private-Token": rootToken,
|
|
77
|
+
},
|
|
78
|
+
body: data ? JSON.stringify(data) : undefined,
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
if (result.status >= 200 && result.status < 400) {
|
|
82
|
+
if (result.headers.get("content-type") === "application/json") {
|
|
83
|
+
return result.json();
|
|
78
84
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
);
|
|
84
|
-
process.exit(1);
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
if (result.status === 404) {
|
|
88
|
+
throw new Error("not found");
|
|
85
89
|
}
|
|
90
|
+
|
|
91
|
+
throw new Error(
|
|
92
|
+
`Could not send request to gitlab api ${path}: ${result.status} "${
|
|
93
|
+
result.statusText
|
|
94
|
+
}".\nResponse: ${JSON.stringify(await result.json(), null, 2)}`,
|
|
95
|
+
);
|
|
86
96
|
};
|
|
87
97
|
|
|
88
|
-
export const
|
|
98
|
+
export const getProjectInfo = async (
|
|
89
99
|
vorpal: CommandInstance | null,
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
100
|
+
): Promise<{ id: string; web_url: string }> => {
|
|
101
|
+
const { gitRemotePath } = await getGitRemoteHostAndPath();
|
|
102
|
+
const project = await doGitlabRequest(
|
|
103
|
+
vorpal,
|
|
104
|
+
`projects/${encodeURIComponent(gitRemotePath)}`,
|
|
105
|
+
);
|
|
106
|
+
return project;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
type GitlabVariable = {
|
|
110
|
+
variable_type: string;
|
|
111
|
+
key: string;
|
|
112
|
+
value: string;
|
|
113
|
+
protected: boolean;
|
|
114
|
+
masked: boolean;
|
|
115
|
+
environment_scope: string;
|
|
116
|
+
};
|
|
117
|
+
export const getAllVariables = memoizee(
|
|
118
|
+
async (
|
|
119
|
+
vorpal: CommandInstance | null,
|
|
120
|
+
n = 5, // how many requests to do in parallel, 5 seems a good value for many projects, ideally we would do one request in parallel per component
|
|
121
|
+
): Promise<Array<GitlabVariable>> => {
|
|
122
|
+
const { id } = await getProjectInfo(vorpal);
|
|
123
|
+
|
|
124
|
+
let all: Array<GitlabVariable> = [];
|
|
125
|
+
let result: Array<Array<GitlabVariable>> = [];
|
|
126
|
+
let page = 1;
|
|
127
|
+
|
|
128
|
+
do {
|
|
129
|
+
// Create an array of promises for N pages
|
|
130
|
+
const promises = Array.from({ length: n }, (_, i) => {
|
|
131
|
+
return doGitlabRequest(
|
|
132
|
+
vorpal,
|
|
133
|
+
`projects/${id}/variables?per_page=100&page=${page + i}`,
|
|
134
|
+
);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// Wait for all promises to resolve
|
|
138
|
+
result = await Promise.all(promises);
|
|
139
|
+
|
|
140
|
+
// Increment the page by N
|
|
141
|
+
page += n;
|
|
142
|
+
|
|
143
|
+
// Flatten the result array and add it to 'all'
|
|
144
|
+
all = [...all, ...result.flat()];
|
|
145
|
+
// Continue only if the last page had results
|
|
146
|
+
} while (result.length > 0 && result[result.length - 1].length > 0);
|
|
147
|
+
|
|
148
|
+
return all;
|
|
99
149
|
},
|
|
100
|
-
|
|
150
|
+
{ promise: true },
|
|
151
|
+
);
|
|
101
152
|
|
|
102
153
|
export const getVariableValueByRawName = async (
|
|
103
154
|
vorpal: CommandInstance,
|
|
104
155
|
rawName: string,
|
|
105
|
-
{
|
|
106
|
-
projectId,
|
|
107
|
-
...existing
|
|
108
|
-
}: GitLabApiDataOptional & { projectId?: number | string } = {},
|
|
109
156
|
) => {
|
|
110
|
-
const
|
|
111
|
-
host,
|
|
112
|
-
path,
|
|
113
|
-
token: inputToken,
|
|
114
|
-
} = await getGitLabHostPathToken(existing, vorpal);
|
|
115
|
-
const token = inputToken || (await getGitlabToken(vorpal, host));
|
|
116
|
-
const id =
|
|
117
|
-
projectId || (await getGitLabProjectId({ host, path, token }, vorpal));
|
|
118
|
-
const allVariables = await gitLabVariable.getAll({
|
|
119
|
-
logger: vorpal,
|
|
120
|
-
host,
|
|
121
|
-
path,
|
|
122
|
-
token,
|
|
123
|
-
projectId: id,
|
|
124
|
-
});
|
|
157
|
+
const allVariables = await getAllVariables(vorpal);
|
|
125
158
|
return allVariables.find((v) => v.key === rawName)?.value;
|
|
126
159
|
};
|
|
127
160
|
|
|
128
|
-
const
|
|
161
|
+
const maskableRegex = new RegExp("^[a-zA-Z0-9_+=/@:.~-]{8,}$"); // SEE https://gitlab.com/gitlab-org/gitlab-foss/-/blob/master/spec/frontend/ci_variable_list/components/ci_variable_modal_spec.js#L20
|
|
162
|
+
const isMaskable = (value: string): boolean => maskableRegex.test(value);
|
|
163
|
+
|
|
164
|
+
const createVariable = async (
|
|
129
165
|
vorpal: CommandInstance,
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
166
|
+
projectId: string,
|
|
167
|
+
key: string,
|
|
168
|
+
value: string,
|
|
169
|
+
masked = true,
|
|
170
|
+
environment_scope = "*",
|
|
134
171
|
) => {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
path,
|
|
147
|
-
token,
|
|
148
|
-
projectId: id,
|
|
149
|
-
});
|
|
172
|
+
return await doGitlabRequest(
|
|
173
|
+
vorpal,
|
|
174
|
+
`projects/${projectId}/variables`,
|
|
175
|
+
{
|
|
176
|
+
key,
|
|
177
|
+
value,
|
|
178
|
+
masked: masked && isMaskable(value),
|
|
179
|
+
environment_scope,
|
|
180
|
+
},
|
|
181
|
+
"POST",
|
|
182
|
+
);
|
|
150
183
|
};
|
|
151
184
|
|
|
152
|
-
const
|
|
153
|
-
|
|
185
|
+
const updateVariable = async (
|
|
186
|
+
vorpal: CommandInstance,
|
|
187
|
+
projectId: string,
|
|
188
|
+
key: string,
|
|
189
|
+
value: string,
|
|
190
|
+
masked = true,
|
|
191
|
+
) => {
|
|
192
|
+
return await doGitlabRequest(
|
|
193
|
+
vorpal,
|
|
194
|
+
`projects/${projectId}/variables/${key}`,
|
|
195
|
+
{
|
|
196
|
+
value,
|
|
197
|
+
masked: masked && isMaskable(value),
|
|
198
|
+
},
|
|
199
|
+
"PUT",
|
|
200
|
+
);
|
|
201
|
+
};
|
|
154
202
|
|
|
155
|
-
|
|
203
|
+
const deleteVariable = async (
|
|
156
204
|
vorpal: CommandInstance,
|
|
157
|
-
|
|
158
|
-
|
|
205
|
+
projectId: string,
|
|
206
|
+
key: string,
|
|
159
207
|
) => {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
208
|
+
return await doGitlabRequest(
|
|
209
|
+
vorpal,
|
|
210
|
+
`projects/${projectId}/variables/${key}`,
|
|
211
|
+
undefined,
|
|
212
|
+
"DELETE",
|
|
213
|
+
);
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
const getAllCatladderEnvVarsInGitlab = async (vorpal: CommandInstance) => {
|
|
217
|
+
const allVariables = await getAllVariables(vorpal).then((v) =>
|
|
218
|
+
v.reduce<{
|
|
219
|
+
[key: string]: {
|
|
220
|
+
value?: string;
|
|
221
|
+
backups: number[];
|
|
222
|
+
};
|
|
223
|
+
}>((acc, variable) => {
|
|
224
|
+
const { key } = variable;
|
|
225
|
+
|
|
226
|
+
if (key.startsWith("CL_")) {
|
|
227
|
+
const matchBackup = key.match(/(CL_.*)_backup_([0-9]+)/);
|
|
228
|
+
|
|
229
|
+
if (matchBackup) {
|
|
230
|
+
const key = matchBackup[1];
|
|
231
|
+
const timestamp = Number(matchBackup[2]);
|
|
232
|
+
const backups = [...(acc[key]?.backups ?? []), timestamp];
|
|
233
|
+
return {
|
|
234
|
+
...acc,
|
|
235
|
+
[key]: {
|
|
236
|
+
...(acc[key] ?? {}), // add value
|
|
237
|
+
backups,
|
|
238
|
+
},
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return {
|
|
243
|
+
...acc,
|
|
244
|
+
[key]: {
|
|
245
|
+
backups: [],
|
|
246
|
+
...(acc[key] ?? {}), // may add backups
|
|
247
|
+
value: variable.value,
|
|
248
|
+
},
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return acc;
|
|
253
|
+
}, {}),
|
|
254
|
+
);
|
|
255
|
+
return allVariables;
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
const getBackupKey = (fullKey: string, timestamp: number) =>
|
|
259
|
+
`${fullKey}_backup_${timestamp}`;
|
|
260
|
+
export const clearBackups = async (vorpal: CommandInstance, keep: number) => {
|
|
261
|
+
const existingVariables = await getAllCatladderEnvVarsInGitlab(vorpal);
|
|
262
|
+
const { id } = await getProjectInfo(vorpal);
|
|
174
263
|
for (const [key, { backups }] of Object.entries(existingVariables)) {
|
|
175
264
|
const backupsSorted = backups.sort((a, b) => b - a);
|
|
176
265
|
//const toKeep = backupsSorted.slice(0, keep);
|
|
177
266
|
const toDelete = backupsSorted.slice(keep);
|
|
178
267
|
|
|
179
268
|
for (const timestamp of toDelete) {
|
|
180
|
-
await
|
|
181
|
-
{ projectId: id, key: getBackupKey(key, timestamp), token, host },
|
|
182
|
-
vorpal,
|
|
183
|
-
);
|
|
269
|
+
await deleteVariable(vorpal, id, getBackupKey(key, timestamp));
|
|
184
270
|
}
|
|
185
271
|
}
|
|
186
272
|
};
|
|
@@ -192,27 +278,11 @@ export const upsertAllVariables = async (
|
|
|
192
278
|
componentName: string,
|
|
193
279
|
backup = true,
|
|
194
280
|
masked = true, // FIXME: would be better to have this per variable
|
|
195
|
-
{
|
|
196
|
-
projectId,
|
|
197
|
-
...existing
|
|
198
|
-
}: GitLabApiDataOptional & { projectId?: number | string } = {},
|
|
199
281
|
): Promise<void> => {
|
|
200
|
-
const {
|
|
201
|
-
host,
|
|
202
|
-
path,
|
|
203
|
-
token: inputToken,
|
|
204
|
-
} = await getGitLabHostPathToken(existing, vorpal);
|
|
205
|
-
const token = inputToken || (await getGitlabToken(vorpal, host));
|
|
206
|
-
const id =
|
|
207
|
-
projectId || (await getGitLabProjectId({ host, path, token }, vorpal));
|
|
282
|
+
const { id } = await getProjectInfo(vorpal);
|
|
208
283
|
|
|
209
284
|
// we list all existing variables. We also gather backup versions, but its currently unused
|
|
210
|
-
const existingVariables = await getAllCatladderEnvVarsInGitlab(vorpal
|
|
211
|
-
projectId: id,
|
|
212
|
-
host,
|
|
213
|
-
path,
|
|
214
|
-
token,
|
|
215
|
-
});
|
|
285
|
+
const existingVariables = await getAllCatladderEnvVarsInGitlab(vorpal);
|
|
216
286
|
for (const [key, value] of Object.entries(variables ?? {})) {
|
|
217
287
|
const fullKey = getSecretVarName(env, componentName, key);
|
|
218
288
|
const valueSanitized = isObject(value) ? JSON.stringify(value) : `${value}`;
|
|
@@ -220,52 +290,29 @@ export const upsertAllVariables = async (
|
|
|
220
290
|
const exists = has(existingVariables, fullKey);
|
|
221
291
|
const oldValue = existingVariables[fullKey]?.value;
|
|
222
292
|
const changed = oldValue !== valueSanitized;
|
|
223
|
-
if (
|
|
293
|
+
if (changed) {
|
|
294
|
+
if (exists) {
|
|
295
|
+
vorpal.log(`changed: ${key}`);
|
|
296
|
+
|
|
297
|
+
await updateVariable(vorpal, id, fullKey, valueSanitized, masked);
|
|
298
|
+
// write backup
|
|
299
|
+
if (backup) {
|
|
300
|
+
await createVariable(
|
|
301
|
+
vorpal,
|
|
302
|
+
id,
|
|
303
|
+
getBackupKey(fullKey, new Date().getTime()),
|
|
304
|
+
oldValue,
|
|
305
|
+
masked,
|
|
306
|
+
"_backup",
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
} else {
|
|
310
|
+
vorpal.log(`new : ${key}`);
|
|
311
|
+
await createVariable(vorpal, id, fullKey, valueSanitized, masked);
|
|
312
|
+
}
|
|
313
|
+
} else {
|
|
224
314
|
vorpal.log(`skip : ${key}`);
|
|
225
|
-
continue;
|
|
226
|
-
}
|
|
227
|
-
if (!exists) {
|
|
228
|
-
vorpal.log(`new : ${key}`);
|
|
229
|
-
await gitLabVariable.create(
|
|
230
|
-
{
|
|
231
|
-
projectId: id,
|
|
232
|
-
key: fullKey,
|
|
233
|
-
value: valueSanitized,
|
|
234
|
-
masked,
|
|
235
|
-
host,
|
|
236
|
-
token,
|
|
237
|
-
},
|
|
238
|
-
vorpal,
|
|
239
|
-
);
|
|
240
|
-
continue;
|
|
241
|
-
}
|
|
242
|
-
vorpal.log(`changed: ${key}`);
|
|
243
|
-
|
|
244
|
-
await gitLabVariable.update(
|
|
245
|
-
{
|
|
246
|
-
projectId: id,
|
|
247
|
-
key: fullKey,
|
|
248
|
-
value: valueSanitized,
|
|
249
|
-
masked,
|
|
250
|
-
host,
|
|
251
|
-
token,
|
|
252
|
-
},
|
|
253
|
-
vorpal,
|
|
254
|
-
);
|
|
255
|
-
// write backup
|
|
256
|
-
if (backup) {
|
|
257
|
-
await gitLabVariable.create(
|
|
258
|
-
{
|
|
259
|
-
projectId: id,
|
|
260
|
-
key: getBackupKey(fullKey, new Date().getTime()),
|
|
261
|
-
value: oldValue,
|
|
262
|
-
masked,
|
|
263
|
-
host,
|
|
264
|
-
token,
|
|
265
|
-
},
|
|
266
|
-
vorpal,
|
|
267
|
-
);
|
|
268
315
|
}
|
|
269
316
|
}
|
|
270
|
-
|
|
317
|
+
getAllVariables.clear();
|
|
271
318
|
};
|
package/src/utils/log.ts
CHANGED
|
@@ -111,29 +111,3 @@ export const logWarning = (
|
|
|
111
111
|
}
|
|
112
112
|
logLines(cmd, "");
|
|
113
113
|
};
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Logs a notification message using the log method of the provided {@link LoggerCmdInstance}.
|
|
117
|
-
*
|
|
118
|
-
* Line items that are `null` or `undefined` are logged as empty lines.
|
|
119
|
-
*
|
|
120
|
-
* @example
|
|
121
|
-
* ```ts
|
|
122
|
-
* logNotice(cmd, "Message");
|
|
123
|
-
* logNotice(cmd, "Message", "Additional message");
|
|
124
|
-
* logNotice(cmd, "Message", "Additional message", "Another additional message line");
|
|
125
|
-
* logNotice(cmd, "Message", ...additionalMessages); // arrays can be spread into the function
|
|
126
|
-
* logNotice(cmd, "Message", additionalMessages); // but it will flatten the plain array for convenience
|
|
127
|
-
* ```
|
|
128
|
-
*/
|
|
129
|
-
export const logNotice = (
|
|
130
|
-
cmd: LoggerCmdInstance = console,
|
|
131
|
-
message: string,
|
|
132
|
-
...additionalMessages: LinesArg[]
|
|
133
|
-
) => {
|
|
134
|
-
logLines(cmd, "", `[NOTICE] ☝ : ${message}`);
|
|
135
|
-
if (additionalMessages?.length) {
|
|
136
|
-
logLines(cmd, ...additionalMessages.flat());
|
|
137
|
-
}
|
|
138
|
-
logLines(cmd, "");
|
|
139
|
-
};
|