@catladder/cli 5.1.3 → 5.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/apps/cli/src/commands/project/commandPortForward.js +1 -1
- package/dist/apps/cli/src/commands/project/commandPortForward.js.map +1 -1
- package/dist/apps/cli/src/commands/project/secrets/scope.js +25 -2
- package/dist/apps/cli/src/commands/project/secrets/scope.js.map +1 -1
- package/dist/apps/cli/src/config/getProjectConfig.js +4 -1
- package/dist/apps/cli/src/config/getProjectConfig.js.map +1 -1
- package/dist/apps/cli/src/secrets/github.js +4 -2
- package/dist/apps/cli/src/secrets/github.js.map +1 -1
- package/dist/bundles/catenv/index.js +419 -106
- package/dist/bundles/cli/index.js +449 -111
- package/dist/bundles/skills/catladder-config/SKILL.md +34 -2
- package/dist/bundles/skills/catladder-deploys/SKILL.md +5 -0
- package/dist/bundles/skills/catladder-pipelines/SKILL.md +42 -1
- package/dist/bundles/skills/catladder-secrets/SKILL.md +6 -0
- package/dist/packages/pipeline/src/backends/github/GithubBackend.js +23 -3
- package/dist/packages/pipeline/src/backends/github/GithubBackend.js.map +1 -1
- package/dist/packages/pipeline/src/backends/github/createGithubJobs.js +2 -2
- package/dist/packages/pipeline/src/backends/github/createGithubJobs.js.map +1 -1
- package/dist/packages/pipeline/src/backends/gitlab/GitlabBackend.js +18 -2
- package/dist/packages/pipeline/src/backends/gitlab/GitlabBackend.js.map +1 -1
- package/dist/packages/pipeline/src/backends/gitlab/createGitlabJobs.js +2 -2
- package/dist/packages/pipeline/src/backends/gitlab/createGitlabJobs.js.map +1 -1
- package/dist/packages/pipeline/src/backends/gitlab/createGitlabPipeline.d.ts +6 -1
- package/dist/packages/pipeline/src/backends/gitlab/createGitlabPipeline.js +24 -1
- package/dist/packages/pipeline/src/backends/gitlab/createGitlabPipeline.js.map +1 -1
- package/dist/packages/pipeline/src/backends/gitlab/gitlabReleaseJobs.d.ts +17 -0
- package/dist/packages/pipeline/src/backends/gitlab/gitlabReleaseJobs.js +13 -0
- package/dist/packages/pipeline/src/backends/gitlab/gitlabReleaseJobs.js.map +1 -1
- package/dist/packages/pipeline/src/config/configruedEnvs.d.ts +9 -2
- package/dist/packages/pipeline/src/config/configruedEnvs.js +54 -5
- package/dist/packages/pipeline/src/config/configruedEnvs.js.map +1 -1
- package/dist/packages/pipeline/src/context/createAllComponentsContext.d.ts +2 -2
- package/dist/packages/pipeline/src/context/createComponentContext.d.ts +2 -2
- package/dist/packages/pipeline/src/context/createWorkspaceContext.d.ts +2 -2
- package/dist/packages/pipeline/src/context/getEnvConfig.js +35 -19
- package/dist/packages/pipeline/src/context/getEnvConfig.js.map +1 -1
- package/dist/packages/pipeline/src/context/getEnvInherit.d.ts +20 -0
- package/dist/packages/pipeline/src/context/getEnvInherit.js +72 -0
- package/dist/packages/pipeline/src/context/getEnvInherit.js.map +1 -0
- package/dist/packages/pipeline/src/context/getEnvInstance.d.ts +4 -0
- package/dist/packages/pipeline/src/context/{getReviewSlug.js → getEnvInstance.js} +13 -9
- package/dist/packages/pipeline/src/context/getEnvInstance.js.map +1 -0
- package/dist/packages/pipeline/src/context/getEnvOn.d.ts +13 -0
- package/dist/packages/pipeline/src/context/getEnvOn.js +28 -0
- package/dist/packages/pipeline/src/context/getEnvOn.js.map +1 -0
- package/dist/packages/pipeline/src/context/getEnvType.d.ts +8 -2
- package/dist/packages/pipeline/src/context/getEnvType.js +27 -5
- package/dist/packages/pipeline/src/context/getEnvType.js.map +1 -1
- package/dist/packages/pipeline/src/context/getEnvironment.js +3 -0
- package/dist/packages/pipeline/src/context/getEnvironment.js.map +1 -1
- package/dist/packages/pipeline/src/context/getEnvironmentContext.js +18 -8
- package/dist/packages/pipeline/src/context/getEnvironmentContext.js.map +1 -1
- package/dist/packages/pipeline/src/context/getEnvironmentVariables.d.ts +1 -1
- package/dist/packages/pipeline/src/context/getEnvironmentVariables.js +4 -4
- package/dist/packages/pipeline/src/context/getEnvironmentVariables.js.map +1 -1
- package/dist/packages/pipeline/src/context/index.d.ts +1 -0
- package/dist/packages/pipeline/src/context/index.js +1 -0
- package/dist/packages/pipeline/src/context/index.js.map +1 -1
- package/dist/packages/pipeline/src/deploy/base/deploy.js +11 -1
- package/dist/packages/pipeline/src/deploy/base/deploy.js.map +1 -1
- package/dist/packages/pipeline/src/deploy/cloudRun/artifactsRegistry.js +5 -4
- package/dist/packages/pipeline/src/deploy/cloudRun/artifactsRegistry.js.map +1 -1
- package/dist/packages/pipeline/src/deploy/cloudRun/cleanup.js +8 -2
- package/dist/packages/pipeline/src/deploy/cloudRun/cleanup.js.map +1 -1
- package/dist/packages/pipeline/src/deploy/cloudRun/index.js +2 -2
- package/dist/packages/pipeline/src/deploy/cloudRun/index.js.map +1 -1
- package/dist/packages/pipeline/src/deploy/cloudRun/utils/getServiceName.js +2 -2
- package/dist/packages/pipeline/src/deploy/cloudRun/utils/getServiceName.js.map +1 -1
- package/dist/packages/pipeline/src/deploy/kubernetes/index.js +3 -3
- package/dist/packages/pipeline/src/deploy/kubernetes/index.js.map +1 -1
- package/dist/packages/pipeline/src/deploy/pages/deployJob.js +3 -2
- package/dist/packages/pipeline/src/deploy/pages/deployJob.js.map +1 -1
- package/dist/packages/pipeline/src/deploy/types/googleCloudRun.d.ts +9 -0
- package/dist/packages/pipeline/src/types/config.d.ts +126 -9
- package/dist/packages/pipeline/src/types/config.js +11 -10
- package/dist/packages/pipeline/src/types/config.js.map +1 -1
- package/dist/packages/pipeline/src/types/context.d.ts +22 -3
- package/dist/packages/pipeline/src/types/context.js.map +1 -1
- package/dist/packages/pipeline/src/types/environmentContext.d.ts +29 -0
- package/dist/packages/pipeline/src/types/gitlab-types.d.ts +29 -1
- package/dist/skills/catladder-config/SKILL.md +34 -2
- package/dist/skills/catladder-deploys/SKILL.md +5 -0
- package/dist/skills/catladder-pipelines/SKILL.md +42 -1
- package/dist/skills/catladder-secrets/SKILL.md +6 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/commands/project/commandPortForward.ts +1 -1
- package/src/commands/project/secrets/scope.ts +38 -2
- package/src/config/getProjectConfig.ts +9 -1
- package/src/secrets/github.ts +8 -5
- package/dist/packages/pipeline/src/context/getReviewSlug.d.ts +0 -4
- package/dist/packages/pipeline/src/context/getReviewSlug.js.map +0 -1
|
@@ -13,6 +13,24 @@ import type { ProjectImageConfig } from "../customImages/projectImages";
|
|
|
13
13
|
import type { VerifyConfig } from "../verify/types";
|
|
14
14
|
export declare const ALL_PIPELINE_TRIGGERS: readonly ["mainBranch", "mr", "taggedRelease"];
|
|
15
15
|
export type PipelineTrigger = (typeof ALL_PIPELINE_TRIGGERS)[number];
|
|
16
|
+
/**
|
|
17
|
+
* a pipeline that runs on pushes to one specific branch (in addition to
|
|
18
|
+
* the built-in triggers). Declared by an env via its `on` config.
|
|
19
|
+
*/
|
|
20
|
+
export type BranchPipelineTrigger = {
|
|
21
|
+
branch: string;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* everything a pipeline (and therefore an env's jobs) can run on
|
|
25
|
+
*/
|
|
26
|
+
export type EnvPipelineTrigger = PipelineTrigger | BranchPipelineTrigger;
|
|
27
|
+
/**
|
|
28
|
+
* the `on` config of an env: a trigger, or `false` for an env that is
|
|
29
|
+
* not part of any pipeline (like `local`)
|
|
30
|
+
*/
|
|
31
|
+
export type EnvOnConfig = EnvPipelineTrigger | false;
|
|
32
|
+
export declare const isBranchTrigger: (trigger: EnvPipelineTrigger) => trigger is BranchPipelineTrigger;
|
|
33
|
+
export declare const envTriggerEquals: (a: EnvOnConfig | undefined, b: EnvPipelineTrigger) => boolean;
|
|
16
34
|
/**
|
|
17
35
|
* all env types with their trigger.
|
|
18
36
|
* Each env type has a default env with the same name which is always included
|
|
@@ -34,16 +52,10 @@ export declare const ENV_TYPES: {
|
|
|
34
52
|
readonly triggers: readonly [];
|
|
35
53
|
};
|
|
36
54
|
};
|
|
37
|
-
/**
|
|
38
|
-
*
|
|
39
|
-
* @param trigger a trigger
|
|
40
|
-
* @returns array of env types for that trigger. this is also the list of default envs
|
|
41
|
-
*/
|
|
42
|
-
export declare const getEnvTypesByTrigger: (trigger: PipelineTrigger) => ("stage" | "prod" | "local" | "dev" | "review")[];
|
|
43
55
|
export declare const DEFAULT_ENVS: string[];
|
|
44
|
-
export declare const DEFAULT_ENV_TYPES: ("stage" | "prod" | "local" | "
|
|
56
|
+
export declare const DEFAULT_ENV_TYPES: ("stage" | "prod" | "local" | "review" | "dev")[];
|
|
45
57
|
export type EnvType = keyof typeof ENV_TYPES;
|
|
46
|
-
export declare const isKnowEnvType: (env: string) => env is "stage" | "prod" | "local" | "
|
|
58
|
+
export declare const isKnowEnvType: (env: string) => env is "stage" | "prod" | "local" | "review" | "dev";
|
|
47
59
|
export type EnvVars = {
|
|
48
60
|
/**
|
|
49
61
|
* public env vars (means: they are checked in the repo).
|
|
@@ -120,7 +132,100 @@ export type EnvConfig<E extends EnvType = EnvType> = {
|
|
|
120
132
|
* host that is used. If not set, a "canonical" url is created
|
|
121
133
|
*/
|
|
122
134
|
host?: string;
|
|
135
|
+
/**
|
|
136
|
+
* per-component override of the environment's autoStop (see
|
|
137
|
+
* {@link EnvironmentConfig.autoStop} — each component has its own
|
|
138
|
+
* gitlab environment, so the duration may differ per component)
|
|
139
|
+
*/
|
|
140
|
+
autoStop?: string | false;
|
|
123
141
|
} & PartialDeep<DefaultEnvConfig>;
|
|
142
|
+
/**
|
|
143
|
+
* project-wide declaration and tuning of an environment (the top-level
|
|
144
|
+
* `environments` config). Environments are a project-wide concept —
|
|
145
|
+
* every component deploys to a declared env unless it opts out with
|
|
146
|
+
* `env.<name>: false`. Anything that must be consistent across
|
|
147
|
+
* components (which envs exist, when they deploy) lives here; the
|
|
148
|
+
* per-component `env.<name>` entries only override component-local
|
|
149
|
+
* things (vars, deploy settings, host, autoStop).
|
|
150
|
+
*/
|
|
151
|
+
export type EnvironmentConfig = {
|
|
152
|
+
/**
|
|
153
|
+
* the type of env this behaves like (dev, review, stage, prod) —
|
|
154
|
+
* think of it as a preset: it supplies all defaults (when the env
|
|
155
|
+
* deploys, autoStop, deploy policy like rollback history and manual
|
|
156
|
+
* prod deploys) and the env's identity for tooling (the `ENV_TYPE`
|
|
157
|
+
* env var / `env-type` label). Everything it implies can be
|
|
158
|
+
* overridden explicitly. Required for envs whose name is not itself
|
|
159
|
+
* an env type.
|
|
160
|
+
*/
|
|
161
|
+
type?: EnvType;
|
|
162
|
+
/**
|
|
163
|
+
* when this env deploys. Defaults from the env type:
|
|
164
|
+
* - dev: "mainBranch" (pushes to the default branch)
|
|
165
|
+
* - review: "mr" (merge requests / pull requests; the env is created
|
|
166
|
+
* per MR and torn down when it closes)
|
|
167
|
+
* - stage / prod: "taggedRelease" (release tags)
|
|
168
|
+
* - local: false (not part of any pipeline)
|
|
169
|
+
*
|
|
170
|
+
* `{ branch: "next" }` deploys the env on pushes to that branch —
|
|
171
|
+
* one stable environment tracking a long-lived branch.
|
|
172
|
+
*
|
|
173
|
+
* `false` removes the env from all pipelines.
|
|
174
|
+
*/
|
|
175
|
+
on?: EnvOnConfig;
|
|
176
|
+
/**
|
|
177
|
+
* how long the environment stays up after its last deployment before
|
|
178
|
+
* gitlab stops it automatically (gitlab `auto_stop_in`, e.g. "3 days").
|
|
179
|
+
* `false` disables auto-stopping. Defaults from the env type, tunable
|
|
180
|
+
* project-wide via the top-level `autoStop` durations: review
|
|
181
|
+
* "1 week", dev "4 weeks", everything else never.
|
|
182
|
+
*
|
|
183
|
+
* Only applies to stoppable deployments, and only on gitlab (github
|
|
184
|
+
* review apps stop when their pull request closes). Components can
|
|
185
|
+
* override it per env (`env.<name>.autoStop`).
|
|
186
|
+
*
|
|
187
|
+
* NOTE: an explicit value here is a literal — setting it on a review
|
|
188
|
+
* env opts that env out of the pin-label mechanism (the top-level
|
|
189
|
+
* `autoStop.pinLabel`), which only steers the default review lifetime.
|
|
190
|
+
*/
|
|
191
|
+
autoStop?: string | false;
|
|
192
|
+
/**
|
|
193
|
+
* inherit from another environment (see {@link EnvironmentInheritConfig}):
|
|
194
|
+
*
|
|
195
|
+
* `inherit: "dev"` makes this env use dev's per-component config
|
|
196
|
+
* overrides AND dev's secret values. The object form controls the two
|
|
197
|
+
* axes separately.
|
|
198
|
+
*/
|
|
199
|
+
inherit?: EnvironmentInheritConfig;
|
|
200
|
+
};
|
|
201
|
+
/**
|
|
202
|
+
* what an environment inherits from another environment.
|
|
203
|
+
*
|
|
204
|
+
* The string shorthand `inherit: "dev"` means
|
|
205
|
+
* `{ config: "dev", secrets: "dev" }`.
|
|
206
|
+
*
|
|
207
|
+
* - `config`: the named env's per-component overrides (`env.<name>` in
|
|
208
|
+
* each component — vars, deploy/build settings, autoStop) are merged
|
|
209
|
+
* in below this env's own overrides: component base → inherited env's
|
|
210
|
+
* overrides → own overrides. `host` and `type` are never inherited
|
|
211
|
+
* (a host must stay unique per env). The env's `type` defaults to the
|
|
212
|
+
* inherited env's type.
|
|
213
|
+
* - `secrets`: this env uses the named env's secret VALUES — all or
|
|
214
|
+
* nothing: its jobs reference the other env's secret variables
|
|
215
|
+
* (`CL_<OTHERENV>_...`) and it has no secret store of its own, so the
|
|
216
|
+
* secrets CLI manages them via the other env and rotating them
|
|
217
|
+
* affects both envs. Set to `false` (or omit in the object form) for
|
|
218
|
+
* own secrets.
|
|
219
|
+
*
|
|
220
|
+
* Inheriting from `local` is not possible, chains are followed, cycles
|
|
221
|
+
* are an error.
|
|
222
|
+
*/
|
|
223
|
+
export type EnvironmentInheritConfig = string | {
|
|
224
|
+
/** env whose per-component config overrides are inherited */
|
|
225
|
+
config?: string;
|
|
226
|
+
/** env whose secret values are used (all-or-nothing); false = own secrets */
|
|
227
|
+
secrets?: string | false;
|
|
228
|
+
};
|
|
124
229
|
export type EnvConfigWithComponent = EnvConfig<EnvType> & ComponentConfig;
|
|
125
230
|
export type CustomEnv = EnvConfigWithOverride & {
|
|
126
231
|
type: EnvType;
|
|
@@ -134,7 +239,7 @@ export type Env<C extends ConfigProps = never> = {
|
|
|
134
239
|
stage?: EnvConfigWithOverride<"stage"> | false;
|
|
135
240
|
review?: EnvConfigWithOverride<"review"> | false;
|
|
136
241
|
prod?: EnvConfigWithOverride<"prod"> | false;
|
|
137
|
-
} & Record<C["CustomEnvs"],
|
|
242
|
+
} & Partial<Record<C["CustomEnvs"], EnvConfigWithOverride | false>> & Record<string, any>;
|
|
138
243
|
export type ComponentConfig<C extends ConfigProps = never> = {
|
|
139
244
|
/**
|
|
140
245
|
* specify environment configurations
|
|
@@ -315,6 +420,18 @@ export type Config<C extends ConfigProps = never> = {
|
|
|
315
420
|
*/
|
|
316
421
|
images?: Record<string, ProjectImageConfig>;
|
|
317
422
|
builds?: Record<string, WorkspaceBuildConfig>;
|
|
423
|
+
/**
|
|
424
|
+
* project-wide environment declarations and tuning. Environments are
|
|
425
|
+
* shared across all components, so everything that must be consistent
|
|
426
|
+
* between them (which envs exist, their type, when they deploy) is
|
|
427
|
+
* declared here — components only carry per-component overrides.
|
|
428
|
+
*
|
|
429
|
+
* - tune a default env: `environments: { review: { autoStop: "3 days" } }`
|
|
430
|
+
* - declare an extra env (every component deploys to it unless it
|
|
431
|
+
* opts out with `env.<name>: false`):
|
|
432
|
+
* `environments: { next: { type: "dev", on: { branch: "next" } } }`
|
|
433
|
+
*/
|
|
434
|
+
environments?: Record<string, EnvironmentConfig>;
|
|
318
435
|
/**
|
|
319
436
|
* components (sub apps)
|
|
320
437
|
*/
|
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isKnowEnvType = exports.DEFAULT_ENV_TYPES = exports.DEFAULT_ENVS = exports.
|
|
3
|
+
exports.isKnowEnvType = exports.DEFAULT_ENV_TYPES = exports.DEFAULT_ENVS = exports.ENV_TYPES = exports.envTriggerEquals = exports.isBranchTrigger = exports.ALL_PIPELINE_TRIGGERS = void 0;
|
|
4
4
|
exports.ALL_PIPELINE_TRIGGERS = [
|
|
5
5
|
"mainBranch",
|
|
6
6
|
"mr",
|
|
7
7
|
"taggedRelease",
|
|
8
8
|
];
|
|
9
|
+
const isBranchTrigger = (trigger) => typeof trigger === "object" && trigger !== null && "branch" in trigger;
|
|
10
|
+
exports.isBranchTrigger = isBranchTrigger;
|
|
11
|
+
const envTriggerEquals = (a, b) => {
|
|
12
|
+
if (a === undefined || a === false)
|
|
13
|
+
return false;
|
|
14
|
+
if ((0, exports.isBranchTrigger)(b))
|
|
15
|
+
return (0, exports.isBranchTrigger)(a) && a.branch === b.branch;
|
|
16
|
+
return a === b;
|
|
17
|
+
};
|
|
18
|
+
exports.envTriggerEquals = envTriggerEquals;
|
|
9
19
|
/**
|
|
10
20
|
* all env types with their trigger.
|
|
11
21
|
* Each env type has a default env with the same name which is always included
|
|
@@ -27,15 +37,6 @@ exports.ENV_TYPES = {
|
|
|
27
37
|
triggers: [],
|
|
28
38
|
},
|
|
29
39
|
};
|
|
30
|
-
/**
|
|
31
|
-
*
|
|
32
|
-
* @param trigger a trigger
|
|
33
|
-
* @returns array of env types for that trigger. this is also the list of default envs
|
|
34
|
-
*/
|
|
35
|
-
const getEnvTypesByTrigger = (trigger) => Object.entries(exports.ENV_TYPES)
|
|
36
|
-
.filter(([, e]) => e.triggers.includes(trigger))
|
|
37
|
-
.map(([e]) => e);
|
|
38
|
-
exports.getEnvTypesByTrigger = getEnvTypesByTrigger;
|
|
39
40
|
exports.DEFAULT_ENVS = Object.keys(exports.ENV_TYPES);
|
|
40
41
|
exports.DEFAULT_ENV_TYPES = exports.DEFAULT_ENVS;
|
|
41
42
|
const isKnowEnvType = (env) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../../../../packages/pipeline/src/types/config.ts"],"names":[],"mappings":";;;AAea,QAAA,qBAAqB,GAAG;IACnC,YAAY;IACZ,IAAI;IACJ,eAAe;CACP,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../../../../packages/pipeline/src/types/config.ts"],"names":[],"mappings":";;;AAea,QAAA,qBAAqB,GAAG;IACnC,YAAY;IACZ,IAAI;IACJ,eAAe;CACP,CAAC;AAoBJ,MAAM,eAAe,GAAG,CAC7B,OAA2B,EACO,EAAE,CACpC,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAI,QAAQ,IAAI,OAAO,CAAC;AAH5D,QAAA,eAAe,mBAG6C;AAElE,MAAM,gBAAgB,GAAG,CAC9B,CAA0B,EAC1B,CAAqB,EACZ,EAAE;IACX,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IACjD,IAAI,IAAA,uBAAe,EAAC,CAAC,CAAC;QAAE,OAAO,IAAA,uBAAe,EAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,CAAC;IAC3E,OAAO,CAAC,KAAK,CAAC,CAAC;AACjB,CAAC,CAAC;AAPW,QAAA,gBAAgB,oBAO3B;AAEF;;;GAGG;AACU,QAAA,SAAS,GAAG;IACvB,GAAG,EAAE;QACH,QAAQ,EAAE,CAAC,YAAY,CAAC;KACzB;IACD,MAAM,EAAE;QACN,QAAQ,EAAE,CAAC,IAAI,CAAC;KACjB;IACD,KAAK,EAAE;QACL,QAAQ,EAAE,CAAC,eAAe,CAAC;KAC5B;IACD,IAAI,EAAE;QACJ,QAAQ,EAAE,CAAC,eAAe,CAAC;KAC5B;IACD,KAAK,EAAE;QACL,QAAQ,EAAE,EAAE;KACb;CACO,CAAC;AAEE,QAAA,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAS,CAAC,CAAC;AACtC,QAAA,iBAAiB,GAAG,oBAAyB,CAAC;AAGpD,MAAM,aAAa,GAAG,CAAC,GAAW,EAAkB,EAAE;IAC3D,OAAO,GAAG,IAAI,iBAAS,CAAC;AAC1B,CAAC,CAAC;AAFW,QAAA,aAAa,iBAExB"}
|
|
@@ -3,7 +3,8 @@ import type { BuildConfigFromWorkspace, BuildConfigStandalone, WorkspaceBuildCon
|
|
|
3
3
|
import type { PredefinedVariables, SecretEnvVar } from "../context";
|
|
4
4
|
import type { DeployConfig } from "../deploy";
|
|
5
5
|
import type { VariableValue } from "../../../bash/src/index.js";
|
|
6
|
-
import type { ComponentConfig, Config,
|
|
6
|
+
import type { ComponentConfig, Config, EnvPipelineTrigger, EnvType } from "./config";
|
|
7
|
+
import type { EnvironmentInstance } from "./environmentContext";
|
|
7
8
|
import type { BaseStage, CatladderJob, CatladderJobSpec } from "./jobs";
|
|
8
9
|
import type { PipelineType } from "./pipeline";
|
|
9
10
|
export type UnspecifiedEnvVars = Record<string, VariableValue | undefined | null>;
|
|
@@ -29,8 +30,14 @@ export type Environment = {
|
|
|
29
30
|
* the environment slug without component name.
|
|
30
31
|
*/
|
|
31
32
|
slugPrefix: StringOrBashExpression;
|
|
33
|
+
/**
|
|
34
|
+
* how the env is instantiated — `instance.type === "review"` is the
|
|
35
|
+
* way to find out whether this is a review app
|
|
36
|
+
*/
|
|
37
|
+
instance: EnvironmentInstance;
|
|
32
38
|
/**
|
|
33
39
|
* the review slug, if it is a review app, null otherwise
|
|
40
|
+
* @deprecated use `instance` — the review variant carries the slug
|
|
34
41
|
*/
|
|
35
42
|
reviewSlug: StringOrBashExpression | null;
|
|
36
43
|
/**
|
|
@@ -38,6 +45,18 @@ export type Environment = {
|
|
|
38
45
|
*/
|
|
39
46
|
slug: StringOrBashExpression;
|
|
40
47
|
envType: EnvType;
|
|
48
|
+
/**
|
|
49
|
+
* the resolved `autoStop` config (component override, then the
|
|
50
|
+
* project-wide environment config — see {@link EnvironmentConfig.autoStop});
|
|
51
|
+
* undefined means the env type's default applies
|
|
52
|
+
*/
|
|
53
|
+
autoStop?: string | false;
|
|
54
|
+
/**
|
|
55
|
+
* the env whose secret values this env uses — the env itself unless
|
|
56
|
+
* it shares another env's secrets via `inherit`. All secret variable
|
|
57
|
+
* names are built with this env.
|
|
58
|
+
*/
|
|
59
|
+
secretsEnv: string;
|
|
41
60
|
} & EnvironmentEnvVarPart;
|
|
42
61
|
export type YarnWorkspace = {
|
|
43
62
|
name: string;
|
|
@@ -136,7 +155,7 @@ export type ComponentContext<BC extends BuildContextComponent = BuildContextComp
|
|
|
136
155
|
deploy?: DeployContext | null;
|
|
137
156
|
fullConfig: Config;
|
|
138
157
|
environment: Environment;
|
|
139
|
-
trigger?:
|
|
158
|
+
trigger?: EnvPipelineTrigger;
|
|
140
159
|
pipelineType?: PipelineType;
|
|
141
160
|
packageManagerInfo: Promise<PackageManagerInfoComponent>;
|
|
142
161
|
customJobs?: CatladderJobSpec[];
|
|
@@ -159,7 +178,7 @@ export type WorkspaceContext = {
|
|
|
159
178
|
packageManagerInfo: Promise<PackageManagerInfoBase>;
|
|
160
179
|
components: Array<ComponentContext>;
|
|
161
180
|
build: BuildContextWorkspace;
|
|
162
|
-
trigger:
|
|
181
|
+
trigger: EnvPipelineTrigger;
|
|
163
182
|
pipelineType: PipelineType;
|
|
164
183
|
env: string;
|
|
165
184
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../../../../../packages/pipeline/src/types/context.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../../../../../packages/pipeline/src/types/context.ts"],"names":[],"mappings":";;;AAsOO,MAAM,iCAAiC,GAAG,CAC/C,OAAgD,EACK,EAAE;IACvD,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC;AAC7C,CAAC,CAAC;AAJW,QAAA,iCAAiC,qCAI5C;AAEK,MAAM,iCAAiC,GAAG,CAC/C,OAAgD,EACQ,EAAE;IAC1D,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,eAAe,CAAC;AAChD,CAAC,CAAC;AAJW,QAAA,iCAAiC,qCAI5C"}
|
|
@@ -3,20 +3,49 @@ import type { BuildConfig } from "../build";
|
|
|
3
3
|
import type { DeployConfig } from "../deploy";
|
|
4
4
|
import type { Config, EnvConfigWithComponent, EnvType } from "./config";
|
|
5
5
|
import type { PipelineType } from "./pipeline";
|
|
6
|
+
/**
|
|
7
|
+
* how an environment is instantiated:
|
|
8
|
+
* - "stable": one long-lived instance (dev, stage, prod, branch envs)
|
|
9
|
+
* - "review": one instance per merge/pull request (`on: "mr"`),
|
|
10
|
+
* addressed by the runtime review slug (mr<iid> / pr<number>)
|
|
11
|
+
*/
|
|
12
|
+
export type EnvironmentInstance = {
|
|
13
|
+
type: "stable";
|
|
14
|
+
} | {
|
|
15
|
+
type: "review";
|
|
16
|
+
reviewSlug: StringOrBashExpression;
|
|
17
|
+
};
|
|
6
18
|
export type EnvironmentContext<B extends BuildConfig = BuildConfig, D extends DeployConfig = DeployConfig> = {
|
|
7
19
|
envConfigRaw: EnvConfigWithComponent;
|
|
8
20
|
buildConfigRaw: false | B;
|
|
9
21
|
deployConfigRaw: false | D;
|
|
10
22
|
env: string;
|
|
11
23
|
envType: EnvType;
|
|
24
|
+
/**
|
|
25
|
+
* the resolved autoStop config (component override, then project-wide
|
|
26
|
+
* environment config); undefined means the env type's default applies
|
|
27
|
+
*/
|
|
28
|
+
autoStop?: string | false;
|
|
29
|
+
/**
|
|
30
|
+
* the env whose secret values this env uses — the env itself unless
|
|
31
|
+
* it shares another env's secrets via `inherit`. All secret variable
|
|
32
|
+
* names are built with this env.
|
|
33
|
+
*/
|
|
34
|
+
secretsEnv: string;
|
|
12
35
|
componentName: string;
|
|
13
36
|
fullName: StringOrBashExpression;
|
|
14
37
|
/**
|
|
15
38
|
* the environment slug without component name.
|
|
16
39
|
*/
|
|
17
40
|
environmentSlugPrefix: StringOrBashExpression;
|
|
41
|
+
/**
|
|
42
|
+
* how the env is instantiated — `instance.type === "review"` is the
|
|
43
|
+
* way to find out whether this is a review app
|
|
44
|
+
*/
|
|
45
|
+
instance: EnvironmentInstance;
|
|
18
46
|
/**
|
|
19
47
|
* the review slug, if it is a review app, null otherwise
|
|
48
|
+
* @deprecated use `instance` — the review variant carries the slug
|
|
20
49
|
*/
|
|
21
50
|
reviewSlug: StringOrBashExpression | null;
|
|
22
51
|
/**
|
|
@@ -4,6 +4,33 @@ export { Retry, Image as GitlabJobImage } from "./gitlab-ci-yml";
|
|
|
4
4
|
export type Artifacts = GitlabCiArtifacts;
|
|
5
5
|
export type { GitlabJobCache };
|
|
6
6
|
export type GitlabRule = Exclude<Exclude<Rules, null>[number], string | string[]>;
|
|
7
|
+
/**
|
|
8
|
+
* gitlab's auto-cancel policy for redundant pipelines. Tunes the
|
|
9
|
+
* project setting "Auto-cancel redundant pipelines" (Settings > CI/CD >
|
|
10
|
+
* General pipelines) — it does NOT enable it: with the setting off,
|
|
11
|
+
* nothing is ever cancelled regardless of this.
|
|
12
|
+
*
|
|
13
|
+
* needs gitlab >= 16.8 (top-level) / >= 16.10 (per workflow rule).
|
|
14
|
+
*/
|
|
15
|
+
export interface GitlabAutoCancel {
|
|
16
|
+
/**
|
|
17
|
+
* - `conservative` (gitlab's default): cancel the whole pipeline, but
|
|
18
|
+
* only while no `interruptible: false` job has *started* — a single
|
|
19
|
+
* such job then shields every other job from cancellation
|
|
20
|
+
* - `interruptible`: cancel every `interruptible: true` job, with no
|
|
21
|
+
* such veto
|
|
22
|
+
* - `none`: never auto-cancel
|
|
23
|
+
*/
|
|
24
|
+
on_new_commit?: "conservative" | "interruptible" | "none";
|
|
25
|
+
on_job_failure?: "all" | "none";
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* a workflow rule may override {@link GitlabAutoCancel} per pipeline
|
|
29
|
+
* kind — job rules may not.
|
|
30
|
+
*/
|
|
31
|
+
export type GitlabWorkflowRule = GitlabRule & {
|
|
32
|
+
auto_cancel?: GitlabAutoCancel;
|
|
33
|
+
};
|
|
7
34
|
export type GitlabEnvironment = Omit<Exclude<JobTemplate["environment"], undefined | string>, "deployment_tier">;
|
|
8
35
|
export interface GitlabJobDef extends Pick<JobTemplate, "after_script" | "allow_failure" | "artifacts" | "before_script" | "coverage" | "dependencies" | "environment" | "except" | "hooks" | "image" | "interruptible" | "needs" | "only" | "parallel" | "release" | "resource_group" | "retry" | "rules" | "script" | "services" | "stage" | "tags" | "trigger" | "variables"> {
|
|
9
36
|
stage: JobTemplate["stage"];
|
|
@@ -23,8 +50,9 @@ export interface GitlabJobDef extends Pick<JobTemplate, "after_script" | "allow_
|
|
|
23
50
|
export interface GitlabPipeline extends Pick<JobTemplate, "variables"> {
|
|
24
51
|
image: string;
|
|
25
52
|
workflow?: {
|
|
26
|
-
rules: GitlabRule[];
|
|
27
53
|
name?: string;
|
|
54
|
+
auto_cancel?: GitlabAutoCancel;
|
|
55
|
+
rules: GitlabWorkflowRule[];
|
|
28
56
|
variables?: Record<string, string>;
|
|
29
57
|
};
|
|
30
58
|
stages: string[];
|
|
@@ -33,6 +33,10 @@ const config = {
|
|
|
33
33
|
appName: "my-app",
|
|
34
34
|
customerName: "pan",
|
|
35
35
|
pipelines: { gitlab: true, github: true }, // which CI systems to generate
|
|
36
|
+
environments: { // optional: project-wide env declarations/tuning
|
|
37
|
+
review: { autoStop: "3 days" },
|
|
38
|
+
next: { type: "dev", on: { branch: "next" } }, // extra branch-tracking env
|
|
39
|
+
},
|
|
36
40
|
components: {
|
|
37
41
|
www: {
|
|
38
42
|
dir: "frontend", // working directory of this component
|
|
@@ -59,8 +63,36 @@ Key concepts:
|
|
|
59
63
|
- **Environments**: `dev` (deployed on push to the main branch),
|
|
60
64
|
`review` (per merge/pull request), `stage` and `prod` (deployed on
|
|
61
65
|
tagged releases), `local` (only for local development via catenv).
|
|
62
|
-
|
|
63
|
-
|
|
66
|
+
Environments are project-wide: the top-level `environments` config
|
|
67
|
+
declares and tunes them consistently for all components, while
|
|
68
|
+
per-component `env.<name>` entries only carry component-local
|
|
69
|
+
overrides (vars, deploy settings, host, autoStop) or `false` to opt
|
|
70
|
+
the component out. In `environments`:
|
|
71
|
+
- `on` — when the env deploys: `"mainBranch"`, `"mr"`,
|
|
72
|
+
`"taggedRelease"`, `{ branch: "next" }` (a stable env deploying on
|
|
73
|
+
pushes to that branch), or `false` (in no pipeline). `on: "mr"`
|
|
74
|
+
makes an env a review app (one instance per MR/PR, torn down on
|
|
75
|
+
close). Defaults from the env type.
|
|
76
|
+
- `autoStop` — how long a stoppable environment stays up after its
|
|
77
|
+
last deploy before gitlab stops it (e.g. `"3 days"`; `false`
|
|
78
|
+
disables). Defaults: review `"1 week"`, dev `"4 weeks"`, others
|
|
79
|
+
never. GitLab only — github review apps stop when their PR closes.
|
|
80
|
+
Components can override it per env (`env.<name>.autoStop`).
|
|
81
|
+
- Extra envs are declared with any name plus a `type` — the env type
|
|
82
|
+
acts as a preset: it supplies all defaults (trigger, autoStop,
|
|
83
|
+
deploy policy) and the env's identity for tooling (`ENV_TYPE`),
|
|
84
|
+
everything overridable. Every component deploys to a declared env
|
|
85
|
+
unless it opts out:
|
|
86
|
+
`environments: { next: { type: "dev", on: { branch: "next" } } }`.
|
|
87
|
+
- `inherit` — make an env inherit from another env:
|
|
88
|
+
`inherit: "dev"` gives it dev's per-component config overrides
|
|
89
|
+
(merged below its own; `host` and `type` never inherit, the env
|
|
90
|
+
type is implied from the inherited env) AND dev's secret values —
|
|
91
|
+
all-or-nothing: its jobs reference dev's `CL_DEV_*` variables and
|
|
92
|
+
it has no secret store of its own (manage secrets via dev; rotating
|
|
93
|
+
affects both). The object form separates the axes:
|
|
94
|
+
`inherit: { config: "dev" }` inherits config only,
|
|
95
|
+
`inherit: { config: "dev", secrets: "dev" }` both.
|
|
64
96
|
- **Pipelines**: `pipelines: { gitlab: true, github: true }` selects
|
|
65
97
|
which CI systems get generated files. Options objects instead of
|
|
66
98
|
`true` allow per-pipeline settings (e.g. `runnerVariables`,
|
|
@@ -78,6 +78,11 @@ Everything app-level lives under `values`:
|
|
|
78
78
|
completion jobs, and always-on background worker pools.
|
|
79
79
|
- `cloudSql` — attach an (unmanaged) CloudSQL instance; choose the
|
|
80
80
|
connection-string format (`prisma` default, `rails`, `jdbc`).
|
|
81
|
+
`deleteDatabaseOnStop` controls whether the database is dropped when
|
|
82
|
+
the environment stops (default: true for review envs, false else).
|
|
83
|
+
- `revisionsToKeep` — how many inactive revisions (the rollback
|
|
84
|
+
history) the post-deploy cleanup keeps; older revisions and their
|
|
85
|
+
images are deleted. Default: 5 on prod envs, 0 everywhere else.
|
|
81
86
|
- `execute` — run a script/job/HTTP call at a deploy lifecycle point
|
|
82
87
|
(`preDeploy`/`postDeploy`/`preStop`/`postStop`) or on a `schedule`.
|
|
83
88
|
Prefer this over the deprecated `when`/`schedule` fields on `jobs`.
|
|
@@ -11,11 +11,20 @@ generated YAML.
|
|
|
11
11
|
|
|
12
12
|
## Triggers and environments
|
|
13
13
|
|
|
14
|
-
| Trigger | Runs on | Deploys to |
|
|
14
|
+
| Trigger | Runs on | Deploys to (default) |
|
|
15
15
|
|---|---|---|
|
|
16
16
|
| `mainBranch` | push to the main branch | `dev` |
|
|
17
17
|
| `mr` | merge/pull requests | `review` (one app per MR/PR) |
|
|
18
18
|
| `taggedRelease` | git tags | `stage`, `prod` |
|
|
19
|
+
| `{ branch: "<name>" }` | push to that branch | envs declaring it via `on` |
|
|
20
|
+
|
|
21
|
+
The trigger of each env is its `on` in the top-level `environments`
|
|
22
|
+
config (project-wide — components cannot diverge), defaulting from the
|
|
23
|
+
env type as in the table. An env with `on: { branch: "next" }` gets its
|
|
24
|
+
own pipeline (gitlab: rules on `$CI_COMMIT_BRANCH`; github: a
|
|
25
|
+
`catladder-branch-<name>.yml` workflow) and deploys as one stable,
|
|
26
|
+
branch-tracking environment — unlike review apps, it is not
|
|
27
|
+
per-instance and is stopped via the manual stop job/workflow.
|
|
19
28
|
|
|
20
29
|
Generated layout:
|
|
21
30
|
|
|
@@ -37,6 +46,38 @@ Generated layout:
|
|
|
37
46
|
Stages: setup → test → build → deploy → verify (post-deploy checks),
|
|
38
47
|
plus stop jobs for review-app teardown.
|
|
39
48
|
|
|
49
|
+
## Superseded pipelines are cancelled
|
|
50
|
+
|
|
51
|
+
Pushing a new commit cancels the pipeline of the previous one, so the
|
|
52
|
+
runners are not busy with results nobody will read.
|
|
53
|
+
|
|
54
|
+
| Pipeline | On a new commit |
|
|
55
|
+
|---|---|
|
|
56
|
+
| `mr` | cancelled |
|
|
57
|
+
| `mainBranch` (dev) | cancelled, except a release already running |
|
|
58
|
+
| `taggedRelease` | **runs through** — never cancelled |
|
|
59
|
+
| agent runs (`trigger`) | **runs through** — never cancelled |
|
|
60
|
+
|
|
61
|
+
- **GitHub**: the generated MR workflow sets `concurrency` with
|
|
62
|
+
`cancel-in-progress: true`.
|
|
63
|
+
- **GitLab**: generated `workflow:auto_cancel:on_new_commit:
|
|
64
|
+
interruptible`, with per-rule `none` for tags and agent runs. Every
|
|
65
|
+
job carries an explicit `interruptible`, jobs that must finish
|
|
66
|
+
(release jobs, agent jobs) carry `interruptible: false`.
|
|
67
|
+
|
|
68
|
+
**GitLab requires the project setting too.** The generated YAML only
|
|
69
|
+
tunes *how* redundant pipelines are cancelled — it does not switch the
|
|
70
|
+
feature on. If old pipelines keep running, check **Settings > CI/CD >
|
|
71
|
+
General pipelines > Auto-cancel redundant pipelines**; with that
|
|
72
|
+
checkbox off nothing is ever cancelled. (`catladder project-doctor`
|
|
73
|
+
does not check this.)
|
|
74
|
+
|
|
75
|
+
**Adding a hand-written GitLab job?** Set `interruptible` explicitly.
|
|
76
|
+
GitLab defaults it to `false`, and a non-interruptible job that has
|
|
77
|
+
started keeps *itself* alive — under gitlab's own default
|
|
78
|
+
(`conservative`, which catladder overrides) it would shield the whole
|
|
79
|
+
pipeline from cancellation.
|
|
80
|
+
|
|
40
81
|
## Review-app auto-stop and pinning (GitLab)
|
|
41
82
|
|
|
42
83
|
GitLab review environments stop automatically after 1 week, dev
|
|
@@ -38,6 +38,12 @@ files in the repo. All secrets commands accept a **scope**:
|
|
|
38
38
|
`dev:web` (one env of one component), `dev:` (one env, all
|
|
39
39
|
components), `:web` (all envs of one component), or nothing (everything).
|
|
40
40
|
|
|
41
|
+
An env that shares another env's secrets (top-level
|
|
42
|
+
`environments.<name>.inherit`, e.g. a `next` branch env inheriting from
|
|
43
|
+
dev) has **no secret store of its own** — its jobs reference the source
|
|
44
|
+
env's variables directly, so it never appears in secrets scopes: manage
|
|
45
|
+
(and rotate) the values via the source env, which affects both.
|
|
46
|
+
|
|
41
47
|
Check what is declared and what is still unset (never prints values
|
|
42
48
|
unless `--reveal` is passed):
|
|
43
49
|
|