@catladder/cli 5.2.0 → 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.
Files changed (88) hide show
  1. package/dist/apps/cli/src/commands/project/commandPortForward.js +1 -1
  2. package/dist/apps/cli/src/commands/project/commandPortForward.js.map +1 -1
  3. package/dist/apps/cli/src/commands/project/secrets/scope.js +25 -2
  4. package/dist/apps/cli/src/commands/project/secrets/scope.js.map +1 -1
  5. package/dist/apps/cli/src/config/getProjectConfig.js +4 -1
  6. package/dist/apps/cli/src/config/getProjectConfig.js.map +1 -1
  7. package/dist/apps/cli/src/secrets/github.js +4 -2
  8. package/dist/apps/cli/src/secrets/github.js.map +1 -1
  9. package/dist/bundles/catenv/index.js +390 -106
  10. package/dist/bundles/cli/index.js +420 -111
  11. package/dist/bundles/skills/catladder-config/SKILL.md +34 -2
  12. package/dist/bundles/skills/catladder-deploys/SKILL.md +5 -0
  13. package/dist/bundles/skills/catladder-pipelines/SKILL.md +10 -1
  14. package/dist/bundles/skills/catladder-secrets/SKILL.md +6 -0
  15. package/dist/packages/pipeline/src/backends/github/GithubBackend.js +23 -3
  16. package/dist/packages/pipeline/src/backends/github/GithubBackend.js.map +1 -1
  17. package/dist/packages/pipeline/src/backends/github/createGithubJobs.js +2 -2
  18. package/dist/packages/pipeline/src/backends/github/createGithubJobs.js.map +1 -1
  19. package/dist/packages/pipeline/src/backends/gitlab/GitlabBackend.js +18 -2
  20. package/dist/packages/pipeline/src/backends/gitlab/GitlabBackend.js.map +1 -1
  21. package/dist/packages/pipeline/src/backends/gitlab/createGitlabJobs.js +2 -2
  22. package/dist/packages/pipeline/src/backends/gitlab/createGitlabJobs.js.map +1 -1
  23. package/dist/packages/pipeline/src/backends/gitlab/createGitlabPipeline.d.ts +6 -1
  24. package/dist/packages/pipeline/src/backends/gitlab/createGitlabPipeline.js +8 -1
  25. package/dist/packages/pipeline/src/backends/gitlab/createGitlabPipeline.js.map +1 -1
  26. package/dist/packages/pipeline/src/config/configruedEnvs.d.ts +9 -2
  27. package/dist/packages/pipeline/src/config/configruedEnvs.js +54 -5
  28. package/dist/packages/pipeline/src/config/configruedEnvs.js.map +1 -1
  29. package/dist/packages/pipeline/src/context/createAllComponentsContext.d.ts +2 -2
  30. package/dist/packages/pipeline/src/context/createComponentContext.d.ts +2 -2
  31. package/dist/packages/pipeline/src/context/createWorkspaceContext.d.ts +2 -2
  32. package/dist/packages/pipeline/src/context/getEnvConfig.js +35 -19
  33. package/dist/packages/pipeline/src/context/getEnvConfig.js.map +1 -1
  34. package/dist/packages/pipeline/src/context/getEnvInherit.d.ts +20 -0
  35. package/dist/packages/pipeline/src/context/getEnvInherit.js +72 -0
  36. package/dist/packages/pipeline/src/context/getEnvInherit.js.map +1 -0
  37. package/dist/packages/pipeline/src/context/getEnvInstance.d.ts +4 -0
  38. package/dist/packages/pipeline/src/context/{getReviewSlug.js → getEnvInstance.js} +13 -9
  39. package/dist/packages/pipeline/src/context/getEnvInstance.js.map +1 -0
  40. package/dist/packages/pipeline/src/context/getEnvOn.d.ts +13 -0
  41. package/dist/packages/pipeline/src/context/getEnvOn.js +28 -0
  42. package/dist/packages/pipeline/src/context/getEnvOn.js.map +1 -0
  43. package/dist/packages/pipeline/src/context/getEnvType.d.ts +8 -2
  44. package/dist/packages/pipeline/src/context/getEnvType.js +27 -5
  45. package/dist/packages/pipeline/src/context/getEnvType.js.map +1 -1
  46. package/dist/packages/pipeline/src/context/getEnvironment.js +3 -0
  47. package/dist/packages/pipeline/src/context/getEnvironment.js.map +1 -1
  48. package/dist/packages/pipeline/src/context/getEnvironmentContext.js +18 -8
  49. package/dist/packages/pipeline/src/context/getEnvironmentContext.js.map +1 -1
  50. package/dist/packages/pipeline/src/context/getEnvironmentVariables.d.ts +1 -1
  51. package/dist/packages/pipeline/src/context/getEnvironmentVariables.js +4 -4
  52. package/dist/packages/pipeline/src/context/getEnvironmentVariables.js.map +1 -1
  53. package/dist/packages/pipeline/src/context/index.d.ts +1 -0
  54. package/dist/packages/pipeline/src/context/index.js +1 -0
  55. package/dist/packages/pipeline/src/context/index.js.map +1 -1
  56. package/dist/packages/pipeline/src/deploy/base/deploy.js +11 -1
  57. package/dist/packages/pipeline/src/deploy/base/deploy.js.map +1 -1
  58. package/dist/packages/pipeline/src/deploy/cloudRun/artifactsRegistry.js +5 -4
  59. package/dist/packages/pipeline/src/deploy/cloudRun/artifactsRegistry.js.map +1 -1
  60. package/dist/packages/pipeline/src/deploy/cloudRun/cleanup.js +8 -2
  61. package/dist/packages/pipeline/src/deploy/cloudRun/cleanup.js.map +1 -1
  62. package/dist/packages/pipeline/src/deploy/cloudRun/index.js +2 -2
  63. package/dist/packages/pipeline/src/deploy/cloudRun/index.js.map +1 -1
  64. package/dist/packages/pipeline/src/deploy/cloudRun/utils/getServiceName.js +2 -2
  65. package/dist/packages/pipeline/src/deploy/cloudRun/utils/getServiceName.js.map +1 -1
  66. package/dist/packages/pipeline/src/deploy/kubernetes/index.js +3 -3
  67. package/dist/packages/pipeline/src/deploy/kubernetes/index.js.map +1 -1
  68. package/dist/packages/pipeline/src/deploy/pages/deployJob.js +3 -2
  69. package/dist/packages/pipeline/src/deploy/pages/deployJob.js.map +1 -1
  70. package/dist/packages/pipeline/src/deploy/types/googleCloudRun.d.ts +9 -0
  71. package/dist/packages/pipeline/src/types/config.d.ts +126 -9
  72. package/dist/packages/pipeline/src/types/config.js +11 -10
  73. package/dist/packages/pipeline/src/types/config.js.map +1 -1
  74. package/dist/packages/pipeline/src/types/context.d.ts +22 -3
  75. package/dist/packages/pipeline/src/types/context.js.map +1 -1
  76. package/dist/packages/pipeline/src/types/environmentContext.d.ts +29 -0
  77. package/dist/skills/catladder-config/SKILL.md +34 -2
  78. package/dist/skills/catladder-deploys/SKILL.md +5 -0
  79. package/dist/skills/catladder-pipelines/SKILL.md +10 -1
  80. package/dist/skills/catladder-secrets/SKILL.md +6 -0
  81. package/dist/tsconfig.tsbuildinfo +1 -1
  82. package/package.json +1 -1
  83. package/src/commands/project/commandPortForward.ts +1 -1
  84. package/src/commands/project/secrets/scope.ts +38 -2
  85. package/src/config/getProjectConfig.ts +9 -1
  86. package/src/secrets/github.ts +8 -5
  87. package/dist/packages/pipeline/src/context/getReviewSlug.d.ts +0 -4
  88. package/dist/packages/pipeline/src/context/getReviewSlug.js.map +0 -1
@@ -756,7 +756,10 @@ const getEnvironment = async (env, componentName) => {
756
756
  };
757
757
  exports.getEnvironment = getEnvironment;
758
758
  const getGitlabVar = async (io, env, componentName, variableName) => {
759
- const rawVariableName = (0, pipeline_1.getSecretVarName)(env, componentName, variableName);
759
+ const config = await (0, exports.getProjectConfig)();
760
+ // an env sharing another env's secrets (inherit) reads that env's variables
761
+ const secretsEnv = (0, pipeline_1.getSecretsEnv)(config === null || config === void 0 ? void 0 : config.environments, env);
762
+ const rawVariableName = (0, pipeline_1.getSecretVarName)(secretsEnv, componentName, variableName);
760
763
  return await (0, gitlab_1.getVariableValueByRawName)(io, rawVariableName);
761
764
  };
762
765
  exports.getGitlabVar = getGitlabVar;
@@ -2641,6 +2644,7 @@ const promises_1 = __nccwpck_require__(91943);
2641
2644
  const path_1 = __nccwpck_require__(16928);
2642
2645
  const createAllJobs_1 = __nccwpck_require__(83477);
2643
2646
  const config_1 = __nccwpck_require__(75591);
2647
+ const configruedEnvs_1 = __nccwpck_require__(38866);
2644
2648
  const ciVariables_1 = __nccwpck_require__(17300);
2645
2649
  const registryImage_1 = __nccwpck_require__(24333);
2646
2650
  const index_1 = __nccwpck_require__(62853);
@@ -2693,6 +2697,12 @@ const TRIGGER_WORKFLOWS = {
2693
2697
  },
2694
2698
  },
2695
2699
  };
2700
+ const getTriggerWorkflow = (trigger) => (0, config_1.isBranchTrigger)(trigger)
2701
+ ? {
2702
+ name: `🛠️ catladder ${trigger.branch}`,
2703
+ on: { push: { branches: [trigger.branch] } },
2704
+ }
2705
+ : TRIGGER_WORKFLOWS[trigger];
2696
2706
  class GithubBackend {
2697
2707
  constructor() {
2698
2708
  this.type = "github";
@@ -2753,7 +2763,13 @@ class GithubBackend {
2753
2763
  stop: { jobs: {}, conditions: {}, options: [], envTypes: [] },
2754
2764
  rollback: { jobs: {}, conditions: {}, options: [], envTypes: [] },
2755
2765
  };
2756
- for (const trigger of config_1.ALL_PIPELINE_TRIGGERS) {
2766
+ // branch triggers (envs with `on: { branch: ... }`) each get their
2767
+ // own push-triggered workflow next to the built-in ones
2768
+ const allTriggers = [
2769
+ ...config_1.ALL_PIPELINE_TRIGGERS,
2770
+ ...(0, configruedEnvs_1.getConfiguredBranchTriggers)(config),
2771
+ ];
2772
+ for (const trigger of allTriggers) {
2757
2773
  const allJobs = await (0, createAllJobs_1.createAllJobs)({
2758
2774
  config,
2759
2775
  trigger,
@@ -2880,7 +2896,7 @@ class GithubBackend {
2880
2896
  if (Object.keys(jobs).length > 0) {
2881
2897
  const workflowJobs = { ...(0, ensureImageJobs_1.makeEnsureImageGithubJobs)(images), ...jobs };
2882
2898
  workflows[`${GENERATED_FILE_PREFIX}${workflowFileName(trigger)}`] = {
2883
- ...TRIGGER_WORKFLOWS[trigger],
2899
+ ...getTriggerWorkflow(trigger),
2884
2900
  ...workflowPermissions(images),
2885
2901
  env: workflowEnv,
2886
2902
  // the review workflow additionally gets the aggregate job —
@@ -2980,6 +2996,11 @@ const workflowPermissions = (_images) => ({
2980
2996
  permissions: { contents: "read", packages: "write" },
2981
2997
  });
2982
2998
  const workflowFileName = (trigger) => {
2999
+ if ((0, config_1.isBranchTrigger)(trigger)) {
3000
+ // branch names may contain characters that don't belong in a file
3001
+ // name (e.g. "release/next")
3002
+ return `branch-${trigger.branch.replace(/[^a-zA-Z0-9]+/g, "-")}.yml`;
3003
+ }
2983
3004
  switch (trigger) {
2984
3005
  case "mr":
2985
3006
  return "review.yml";
@@ -2998,7 +3019,9 @@ const isReviewStopJob = (context, job) => {
2998
3019
  var _a;
2999
3020
  return ((_a = job.environment) === null || _a === void 0 ? void 0 : _a.action) === "stop" &&
3000
3021
  context.type === "component" &&
3001
- context.environment.envType === "review";
3022
+ // a review app (one instance per pull request) is torn down when its
3023
+ // pull request closes; stable envs get dispatch-triggered stop jobs
3024
+ context.environment.instance.type === "review";
3002
3025
  };
3003
3026
  /**
3004
3027
  * stop/rollback jobs of non-review environments have no automatic
@@ -3329,7 +3352,7 @@ const collectSecretKinds = (allJobs) => {
3329
3352
  ...((_a = context.environment.jobOnlyVars.build.secretEnvVarKeys) !== null && _a !== void 0 ? _a : []),
3330
3353
  ...((_b = context.environment.jobOnlyVars.deploy.secretEnvVarKeys) !== null && _b !== void 0 ? _b : []),
3331
3354
  ];
3332
- entries.forEach(({ key, kind }) => kinds.set((0, getEnvironmentVariables_1.getSecretVarName)(context.env, context.name, key), kind !== null && kind !== void 0 ? kind : "secret"));
3355
+ entries.forEach(({ key, kind }) => kinds.set((0, getEnvironmentVariables_1.getSecretVarName)(context.environment.secretsEnv, context.name, key), kind !== null && kind !== void 0 ? kind : "secret"));
3333
3356
  });
3334
3357
  return kinds;
3335
3358
  };
@@ -3342,7 +3365,7 @@ const getSecretsEnv = (context, kinds) => {
3342
3365
  ...((_b = context.environment.jobOnlyVars.deploy.secretEnvVarKeys) !== null && _b !== void 0 ? _b : []),
3343
3366
  ];
3344
3367
  return Object.fromEntries(keys.map(({ key }) => {
3345
- const name = (0, getEnvironmentVariables_1.getSecretVarName)(context.env, context.name, key);
3368
+ const name = (0, getEnvironmentVariables_1.getSecretVarName)(context.environment.secretsEnv, context.name, key);
3346
3369
  return [name, vaultValueExpression(name, kinds)];
3347
3370
  }));
3348
3371
  };
@@ -4141,6 +4164,7 @@ exports.GitlabBackend = void 0;
4141
4164
  const promises_1 = __nccwpck_require__(91943);
4142
4165
  const rules_1 = __nccwpck_require__(78503);
4143
4166
  const config_1 = __nccwpck_require__(75591);
4167
+ const configruedEnvs_1 = __nccwpck_require__(38866);
4144
4168
  const autoStop_1 = __nccwpck_require__(72792);
4145
4169
  const createAllJobs_1 = __nccwpck_require__(83477);
4146
4170
  const jobImagesPlan_1 = __nccwpck_require__(59623);
@@ -4248,8 +4272,15 @@ class GitlabBackend {
4248
4272
  // release jobs themselves are created afterwards — they need the
4249
4273
  // main-branch job list for the queued-release executor's needs.
4250
4274
  images.resolveRef({ catladderImage: (0, release_1.getReleaseMethod)(config).image });
4251
- // for all triggers create jobs and add base rules
4252
- const jobsPerTrigger = await Promise.all(config_1.ALL_PIPELINE_TRIGGERS.map(async (trigger) => ({
4275
+ // for all triggers create jobs and add base rules. Branch triggers
4276
+ // (envs with `on: { branch: ... }`) each get their own pipeline next
4277
+ // to the built-in ones.
4278
+ const branchTriggers = (0, configruedEnvs_1.getConfiguredBranchTriggers)(config);
4279
+ const allTriggers = [
4280
+ ...config_1.ALL_PIPELINE_TRIGGERS,
4281
+ ...branchTriggers,
4282
+ ];
4283
+ const jobsPerTrigger = await Promise.all(allTriggers.map(async (trigger) => ({
4253
4284
  trigger,
4254
4285
  jobs: await (0, createGitlabJobs_1.createGitlabJobs)(await (0, createAllJobs_1.createAllJobs)({ config, trigger, pipelineType: this.type }), images, getGitlabRulesForTrigger(trigger)),
4255
4286
  })));
@@ -4327,6 +4358,7 @@ class GitlabBackend {
4327
4358
  // per-pipeline-type variables (pipelines.gitlab.runnerVariables)
4328
4359
  ...(0, index_1.getPipelineOptions)(config, this.type).runnerVariables,
4329
4360
  },
4361
+ branchPipelines: branchTriggers.map(({ branch }) => branch),
4330
4362
  autoStop: (0, autoStop_1.getAutoStopConfig)(config),
4331
4363
  });
4332
4364
  }
@@ -4344,6 +4376,13 @@ function getGitlabRulesForTrigger(trigger) {
4344
4376
  // mainBranch: on push to main branch except it's a release commit
4345
4377
  // mr: on merge request
4346
4378
  // taggedRelease: on tag
4379
+ // { branch }: on push to that specific branch
4380
+ if ((0, config_1.isBranchTrigger)(trigger)) {
4381
+ return [
4382
+ rules_1.RULE_NEVER_ON_AGENT_TRIGGER,
4383
+ { if: `$CI_COMMIT_BRANCH == "${trigger.branch}"` },
4384
+ ];
4385
+ }
4347
4386
  switch (trigger) {
4348
4387
  case "mainBranch":
4349
4388
  return [
@@ -4596,7 +4635,7 @@ const addGitlabEnvironment = (context, catladderJobEnvironment, job, allJobs) =>
4596
4635
  return job;
4597
4636
  }
4598
4637
  const { env, name, environment } = context;
4599
- const { envVars, envType } = environment;
4638
+ const { envVars, instance } = environment;
4600
4639
  const { onStop, autoStopIn, action } = catladderJobEnvironment;
4601
4640
  // those can be dynamic, so we therefore have to do this: https://docs.gitlab.com/ee/ci/environments/#set-a-dynamic-environment-url
4602
4641
  const dotEnvFile = "gitlab_environment.env";
@@ -4613,7 +4652,7 @@ const addGitlabEnvironment = (context, catladderJobEnvironment, job, allJobs) =>
4613
4652
  `echo "${exports.GITLAB_ENVIRONMENT_URL_VARIABLE}=${(0, bash_1.getBashVariable)("ROOT_URL")}" >> ${dotEnvFile}`,
4614
4653
  ];
4615
4654
  // this is NOT a bashVariable since it NEEDS to be used as a string in gitlab
4616
- const gitlabEnvironmentName = envType === "review"
4655
+ const gitlabEnvironmentName = instance.type === "review"
4617
4656
  ? `${env}/$CI_COMMIT_REF_NAME/${name}` // FIXME: should be replaced with mr name as well
4618
4657
  : `${env}/${name}`;
4619
4658
  return {
@@ -4781,7 +4820,7 @@ const rules_1 = __nccwpck_require__(78503);
4781
4820
  * build-free image (a catladder job image would drag in a build job).
4782
4821
  */
4783
4822
  const DEFAULT_PIPELINE_IMAGE = "node:22";
4784
- const createGitlabPipelineWithDefaults = ({ image, variables, before_script, autoStop, ...config }) => {
4823
+ const createGitlabPipelineWithDefaults = ({ image, variables, before_script, branchPipelines = [], autoStop, ...config }) => {
4785
4824
  const pinLabel = autoStop && autoStop.pinLabel;
4786
4825
  return {
4787
4826
  image: image !== null && image !== void 0 ? image : DEFAULT_PIPELINE_IMAGE,
@@ -4862,6 +4901,13 @@ const createGitlabPipelineWithDefaults = ({ image, variables, before_script, aut
4862
4901
  PIPELINE_NAME: "Main - $CI_COMMIT_TITLE",
4863
4902
  },
4864
4903
  },
4904
+ ...branchPipelines.map((branch) => ({
4905
+ if: `$CI_COMMIT_BRANCH == "${branch}"`,
4906
+ variables: {
4907
+ PIPELINE_ICON: "🐱🔨",
4908
+ PIPELINE_NAME: `${branch} - $CI_COMMIT_TITLE`,
4909
+ },
4910
+ })),
4865
4911
  {
4866
4912
  when: "always", // fallback
4867
4913
  variables: {
@@ -7288,8 +7334,10 @@ exports.createCatenvContext = createCatenvContext;
7288
7334
  "use strict";
7289
7335
 
7290
7336
  Object.defineProperty(exports, "__esModule", ({ value: true }));
7291
- exports.getAllEnvsByTrigger = exports.getAllEnvsInAllComponents = exports.getAllEnvs = void 0;
7337
+ exports.getConfiguredBranchTriggers = exports.getAllEnvsByTrigger = exports.getAllEnvsInAllComponents = exports.getAllEnvs = void 0;
7292
7338
  const types_1 = __nccwpck_require__(63557);
7339
+ const getEnvOn_1 = __nccwpck_require__(60601);
7340
+ const getEnvType_1 = __nccwpck_require__(46080);
7293
7341
  const getConfiguredAndDefaultEnvs = (config, componentName, envTypes) => {
7294
7342
  var _a, _b;
7295
7343
  const configuredEnvs = (_a = config.components[componentName].env) !== null && _a !== void 0 ? _a : {};
@@ -7297,13 +7345,33 @@ const getConfiguredAndDefaultEnvs = (config, componentName, envTypes) => {
7297
7345
  // these can be disabled with settimg them to `false`
7298
7346
  // this is the list of all not disabled envs. These are always returned
7299
7347
  const enabledDefaultEnvs = envTypes.filter((e) => configuredEnvs[e] !== false);
7300
- const configuredCustomEnvs = Object.entries((_b = config.components[componentName].env) !== null && _b !== void 0 ? _b : {})
7348
+ // envs declared project-wide (top-level `environments`): every
7349
+ // component deploys to them unless it opts out with `env.<name>: false`
7350
+ const declaredEnvs = Object.keys((_b = config.environments) !== null && _b !== void 0 ? _b : {})
7351
+ .filter((envName) => !(0, types_1.isKnowEnvType)(envName)) // default envs are already handled above
7352
+ .map((envName) => {
7353
+ const envType = (0, getEnvType_1.getDeclaredEnvType)(config.environments, envName);
7354
+ if (!envType) {
7355
+ throw new Error(`environment "${envName}" needs a type (dev, review, stage, prod) or an inherit`);
7356
+ }
7357
+ return [envName, envType];
7358
+ })
7359
+ .filter(([envName, envType]) => envTypes.includes(envType) && configuredEnvs[envName] !== false)
7360
+ .map(([envName]) => envName);
7361
+ // legacy: custom envs declared per component via their `type`
7362
+ const configuredCustomEnvs = Object.entries(configuredEnvs)
7301
7363
  .filter(([, config]) => config &&
7302
7364
  "type" in config &&
7303
7365
  config.type &&
7304
7366
  envTypes.includes(config.type))
7305
7367
  .map(([envName]) => envName);
7306
- return [...new Set([...enabledDefaultEnvs, ...configuredCustomEnvs])];
7368
+ return [
7369
+ ...new Set([
7370
+ ...enabledDefaultEnvs,
7371
+ ...declaredEnvs,
7372
+ ...configuredCustomEnvs,
7373
+ ]),
7374
+ ];
7307
7375
  };
7308
7376
  const getAllEnvs = (config, componentName) => {
7309
7377
  return getConfiguredAndDefaultEnvs(config, componentName, types_1.DEFAULT_ENV_TYPES);
@@ -7315,11 +7383,38 @@ const getAllEnvsInAllComponents = (config) => {
7315
7383
  ];
7316
7384
  };
7317
7385
  exports.getAllEnvsInAllComponents = getAllEnvsInAllComponents;
7386
+ /**
7387
+ * the resolved `on` of one env of a component (the project-wide `on`
7388
+ * of the env, falling back to the env type's default trigger)
7389
+ */
7390
+ const getEnvOnForComponentEnv = (config, componentName, env) => {
7391
+ var _a;
7392
+ const entry = (_a = config.components[componentName].env) === null || _a === void 0 ? void 0 : _a[env];
7393
+ return (0, getEnvOn_1.getEnvOn)(env, entry && entry !== false ? entry : {}, config.environments);
7394
+ };
7318
7395
  const getAllEnvsByTrigger = (config, componentName, trigger) => {
7319
- const envTypesByTrigger = (0, types_1.getEnvTypesByTrigger)(trigger);
7320
- return getConfiguredAndDefaultEnvs(config, componentName, envTypesByTrigger);
7396
+ return (0, exports.getAllEnvs)(config, componentName).filter((env) => (0, types_1.envTriggerEquals)(getEnvOnForComponentEnv(config, componentName, env), trigger));
7321
7397
  };
7322
7398
  exports.getAllEnvsByTrigger = getAllEnvsByTrigger;
7399
+ /**
7400
+ * all branch triggers declared by any env of any component (via
7401
+ * `on: { branch: "..." }`), deduplicated and sorted for deterministic
7402
+ * pipeline generation. Each gets its own pipeline next to the built-in
7403
+ * triggers.
7404
+ */
7405
+ const getConfiguredBranchTriggers = (config) => {
7406
+ const branches = new Set();
7407
+ for (const componentName of Object.keys(config.components)) {
7408
+ for (const env of (0, exports.getAllEnvs)(config, componentName)) {
7409
+ const on = getEnvOnForComponentEnv(config, componentName, env);
7410
+ if (on && (0, types_1.isBranchTrigger)(on)) {
7411
+ branches.add(on.branch);
7412
+ }
7413
+ }
7414
+ }
7415
+ return [...branches].sort().map((branch) => ({ branch }));
7416
+ };
7417
+ exports.getConfiguredBranchTriggers = getConfiguredBranchTriggers;
7323
7418
  //# sourceMappingURL=configruedEnvs.js.map
7324
7419
 
7325
7420
  /***/ }),
@@ -7650,53 +7745,237 @@ exports.getBuildInfoVariables = getBuildInfoVariables;
7650
7745
  Object.defineProperty(exports, "__esModule", ({ value: true }));
7651
7746
  exports.getEnvConfig = void 0;
7652
7747
  const lodash_es_1 = __nccwpck_require__(50210);
7748
+ const getEnvInherit_1 = __nccwpck_require__(52181);
7653
7749
  const getEnvConfig = (config, componentName, env) => {
7654
- var _a, _b;
7750
+ var _a;
7655
7751
  const defaultConfig = config.components[componentName];
7656
7752
  if (!defaultConfig) {
7657
7753
  throw new Error("unknown component " + componentName);
7658
7754
  }
7659
- const envCustomizations = (_b = (_a = defaultConfig.env) === null || _a === void 0 ? void 0 : _a[env]) !== null && _b !== void 0 ? _b : {};
7660
- if (envCustomizations === false) {
7661
- // env is disabled, still return the default config
7662
- return defaultConfig;
7663
- }
7664
- /**
7665
- * env config is merged with default. Arrays are not merged.
7666
- * you can customize this by providing a function that takes the default value as argument
7667
- */
7668
- return (0, lodash_es_1.mergeWith)(
7755
+ // env config is layered onto the component config: the per-component
7756
+ // overrides of inherited envs first (oldest ancestor first, see
7757
+ // `environments.<name>.inherit`), the env's own overrides last
7758
+ const chain = [...(0, getEnvInherit_1.getInheritedConfigChain)(config.environments, env), env];
7669
7759
  // mergeWith unfortunatly mutates the first object, so we need to clone it.
7670
7760
  // Passing empty object also doesn't work for us, because that will mess with the customizer function (second argument isn't nessecary the customized value)
7671
- (0, lodash_es_1.cloneDeep)(defaultConfig), envCustomizations, (defaultValue, customValue, key, obj, source) => {
7672
- // check if custom value is a function (and default is not),
7673
- // we currently don't have config options, that are functions, but we might in the future (customJobs is an exception)
7674
- if (typeof customValue === "function" &&
7675
- typeof defaultValue !== "function") {
7676
- return customValue(defaultValue);
7761
+ const result = (0, lodash_es_1.cloneDeep)(defaultConfig);
7762
+ for (const chainEnv of chain) {
7763
+ const envCustomizations = (_a = defaultConfig.env) === null || _a === void 0 ? void 0 : _a[chainEnv];
7764
+ if (!envCustomizations || envCustomizations === false) {
7765
+ if (chainEnv === env && envCustomizations === false) {
7766
+ // env is disabled, still return the default config
7767
+ return defaultConfig;
7768
+ }
7769
+ continue;
7677
7770
  }
7678
- return undefined;
7679
- });
7771
+ /**
7772
+ * env config is merged with default. Arrays are not merged.
7773
+ * you can customize this by providing a function that takes the default value as argument
7774
+ */
7775
+ (0, lodash_es_1.mergeWith)(result,
7776
+ // `host` must stay unique per env and `type` is the inherited
7777
+ // env's identity — neither is inherited
7778
+ chainEnv === env
7779
+ ? envCustomizations
7780
+ : (0, lodash_es_1.omit)(envCustomizations, ["host", "type"]), (defaultValue, customValue, key, obj, source) => {
7781
+ // check if custom value is a function (and default is not),
7782
+ // we currently don't have config options, that are functions, but we might in the future (customJobs is an exception)
7783
+ if (typeof customValue === "function" &&
7784
+ typeof defaultValue !== "function") {
7785
+ return customValue(defaultValue);
7786
+ }
7787
+ return undefined;
7788
+ });
7789
+ }
7790
+ return result;
7680
7791
  };
7681
7792
  exports.getEnvConfig = getEnvConfig;
7682
7793
  //# sourceMappingURL=getEnvConfig.js.map
7683
7794
 
7684
7795
  /***/ }),
7685
7796
 
7797
+ /***/ 52181:
7798
+ /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
7799
+
7800
+ "use strict";
7801
+
7802
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
7803
+ exports.getSecretsEnv = exports.getInheritedConfigChain = exports.normalizeEnvInherit = void 0;
7804
+ const config_1 = __nccwpck_require__(75591);
7805
+ const normalizeEnvInherit = (inherit) => {
7806
+ if (!inherit)
7807
+ return {};
7808
+ if (typeof inherit === "string") {
7809
+ return { config: inherit, secrets: inherit };
7810
+ }
7811
+ return {
7812
+ config: inherit.config,
7813
+ secrets: inherit.secrets === false ? undefined : inherit.secrets,
7814
+ };
7815
+ };
7816
+ exports.normalizeEnvInherit = normalizeEnvInherit;
7817
+ const assertValidInheritTarget = (environments, env, target) => {
7818
+ if (target === "local") {
7819
+ throw new Error(`environment "${env}" cannot inherit from "local" — local is not a deployment environment`);
7820
+ }
7821
+ if (!(0, config_1.isKnowEnvType)(target) && !(environments === null || environments === void 0 ? void 0 : environments[target])) {
7822
+ throw new Error(`environment "${env}" inherits from unknown environment "${target}"`);
7823
+ }
7824
+ };
7825
+ /**
7826
+ * the chain of envs whose per-component config overrides feed into
7827
+ * `env`, oldest ancestor first (env itself not included). Cycles and
7828
+ * unknown/`local` targets are an error.
7829
+ */
7830
+ const getInheritedConfigChain = (environments, env) => {
7831
+ var _a;
7832
+ const chain = [];
7833
+ const seen = new Set([env]);
7834
+ let current = env;
7835
+ for (;;) {
7836
+ const target = (0, exports.normalizeEnvInherit)((_a = environments === null || environments === void 0 ? void 0 : environments[current]) === null || _a === void 0 ? void 0 : _a.inherit).config;
7837
+ if (!target)
7838
+ break;
7839
+ assertValidInheritTarget(environments, current, target);
7840
+ if (seen.has(target)) {
7841
+ throw new Error(`environment "${env}" has a cyclic config inheritance via "${target}"`);
7842
+ }
7843
+ seen.add(target);
7844
+ chain.unshift(target);
7845
+ current = target;
7846
+ }
7847
+ return chain;
7848
+ };
7849
+ exports.getInheritedConfigChain = getInheritedConfigChain;
7850
+ /**
7851
+ * the env whose secret values `env` uses (follows `inherit` secret
7852
+ * sharing transitively; the env itself when it has its own secrets).
7853
+ * All secret variable names must be built with this env.
7854
+ */
7855
+ const getSecretsEnv = (environments, env) => {
7856
+ var _a;
7857
+ const seen = new Set([env]);
7858
+ let current = env;
7859
+ for (;;) {
7860
+ const target = (0, exports.normalizeEnvInherit)((_a = environments === null || environments === void 0 ? void 0 : environments[current]) === null || _a === void 0 ? void 0 : _a.inherit).secrets;
7861
+ if (!target)
7862
+ return current;
7863
+ assertValidInheritTarget(environments, current, target);
7864
+ if (seen.has(target)) {
7865
+ throw new Error(`environment "${env}" has a cyclic secrets inheritance via "${target}"`);
7866
+ }
7867
+ seen.add(target);
7868
+ current = target;
7869
+ }
7870
+ };
7871
+ exports.getSecretsEnv = getSecretsEnv;
7872
+ //# sourceMappingURL=getEnvInherit.js.map
7873
+
7874
+ /***/ }),
7875
+
7876
+ /***/ 13055:
7877
+ /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
7878
+
7879
+ "use strict";
7880
+
7881
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
7882
+ exports.getEnvInstance = void 0;
7883
+ const bash_1 = __nccwpck_require__(94143);
7884
+ const bashExpressionPerPipelineType_1 = __nccwpck_require__(6495);
7885
+ const getEnvOn_1 = __nccwpck_require__(60601);
7886
+ const REVIEW_SLUG = {
7887
+ default: "unknown-review-slug",
7888
+ gitlab: new bash_1.BashExpression(`$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })`),
7889
+ // CL_PR_NUMBER is injected by the github backend at the workflow level
7890
+ github: new bash_1.BashExpression(`$([ -n "$CL_PR_NUMBER" ] && echo "pr$CL_PR_NUMBER" || echo "unknown")`),
7891
+ };
7892
+ const getEnvInstance = (envConfig, env, pipelineType, environments) => {
7893
+ // an env deploying per merge request is a review app — one dynamic
7894
+ // instance per MR, identified by the review slug
7895
+ if ((0, getEnvOn_1.getEnvOn)(env, envConfig, environments) === "mr") {
7896
+ return {
7897
+ type: "review",
7898
+ reviewSlug: (0, bashExpressionPerPipelineType_1.getBashExpressionPerPipelineType)(REVIEW_SLUG, pipelineType),
7899
+ };
7900
+ }
7901
+ return { type: "stable" };
7902
+ };
7903
+ exports.getEnvInstance = getEnvInstance;
7904
+ //# sourceMappingURL=getEnvInstance.js.map
7905
+
7906
+ /***/ }),
7907
+
7908
+ /***/ 60601:
7909
+ /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
7910
+
7911
+ "use strict";
7912
+
7913
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
7914
+ exports.getEnvOn = void 0;
7915
+ const types_1 = __nccwpck_require__(63557);
7916
+ const getEnvType_1 = __nccwpck_require__(46080);
7917
+ const getDefaultOnForType = (envType) => {
7918
+ var _a;
7919
+ const triggers = types_1.ENV_TYPES[envType].triggers;
7920
+ return (_a = triggers[0]) !== null && _a !== void 0 ? _a : false;
7921
+ };
7922
+ /**
7923
+ * resolves when an env deploys: the project-wide `on` config of the env
7924
+ * (top-level `environments`), falling back to the default of its env
7925
+ * type (dev → mainBranch, review → mr, stage/prod → taggedRelease,
7926
+ * local → false).
7927
+ *
7928
+ * `on` is deliberately not configurable per component — an environment
7929
+ * deploys at one point in time for the whole project.
7930
+ */
7931
+ const getEnvOn = (env, envConfig, environments) => {
7932
+ var _a;
7933
+ const on = (_a = environments === null || environments === void 0 ? void 0 : environments[env]) === null || _a === void 0 ? void 0 : _a.on;
7934
+ if (on !== undefined)
7935
+ return on;
7936
+ return getDefaultOnForType((0, getEnvType_1.getEnvType)(env, envConfig, environments));
7937
+ };
7938
+ exports.getEnvOn = getEnvOn;
7939
+ //# sourceMappingURL=getEnvOn.js.map
7940
+
7941
+ /***/ }),
7942
+
7686
7943
  /***/ 46080:
7687
7944
  /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
7688
7945
 
7689
7946
  "use strict";
7690
7947
 
7691
7948
  Object.defineProperty(exports, "__esModule", ({ value: true }));
7692
- exports.getEnvType = void 0;
7949
+ exports.getEnvType = exports.getDeclaredEnvType = void 0;
7693
7950
  const types_1 = __nccwpck_require__(63557);
7694
- const getEnvType = (env, envConfig) => {
7695
- if (envConfig.type)
7696
- return envConfig.type;
7697
- if ((0, types_1.isKnowEnvType)(env)) {
7951
+ const getEnvInherit_1 = __nccwpck_require__(52181);
7952
+ /**
7953
+ * the type of a project-wide declared env: its explicit `type`, its
7954
+ * name (when it is itself an env type), or — for envs that inherit —
7955
+ * the type of the env they inherit their config from
7956
+ */
7957
+ const getDeclaredEnvType = (environments, env, seen = new Set()) => {
7958
+ const declared = environments === null || environments === void 0 ? void 0 : environments[env];
7959
+ if (declared === null || declared === void 0 ? void 0 : declared.type)
7960
+ return declared.type;
7961
+ if ((0, types_1.isKnowEnvType)(env))
7698
7962
  return env;
7963
+ const inheritTarget = (0, getEnvInherit_1.normalizeEnvInherit)(declared === null || declared === void 0 ? void 0 : declared.inherit).config;
7964
+ if (inheritTarget && !seen.has(inheritTarget)) {
7965
+ seen.add(inheritTarget);
7966
+ return (0, exports.getDeclaredEnvType)(environments, inheritTarget, seen);
7699
7967
  }
7968
+ return undefined;
7969
+ };
7970
+ exports.getDeclaredEnvType = getDeclaredEnvType;
7971
+ const getEnvType = (env, envConfig, environments) => {
7972
+ // legacy: per-component custom envs declare their type themselves
7973
+ if (envConfig.type)
7974
+ return envConfig.type;
7975
+ // project-wide declaration (top-level `environments`)
7976
+ const declaredType = (0, exports.getDeclaredEnvType)(environments, env);
7977
+ if (declaredType)
7978
+ return declaredType;
7700
7979
  throw new Error("unknown env type: " + env);
7701
7980
  };
7702
7981
  exports.getEnvType = getEnvType;
@@ -7722,8 +8001,11 @@ const getEnvironment = async (ctx) => {
7722
8001
  envType,
7723
8002
  fullName: envContext.fullName,
7724
8003
  slugPrefix: envContext.environmentSlugPrefix,
8004
+ instance: envContext.instance,
7725
8005
  reviewSlug: envContext.reviewSlug,
7726
8006
  slug: envContext.environmentSlug,
8007
+ autoStop: envContext.autoStop,
8008
+ secretsEnv: envContext.secretsEnv,
7727
8009
  ...variables,
7728
8010
  };
7729
8011
  };
@@ -7741,19 +8023,26 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
7741
8023
  exports.getEnvironmentContext = void 0;
7742
8024
  const bash_1 = __nccwpck_require__(94143);
7743
8025
  const getEnvConfig_1 = __nccwpck_require__(69578);
8026
+ const getEnvInstance_1 = __nccwpck_require__(13055);
8027
+ const getEnvInherit_1 = __nccwpck_require__(52181);
7744
8028
  const getEnvType_1 = __nccwpck_require__(46080);
7745
- const getReviewSlug_1 = __nccwpck_require__(77360);
7746
- const getEnvironmentSlugPrefix = (env, reviewSlug) => {
7747
- if (reviewSlug) {
7748
- return (0, bash_1.joinBashExpressions)([env, reviewSlug], "-");
8029
+ const getEnvironmentSlugPrefix = (env, instance) => {
8030
+ if (instance.type === "review") {
8031
+ return (0, bash_1.joinBashExpressions)([env, instance.reviewSlug], "-");
7749
8032
  }
7750
8033
  return env;
7751
8034
  };
7752
8035
  const getEnvironmentContext = ({ env, componentName, config, pipelineType, }) => {
8036
+ var _a, _b;
7753
8037
  const envConfigRaw = (0, getEnvConfig_1.getEnvConfig)(config, componentName, env);
7754
- const envType = (0, getEnvType_1.getEnvType)(env, envConfigRaw);
7755
- const reviewSlug = (0, getReviewSlug_1.getReviewSlug)(envConfigRaw, env, pipelineType);
7756
- const environmentSlugPrefix = getEnvironmentSlugPrefix(env, reviewSlug);
8038
+ const envType = (0, getEnvType_1.getEnvType)(env, envConfigRaw, config.environments);
8039
+ const instance = (0, getEnvInstance_1.getEnvInstance)(envConfigRaw, env, pipelineType, config.environments);
8040
+ // component-level autoStop overrides the project-wide environment
8041
+ // config; undefined means the env type's default applies
8042
+ const autoStop = envConfigRaw.autoStop !== undefined
8043
+ ? envConfigRaw.autoStop
8044
+ : (_b = (_a = config.environments) === null || _a === void 0 ? void 0 : _a[env]) === null || _b === void 0 ? void 0 : _b.autoStop;
8045
+ const environmentSlugPrefix = getEnvironmentSlugPrefix(env, instance);
7757
8046
  const environmentSlug = environmentSlugPrefix.concat(`-${componentName}`);
7758
8047
  const fullName = (0, bash_1.joinBashExpressions)([config.customerName, config.appName, environmentSlug], "-");
7759
8048
  return {
@@ -7762,10 +8051,13 @@ const getEnvironmentContext = ({ env, componentName, config, pipelineType, }) =>
7762
8051
  buildConfigRaw: envConfigRaw.build,
7763
8052
  environmentSlugPrefix,
7764
8053
  environmentSlug,
7765
- reviewSlug,
8054
+ instance,
8055
+ reviewSlug: instance.type === "review" ? instance.reviewSlug : null,
7766
8056
  pipelineType,
7767
8057
  fullName,
7768
8058
  envType,
8059
+ autoStop,
8060
+ secretsEnv: (0, getEnvInherit_1.getSecretsEnv)(config.environments, env),
7769
8061
  componentName,
7770
8062
  env,
7771
8063
  fullConfig: config,
@@ -7850,7 +8142,7 @@ const getEnvironmentVariables = async (ctx, options = {}) => {
7850
8142
  ...(0, envVars_1.normalizeSecretVarsConfig)((_f = envConfigRaw.vars) === null || _f === void 0 ? void 0 : _f.secret),
7851
8143
  ...additionalSecretKeys,
7852
8144
  ];
7853
- const secretEnvVars = (0, envVars_1.makeSecretEnvVarMapping)(env, componentName, secretEnvVarKeys);
8145
+ const secretEnvVars = (0, envVars_1.makeSecretEnvVarMapping)(environmentContext.secretsEnv, componentName, secretEnvVarKeys);
7854
8146
  const publicEnvVarsRawSanitized = (0, envVars_1.stringifyValues)(publicEnvVarsRaw);
7855
8147
  const publicEnvVarsUnresolved = Object.fromEntries(Object.entries(publicEnvVarsRawSanitized).map(([key, value]) => [
7856
8148
  key,
@@ -7884,11 +8176,11 @@ const getEnvironmentVariables = async (ctx, options = {}) => {
7884
8176
  envVars,
7885
8177
  secretEnvVarKeys,
7886
8178
  jobOnlyVars: {
7887
- build: await (0, transformJobOnlyVars_1.transformJobOnlyVars)(env, componentName, (buildConfigRaw &&
8179
+ build: await (0, transformJobOnlyVars_1.transformJobOnlyVars)(environmentContext.secretsEnv, componentName, (buildConfigRaw &&
7888
8180
  (0, types_1.isStandaloneBuildConfig)(buildConfigRaw) &&
7889
8181
  buildConfigRaw.jobVars) ||
7890
8182
  null),
7891
- deploy: await (0, transformJobOnlyVars_1.transformJobOnlyVars)(env, componentName, (deployConfigRaw && deployConfigRaw.jobVars) || null),
8183
+ deploy: await (0, transformJobOnlyVars_1.transformJobOnlyVars)(environmentContext.secretsEnv, componentName, (deployConfigRaw && deployConfigRaw.jobVars) || null),
7892
8184
  },
7893
8185
  };
7894
8186
  };
@@ -7900,7 +8192,7 @@ const addIndexVar = (vars) => ({
7900
8192
  ...vars,
7901
8193
  _ALL_ENV_VAR_KEYS: JSON.stringify(Object.keys(vars)),
7902
8194
  });
7903
- const getSecretVarNameForContext = (context, key) => (0, exports.getSecretVarName)(context.env, context.name, key);
8195
+ const getSecretVarNameForContext = (context, key) => (0, exports.getSecretVarName)(context.environment.secretsEnv, context.name, key);
7904
8196
  exports.getSecretVarNameForContext = getSecretVarNameForContext;
7905
8197
  //# sourceMappingURL=getEnvironmentVariables.js.map
7906
8198
 
@@ -7944,34 +8236,6 @@ exports.getLabels = getLabels;
7944
8236
 
7945
8237
  /***/ }),
7946
8238
 
7947
- /***/ 77360:
7948
- /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
7949
-
7950
- "use strict";
7951
-
7952
- Object.defineProperty(exports, "__esModule", ({ value: true }));
7953
- exports.getReviewSlug = void 0;
7954
- const bash_1 = __nccwpck_require__(94143);
7955
- const bashExpressionPerPipelineType_1 = __nccwpck_require__(6495);
7956
- const getEnvType_1 = __nccwpck_require__(46080);
7957
- const REVIEW_SLUG = {
7958
- default: "unknown-review-slug",
7959
- gitlab: new bash_1.BashExpression(`$([ -n "$CI_MERGE_REQUEST_IID" ] && echo "mr$CI_MERGE_REQUEST_IID" || { [ -n "$CI_COMMIT_REF_SLUG" ] && echo "$CI_COMMIT_REF_SLUG" || echo "unknown"; })`),
7960
- // CL_PR_NUMBER is injected by the github backend at the workflow level
7961
- github: new bash_1.BashExpression(`$([ -n "$CL_PR_NUMBER" ] && echo "pr$CL_PR_NUMBER" || echo "unknown")`),
7962
- };
7963
- const getReviewSlug = (envConfig, env, pipelineType) => {
7964
- const envType = (0, getEnvType_1.getEnvType)(env, envConfig);
7965
- if (envType === "review") {
7966
- return (0, bashExpressionPerPipelineType_1.getBashExpressionPerPipelineType)(REVIEW_SLUG, pipelineType);
7967
- }
7968
- return null; // not a review app;
7969
- };
7970
- exports.getReviewSlug = getReviewSlug;
7971
- //# sourceMappingURL=getReviewSlug.js.map
7972
-
7973
- /***/ }),
7974
-
7975
8239
  /***/ 15707:
7976
8240
  /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
7977
8241
 
@@ -7994,6 +8258,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
7994
8258
  Object.defineProperty(exports, "__esModule", ({ value: true }));
7995
8259
  __exportStar(__nccwpck_require__(53373), exports);
7996
8260
  __exportStar(__nccwpck_require__(69578), exports);
8261
+ __exportStar(__nccwpck_require__(52181), exports);
7997
8262
  __exportStar(__nccwpck_require__(21494), exports);
7998
8263
  __exportStar(__nccwpck_require__(17429), exports);
7999
8264
  //# sourceMappingURL=index.js.map
@@ -8603,8 +8868,11 @@ class DeployJob extends jobs_1.CatladderJob {
8603
8868
  var _a, _b, _c, _d, _e, _f, _g;
8604
8869
  const hasDocker = (0, docker_1.requiresDockerBuild)(context);
8605
8870
  const isStoppable = (0, utils_1.contextIsStoppable)(context);
8871
+ // env-level autoStop config wins; the env type only supplies the
8872
+ // default (via the project-wide `autoStop` durations)
8873
+ const autoStopConfigured = context.environment.autoStop;
8606
8874
  const autoStopConfig = (0, autoStop_1.getAutoStopConfig)(context.fullConfig);
8607
- const autoStop = context.environment.envType === "review"
8875
+ const autoStopDefault = context.environment.envType === "review"
8608
8876
  ? // review envs read the lifetime from a pipeline variable, so
8609
8877
  // the pin label's workflow rule can override it to "never"
8610
8878
  autoStopConfig.pinLabel === false
@@ -8613,6 +8881,13 @@ class DeployJob extends jobs_1.CatladderJob {
8613
8881
  : context.environment.envType === "dev"
8614
8882
  ? autoStopConfig.dev
8615
8883
  : undefined;
8884
+ // NOTE: an explicit env-level autoStop is a literal — a review env
8885
+ // overriding it opts out of the pin-label variable indirection
8886
+ const autoStop = autoStopConfigured === undefined
8887
+ ? autoStopDefault
8888
+ : autoStopConfigured === false
8889
+ ? undefined
8890
+ : autoStopConfigured;
8616
8891
  const deployConfig = (_a = context.deploy) === null || _a === void 0 ? void 0 : _a.config;
8617
8892
  // if auto or manual is configured explicitly, use that
8618
8893
  const whenDeployDefined = deployConfig && deployConfig.when ? deployConfig.when : undefined;
@@ -8880,7 +9155,8 @@ exports.getArtifactsRegistryDockerUrl = getArtifactsRegistryDockerUrl;
8880
9155
  * lecacyReviewImageName is only temporary. In old versions the images had no reviewslug in review apps, which makes cleanup harder. We delete all those images now, but need the path
8881
9156
  */
8882
9157
  const getArtifactsRegistryImageName = (context, lecacyReviewImageName = false) => {
8883
- if (lecacyReviewImageName && context.environment.envType !== "review") {
9158
+ const { instance } = context.environment;
9159
+ if (lecacyReviewImageName && instance.type !== "review") {
8884
9160
  throw new Error("lecacyReviewImageName is only allowed for review app");
8885
9161
  }
8886
9162
  const dockerUrl = (0, exports.getArtifactsRegistryDockerUrl)(context);
@@ -8888,8 +9164,8 @@ const getArtifactsRegistryImageName = (context, lecacyReviewImageName = false) =
8888
9164
  dockerUrl,
8889
9165
  context.env,
8890
9166
  context.name,
8891
- ...(context.environment.reviewSlug && !lecacyReviewImageName
8892
- ? [context.environment.reviewSlug]
9167
+ ...(instance.type === "review" && !lecacyReviewImageName
9168
+ ? [instance.reviewSlug]
8893
9169
  : []),
8894
9170
  ];
8895
9171
  return (0, bash_1.joinBashExpressions)(gcloudImagePath, "/");
@@ -8939,7 +9215,7 @@ const getDeleteUnusedImagesCommands = (context, keep = 0) => {
8939
9215
  ...getDeleteImageCommands(buildCacheImageName, 1),
8940
9216
  // because a recent version of catladder had no review-slug in the image name, we have to delete those as well
8941
9217
  // we can later remove this line in some months
8942
- ...(context.environment.envType === "review"
9218
+ ...(context.environment.instance.type === "review"
8943
9219
  ? (0, gitlab_1.allowFailureInScripts)(getDeleteImageCommands((0, exports.getArtifactsRegistryImageName)(context, true), 0))
8944
9220
  : []),
8945
9221
  ];
@@ -8960,12 +9236,18 @@ const gitlab_1 = __nccwpck_require__(86962);
8960
9236
  const artifactsRegistry_1 = __nccwpck_require__(44330);
8961
9237
  const cloudRunRevisions_1 = __nccwpck_require__(55698);
8962
9238
  const getRemoveOldRevisionsAndImagesCommand = (context, when) => {
9239
+ var _a;
8963
9240
  if (when === "onStop") {
8964
9241
  // service is already deleted, so we don't need to delete old revisions, just delete all images
8965
9242
  return (0, artifactsRegistry_1.getDeleteUnusedImagesCommands)(context);
8966
9243
  }
8967
- // this number only targets inactive revisions
8968
- const revisionsToKeep = context.environment.envType === "prod" ? 5 : 0;
9244
+ const deployConfig = (_a = context.deploy) === null || _a === void 0 ? void 0 : _a.config;
9245
+ const configuredRevisionsToKeep = deployConfig && deployConfig.type === "google-cloudrun"
9246
+ ? deployConfig.revisionsToKeep
9247
+ : undefined;
9248
+ // this number only targets inactive revisions; the env type only
9249
+ // supplies the default (prod keeps a rollback history)
9250
+ const revisionsToKeep = configuredRevisionsToKeep !== null && configuredRevisionsToKeep !== void 0 ? configuredRevisionsToKeep : (context.environment.envType === "prod" ? 5 : 0);
8969
9251
  // this number needs to be higher than inactive after deploy, so we add one
8970
9252
  const imagesToKeep = revisionsToKeep + 1;
8971
9253
  const deleteOldRevisionsCommands = (0, cloudRunRevisions_1.getDeleteUnusedRevisionsCommands)(context, revisionsToKeep);
@@ -9872,7 +10154,7 @@ const cloudRunExecutionUrl_1 = __nccwpck_require__(49963);
9872
10154
  const database_1 = __nccwpck_require__(11595);
9873
10155
  const getServiceName_1 = __nccwpck_require__(33102);
9874
10156
  exports.GCLOUD_DEPLOY_CREDENTIALS_KEY = "GCLOUD_DEPLOY_credentialsKey";
9875
- const getCloudSqlVariables = ({ deployConfigRaw, environmentSlugPrefix, env, componentName, fullConfig, }) => {
10157
+ const getCloudSqlVariables = ({ deployConfigRaw, environmentSlugPrefix, secretsEnv, componentName, fullConfig, }) => {
9876
10158
  var _a, _b, _c;
9877
10159
  if (deployConfigRaw && deployConfigRaw.cloudSql) {
9878
10160
  const DB_NAME = (0, utils_1.getFullDbName)(deployConfigRaw.cloudSql, fullConfig, environmentSlugPrefix, componentName);
@@ -9883,7 +10165,7 @@ const getCloudSqlVariables = ({ deployConfigRaw, environmentSlugPrefix, env, com
9883
10165
  CLOUD_SQL_INSTANCE_CONNECTION_NAME: deployConfigRaw.cloudSql.instanceConnectionName,
9884
10166
  DB_NAME: DB_NAME,
9885
10167
  DB_USER: (_b = deployConfigRaw.cloudSql.dbUser) !== null && _b !== void 0 ? _b : "postgres",
9886
- DB_PASSWORD: "$" + (0, context_1.getSecretVarName)(env, componentName, "DB_PASSWORD"),
10168
+ DB_PASSWORD: "$" + (0, context_1.getSecretVarName)(secretsEnv, componentName, "DB_PASSWORD"),
9887
10169
  };
9888
10170
  return {
9889
10171
  ...dbVars,
@@ -10356,7 +10638,7 @@ const fromComponentContext = (context) => {
10356
10638
  environmentSlugPrefix: context.environment.slugPrefix,
10357
10639
  componentName: context.name,
10358
10640
  env: context.env,
10359
- isReviewEnv: context.environment.envType === "review",
10641
+ isReviewEnv: context.environment.instance.type === "review",
10360
10642
  deployConfig: deployConfig && deployConfig.type === "google-cloudrun"
10361
10643
  ? deployConfig
10362
10644
  : null,
@@ -10368,7 +10650,7 @@ const fromEnvironmentContext = (context) => ({
10368
10650
  environmentSlugPrefix: context.environmentSlugPrefix,
10369
10651
  componentName: context.componentName,
10370
10652
  env: context.env,
10371
- isReviewEnv: context.envType === "review",
10653
+ isReviewEnv: context.instance.type === "review",
10372
10654
  deployConfig: context.deployConfigRaw || null,
10373
10655
  config: context.fullConfig,
10374
10656
  });
@@ -10822,9 +11104,9 @@ exports.KUBERNETES_DEPLOY_TYPE = {
10822
11104
  jobs: deployJob_1.createKubernetesDeployJobs,
10823
11105
  defaults: () => ({}),
10824
11106
  additionalSecretKeys: additionalSecretKeys_1.additionalKubernetesSecretKeys,
10825
- getAdditionalEnvVars: ({ componentName, fullConfig, deployConfigRaw, env, reviewSlug, envType, }) => {
11107
+ getAdditionalEnvVars: ({ componentName, fullConfig, deployConfigRaw, env, instance, }) => {
10826
11108
  var _a;
10827
- const KUBE_APP_NAME_PREFIX = envType === "review" && reviewSlug ? reviewSlug.concat("-") : "";
11109
+ const KUBE_APP_NAME_PREFIX = instance.type === "review" ? instance.reviewSlug.concat("-") : "";
10828
11110
  const KUBE_APP_NAME = KUBE_APP_NAME_PREFIX.concat(componentName);
10829
11111
  const KUBE_NAMESPACE = (0, __1.getKubernetesNamespace)(fullConfig, env);
10830
11112
  const componentSlug = (0, slugify_1.default)(componentName);
@@ -10833,7 +11115,7 @@ exports.KUBERNETES_DEPLOY_TYPE = {
10833
11115
  "panter.cloud";
10834
11116
  const HOSTNAME_INTERNAL = (0, bash_1.joinBashExpressions)([
10835
11117
  componentSlug,
10836
- ...(envType === "review" && reviewSlug ? [reviewSlug] : []),
11118
+ ...(instance.type === "review" ? [instance.reviewSlug] : []),
10837
11119
  env,
10838
11120
  fullConfig.appName,
10839
11121
  fullConfig.customerName,
@@ -11191,7 +11473,8 @@ const createPagesDeployJobs = async (context) => {
11191
11473
  throw new Error("deploy config is not pages");
11192
11474
  }
11193
11475
  const onGithub = context.pipelineType === "github";
11194
- if (onGithub && context.environment.envType === "review") {
11476
+ const isReviewApp = context.environment.instance.type === "review";
11477
+ if (onGithub && isReviewApp) {
11195
11478
  // github pages serves ONE site per repository and deploy-pages
11196
11479
  // replaces all of it — there is no path_prefix equivalent, so per-PR
11197
11480
  // previews cannot exist (deploy-pages has a `preview` input, but it
@@ -11202,7 +11485,7 @@ const createPagesDeployJobs = async (context) => {
11202
11485
  }
11203
11486
  // review environments publish under their own path prefix (gitlab
11204
11487
  // parallel deployments) — every merge request gets a site preview
11205
- const pathPrefix = context.environment.envType === "review" ? "mr-$CI_MERGE_REQUEST_IID" : "";
11488
+ const pathPrefix = isReviewApp ? "mr-$CI_MERGE_REQUEST_IID" : "";
11206
11489
  const publishDir = (_b = deployConfig.publishDir) !== null && _b !== void 0 ? _b : "public";
11207
11490
  const packageManagerInstall = await (0, packageManagerInstall_1.getPackageManagerInstall)(context, {
11208
11491
  noCustomPostInstall: true,
@@ -12899,12 +13182,22 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
12899
13182
  "use strict";
12900
13183
 
12901
13184
  Object.defineProperty(exports, "__esModule", ({ value: true }));
12902
- exports.isKnowEnvType = exports.DEFAULT_ENV_TYPES = exports.DEFAULT_ENVS = exports.getEnvTypesByTrigger = exports.ENV_TYPES = exports.ALL_PIPELINE_TRIGGERS = void 0;
13185
+ exports.isKnowEnvType = exports.DEFAULT_ENV_TYPES = exports.DEFAULT_ENVS = exports.ENV_TYPES = exports.envTriggerEquals = exports.isBranchTrigger = exports.ALL_PIPELINE_TRIGGERS = void 0;
12903
13186
  exports.ALL_PIPELINE_TRIGGERS = [
12904
13187
  "mainBranch",
12905
13188
  "mr",
12906
13189
  "taggedRelease",
12907
13190
  ];
13191
+ const isBranchTrigger = (trigger) => typeof trigger === "object" && trigger !== null && "branch" in trigger;
13192
+ exports.isBranchTrigger = isBranchTrigger;
13193
+ const envTriggerEquals = (a, b) => {
13194
+ if (a === undefined || a === false)
13195
+ return false;
13196
+ if ((0, exports.isBranchTrigger)(b))
13197
+ return (0, exports.isBranchTrigger)(a) && a.branch === b.branch;
13198
+ return a === b;
13199
+ };
13200
+ exports.envTriggerEquals = envTriggerEquals;
12908
13201
  /**
12909
13202
  * all env types with their trigger.
12910
13203
  * Each env type has a default env with the same name which is always included
@@ -12926,15 +13219,6 @@ exports.ENV_TYPES = {
12926
13219
  triggers: [],
12927
13220
  },
12928
13221
  };
12929
- /**
12930
- *
12931
- * @param trigger a trigger
12932
- * @returns array of env types for that trigger. this is also the list of default envs
12933
- */
12934
- const getEnvTypesByTrigger = (trigger) => Object.entries(exports.ENV_TYPES)
12935
- .filter(([, e]) => e.triggers.includes(trigger))
12936
- .map(([e]) => e);
12937
- exports.getEnvTypesByTrigger = getEnvTypesByTrigger;
12938
13222
  exports.DEFAULT_ENVS = Object.keys(exports.ENV_TYPES);
12939
13223
  exports.DEFAULT_ENV_TYPES = exports.DEFAULT_ENVS;
12940
13224
  const isKnowEnvType = (env) => {