@catladder/cli 0.0.0-next-1cd29c1f → 0.0.0-next-52feb889

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 (112) hide show
  1. package/dist/bundles/catenv/index.js +45 -9
  2. package/dist/bundles/cli/index.js +125 -11
  3. package/dist/bundles/runner-images/agent-claude/Dockerfile +5 -0
  4. package/dist/bundles/runner-images/docker-build/Dockerfile +26 -0
  5. package/dist/bundles/runner-images/docker-build/scripts/ensureMeteorDockerfile +55 -0
  6. package/dist/bundles/runner-images/docker-build/scripts/ensureNginxDockerfile +85 -0
  7. package/dist/bundles/runner-images/docker-build/scripts/ensureNodeDockerfile +50 -0
  8. package/dist/bundles/runner-images/gcloud/Dockerfile +3 -0
  9. package/dist/bundles/runner-images/jobs-default/Dockerfile +22 -0
  10. package/dist/bundles/runner-images/jobs-meteor/Dockerfile +7 -0
  11. package/dist/bundles/runner-images/jobs-testing-chrome/Dockerfile +15 -0
  12. package/dist/bundles/runner-images/kubernetes/Dockerfile +26 -0
  13. package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/Chart.lock +9 -0
  14. package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/Chart.yaml +14 -0
  15. package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/README.md +24 -0
  16. package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/charts/mailhog-5.0.1.tgz +0 -0
  17. package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/charts/mongodb-12.1.27.tgz +0 -0
  18. package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/myvalues.yaml +15 -0
  19. package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/templates/_helpers.tpl +202 -0
  20. package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/templates/app.cloudsql-proxy-credentials.yml +10 -0
  21. package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/templates/app.cronjobs.yml +69 -0
  22. package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/templates/app.deployment.autoscaler.yml +19 -0
  23. package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/templates/app.deployment.yml +103 -0
  24. package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/templates/app.env.configmap.yml +27 -0
  25. package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/templates/app.env.secrets.yml +10 -0
  26. package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/templates/app.ingress.redirects.yaml +91 -0
  27. package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/templates/app.ingress.yaml +48 -0
  28. package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/templates/app.jobs.yml +70 -0
  29. package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/templates/app.service.yaml +31 -0
  30. package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/templates/app.volumes.yml +20 -0
  31. package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/templates/app.worker.deployment.yml +104 -0
  32. package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/templates/app.worker.service.yaml +34 -0
  33. package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/templates/mailhog.ingress.yaml +35 -0
  34. package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/templates/maintenance.deployment.yml +45 -0
  35. package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/templates/maintenance.service.yml +24 -0
  36. package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/templates/mongodb.backup.cronjob.yml +120 -0
  37. package/dist/bundles/runner-images/kubernetes/helm-charts/the-panter-chart/values.yaml +154 -0
  38. package/dist/bundles/runner-images/kubernetes/scripts/kubernetesCreateSecret +11 -0
  39. package/dist/bundles/runner-images/kubernetes/scripts/kubernetesDelete +5 -0
  40. package/dist/bundles/runner-images/kubernetes/scripts/kubernetesDeploy +57 -0
  41. package/dist/bundles/runner-images/kubernetes/scripts/kubernetesRollback +5 -0
  42. package/dist/bundles/runner-images/semantic-release/Dockerfile +24 -0
  43. package/dist/bundles/runner-images/semantic-release/scripts/semanticRelease +67 -0
  44. package/dist/cli/src/apps/cli/commands/project/setup/ensureGcloudProjectNumbers.d.ts +12 -0
  45. package/dist/cli/src/apps/cli/commands/project/setup/ensureGcloudProjectNumbers.js +64 -0
  46. package/dist/cli/src/apps/cli/commands/project/setup/ensureGcloudProjectNumbers.js.map +1 -0
  47. package/dist/cli/src/apps/cli/commands/project/setup/index.js +3 -0
  48. package/dist/cli/src/apps/cli/commands/project/setup/index.js.map +1 -1
  49. package/dist/cli/src/config/getProjectConfig.d.ts +6 -0
  50. package/dist/cli/src/config/getProjectConfig.js +10 -1
  51. package/dist/cli/src/config/getProjectConfig.js.map +1 -1
  52. package/dist/cli/src/gcloud/cloudSql/copyDb.js +6 -2
  53. package/dist/cli/src/gcloud/cloudSql/copyDb.js.map +1 -1
  54. package/dist/pipeline/src/constants.js +1 -1
  55. package/dist/pipeline/src/context/index.d.ts +1 -0
  56. package/dist/pipeline/src/context/index.js +1 -0
  57. package/dist/pipeline/src/context/index.js.map +1 -1
  58. package/dist/pipeline/src/customImages/shippedImages.js +3 -1
  59. package/dist/pipeline/src/customImages/shippedImages.js.map +1 -1
  60. package/dist/pipeline/src/deploy/cloudRun/createJobs/execute/schedules.js +18 -3
  61. package/dist/pipeline/src/deploy/cloudRun/createJobs/execute/schedules.js.map +1 -1
  62. package/dist/pipeline/src/deploy/types/googleCloudRun.d.ts +5 -1
  63. package/dist/pipeline/src/store/index.d.ts +4 -0
  64. package/dist/pipeline/src/store/index.js +12 -3
  65. package/dist/pipeline/src/store/index.js.map +1 -1
  66. package/dist/runner-images/agent-claude/Dockerfile +5 -0
  67. package/dist/runner-images/docker-build/Dockerfile +26 -0
  68. package/dist/runner-images/docker-build/scripts/ensureMeteorDockerfile +55 -0
  69. package/dist/runner-images/docker-build/scripts/ensureNginxDockerfile +85 -0
  70. package/dist/runner-images/docker-build/scripts/ensureNodeDockerfile +50 -0
  71. package/dist/runner-images/gcloud/Dockerfile +3 -0
  72. package/dist/runner-images/jobs-default/Dockerfile +22 -0
  73. package/dist/runner-images/jobs-meteor/Dockerfile +7 -0
  74. package/dist/runner-images/jobs-testing-chrome/Dockerfile +15 -0
  75. package/dist/runner-images/kubernetes/Dockerfile +26 -0
  76. package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/Chart.lock +9 -0
  77. package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/Chart.yaml +14 -0
  78. package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/README.md +24 -0
  79. package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/charts/mailhog-5.0.1.tgz +0 -0
  80. package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/charts/mongodb-12.1.27.tgz +0 -0
  81. package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/myvalues.yaml +15 -0
  82. package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/templates/_helpers.tpl +202 -0
  83. package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/templates/app.cloudsql-proxy-credentials.yml +10 -0
  84. package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/templates/app.cronjobs.yml +69 -0
  85. package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/templates/app.deployment.autoscaler.yml +19 -0
  86. package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/templates/app.deployment.yml +103 -0
  87. package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/templates/app.env.configmap.yml +27 -0
  88. package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/templates/app.env.secrets.yml +10 -0
  89. package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/templates/app.ingress.redirects.yaml +91 -0
  90. package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/templates/app.ingress.yaml +48 -0
  91. package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/templates/app.jobs.yml +70 -0
  92. package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/templates/app.service.yaml +31 -0
  93. package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/templates/app.volumes.yml +20 -0
  94. package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/templates/app.worker.deployment.yml +104 -0
  95. package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/templates/app.worker.service.yaml +34 -0
  96. package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/templates/mailhog.ingress.yaml +35 -0
  97. package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/templates/maintenance.deployment.yml +45 -0
  98. package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/templates/maintenance.service.yml +24 -0
  99. package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/templates/mongodb.backup.cronjob.yml +120 -0
  100. package/dist/runner-images/kubernetes/helm-charts/the-panter-chart/values.yaml +154 -0
  101. package/dist/runner-images/kubernetes/scripts/kubernetesCreateSecret +11 -0
  102. package/dist/runner-images/kubernetes/scripts/kubernetesDelete +5 -0
  103. package/dist/runner-images/kubernetes/scripts/kubernetesDeploy +57 -0
  104. package/dist/runner-images/kubernetes/scripts/kubernetesRollback +5 -0
  105. package/dist/runner-images/semantic-release/Dockerfile +24 -0
  106. package/dist/runner-images/semantic-release/scripts/semanticRelease +67 -0
  107. package/dist/tsconfig.tsbuildinfo +1 -1
  108. package/package.json +3 -2
  109. package/src/apps/cli/commands/project/setup/ensureGcloudProjectNumbers.ts +61 -0
  110. package/src/apps/cli/commands/project/setup/index.ts +3 -0
  111. package/src/config/getProjectConfig.ts +9 -0
  112. package/src/gcloud/cloudSql/copyDb.ts +7 -2
@@ -397,7 +397,7 @@ program.parse();
397
397
  Object.defineProperty(exports, "__esModule", ({
398
398
  value: true
399
399
  }));
400
- exports.getJobOnlyEnvVarsResolved = exports.getEnvVarsResolved = exports.getGitlabVar = exports.getEnvironment = exports.getAllPipelineContexts = exports.getAllComponentsWithAllEnvsHierarchical = exports.getAllComponentsWithAllEnvsFlat = exports.getPipelineContextByChoice = exports.getProjectComponents = exports.getProjectConfig = exports.parseChoice = void 0;
400
+ exports.getJobOnlyEnvVarsResolved = exports.getEnvVarsResolved = exports.getGitlabVar = exports.getEnvironment = exports.getAllPipelineContexts = exports.getAllComponentsWithAllEnvsHierarchical = exports.getAllComponentsWithAllEnvsFlat = exports.getPipelineContextByChoice = exports.getProjectComponents = exports.invalidateProjectConfig = exports.getProjectConfig = exports.parseChoice = void 0;
401
401
  const pipeline_1 = __nccwpck_require__(60241);
402
402
  const gitlab_1 = __nccwpck_require__(4508);
403
403
  const projects_1 = __nccwpck_require__(57414);
@@ -427,6 +427,15 @@ const getProjectConfig = async () => {
427
427
  return currentConfig;
428
428
  };
429
429
  exports.getProjectConfig = getProjectConfig;
430
+ /**
431
+ * drops the cached config so the next access re-reads it from disk —
432
+ * needed after writing the catladder store, which is attached to the
433
+ * config (`config.store`) at read time
434
+ */
435
+ const invalidateProjectConfig = () => {
436
+ currentConfig = null;
437
+ };
438
+ exports.invalidateProjectConfig = invalidateProjectConfig;
430
439
  const getProjectComponents = async () => {
431
440
  const config = await (0, exports.getProjectConfig)();
432
441
  if (!config) return [];
@@ -5136,7 +5145,7 @@ Object.defineProperty(exports, "__esModule", ({
5136
5145
  value: true
5137
5146
  }));
5138
5147
  exports.DOCKER_REGISTRY = exports.PIPELINE_IMAGE_TAG = void 0;
5139
- exports.PIPELINE_IMAGE_TAG = "next-1cd29c1f" || 0;
5148
+ exports.PIPELINE_IMAGE_TAG = "next-52feb889" || 0;
5140
5149
  exports.DOCKER_REGISTRY = "git.panter.ch:5001/catladder/catladder" || 0;
5141
5150
 
5142
5151
  /***/ }),
@@ -5747,6 +5756,7 @@ Object.defineProperty(exports, "__esModule", ({
5747
5756
  value: true
5748
5757
  }));
5749
5758
  __exportStar(__nccwpck_require__(14847), exports);
5759
+ __exportStar(__nccwpck_require__(57044), exports);
5750
5760
  __exportStar(__nccwpck_require__(14956), exports);
5751
5761
  __exportStar(__nccwpck_require__(85855), exports);
5752
5762
 
@@ -6151,7 +6161,9 @@ exports.RUNNER_IMAGE_BUILD_CONTEXT = {
6151
6161
  */
6152
6162
  const getShippedImagesDir = () => {
6153
6163
  const candidates = [
6154
- // built package: dist/customImages -> dist/runner-images
6164
+ // built pipeline package: dist/customImages -> dist/runner-images
6165
+ // bundled cli package (what consumers install): the ncc bundles live
6166
+ // in dist/bundles/<name>, so both resolve to dist/bundles/runner-images
6155
6167
  (0, path_1.join)(__dirname, "..", "runner-images"),
6156
6168
  // repository: pipeline/src/customImages -> <root>/runner-images
6157
6169
  (0, path_1.join)(__dirname, "..", "..", "..", "runner-images")];
@@ -7032,8 +7044,11 @@ const getCreateScheduleScript = context => {
7032
7044
  config
7033
7045
  }, jobIndex) => {
7034
7046
  var _a;
7047
+ // `headers` is pulled out of the shared args because the flag name differs
7048
+ // between create (`--headers`) and update (`--update-headers`).
7035
7049
  const {
7036
7050
  uri,
7051
+ headers,
7037
7052
  ...args
7038
7053
  } = getSchedulerArgs(config, context);
7039
7054
  const argsString = (0, createArgsString_1.createArgsString)({
@@ -7044,12 +7059,15 @@ const getCreateScheduleScript = context => {
7044
7059
  schedule: `"${config.schedule}"`,
7045
7060
  "max-retry-attempts": (_a = config.maxRetryAttempts) !== null && _a !== void 0 ? _a : 0
7046
7061
  });
7047
- return [jobIndex === 0 ? `exist_scheduler_names="$(\n ${(0, common_1.gcloudSchedulerCmd)()} jobs list --filter='httpTarget.uri ~ ${context.env}.*${context.name}' --format='value(name)' --limit=999 --location='${location}' --project='${project}'\n)"` : null, `current_job_uri="${uri}"`, `current_scheduler_name="${fullName}"`, `if echo "$exist_scheduler_names" | grep -Fx "$current_scheduler_name" >/dev/null; then`, ` ${(0, common_1.gcloudSchedulerCmd)()} jobs update http "$current_scheduler_name" ${argsString}`, `else`, ` ${(0, common_1.gcloudSchedulerCmd)()} jobs create http "$current_scheduler_name" ${argsString}`, `fi`].filter(utils_1.notNil).join("\n");
7062
+ const headersValue = headers ? `"${(0, bash_1.bashEscape)(headers)}"` : undefined;
7063
+ const createHeadersArg = headersValue ? ` --headers=${headersValue}` : "";
7064
+ const updateHeadersArg = headersValue ? ` --update-headers=${headersValue}` : "";
7065
+ return [jobIndex === 0 ? `exist_scheduler_names="$(\n ${(0, common_1.gcloudSchedulerCmd)()} jobs list --filter='httpTarget.uri ~ ${context.env}.*${context.name}' --format='value(name)' --limit=999 --location='${location}' --project='${project}'\n)"` : null, `current_job_uri="${uri}"`, `current_scheduler_name="${fullName}"`, `if echo "$exist_scheduler_names" | grep -Fx "$current_scheduler_name" >/dev/null; then`, ` ${(0, common_1.gcloudSchedulerCmd)()} jobs update http "$current_scheduler_name" ${argsString}${updateHeadersArg}`, `else`, ` ${(0, common_1.gcloudSchedulerCmd)()} jobs create http "$current_scheduler_name" ${argsString}${createHeadersArg}`, `fi`].filter(utils_1.notNil).join("\n");
7048
7066
  });
7049
7067
  };
7050
7068
  exports.getCreateScheduleScript = getCreateScheduleScript;
7051
7069
  const getSchedulerArgs = (scheduler, context) => {
7052
- var _a;
7070
+ var _a, _b;
7053
7071
  if (scheduler.type === "job") {
7054
7072
  const {
7055
7073
  projectId,
@@ -7077,10 +7095,19 @@ const getSchedulerArgs = (scheduler, context) => {
7077
7095
  };
7078
7096
  }
7079
7097
  if (scheduler.type === "http") {
7098
+ // default the Content-Type to application/json when a body is sent and the
7099
+ // user didn't set one explicitly. Otherwise Cloud Scheduler falls back to
7100
+ // application/octet-stream, which is rarely what's intended.
7101
+ const hasContentType = Object.keys((_b = scheduler.headers) !== null && _b !== void 0 ? _b : {}).some(k => k.toLowerCase() === "content-type");
7102
+ const headers = scheduler.body && !hasContentType ? {
7103
+ "Content-Type": "application/json",
7104
+ ...scheduler.headers
7105
+ } : scheduler.headers;
7080
7106
  return {
7081
7107
  uri: scheduler.url,
7082
- "message-body": scheduler.body,
7108
+ "message-body": scheduler.body ? '"' + (0, bash_1.bashEscape)(scheduler.body) + '"' : undefined,
7083
7109
  "http-method": scheduler.method,
7110
+ headers: headers ? Object.entries(headers).map(([k, v]) => `${k}=${v}`).join(",") : undefined,
7084
7111
  "oidc-service-account-email": `"${(0, common_1.getComputeServiceAccountEmail)(context)}"`
7085
7112
  };
7086
7113
  }
@@ -9697,6 +9724,10 @@ exports.getCatladderStorePath = getCatladderStorePath;
9697
9724
  /**
9698
9725
  * reads and validates the catladder store. Returns an empty store when the
9699
9726
  * file does not exist (project setup has not run yet).
9727
+ *
9728
+ * An unreadable or invalid store is treated the same as a missing one
9729
+ * (with a warning): the store only holds machine-fetched values, so the
9730
+ * remedy is always rerunning project setup — not hand-editing the file.
9700
9731
  */
9701
9732
  const readCatladderStore = (directory = process.cwd()) => {
9702
9733
  var _a;
@@ -9704,9 +9735,14 @@ const readCatladderStore = (directory = process.cwd()) => {
9704
9735
  if (!(0, fs_1.existsSync)(path)) {
9705
9736
  return {};
9706
9737
  }
9707
- return exports.catladderStoreSchema.parse((_a = (0, yaml_1.parse)((0, fs_1.readFileSync)(path, {
9708
- encoding: "utf-8"
9709
- }))) !== null && _a !== void 0 ? _a : {});
9738
+ try {
9739
+ return exports.catladderStoreSchema.parse((_a = (0, yaml_1.parse)((0, fs_1.readFileSync)(path, {
9740
+ encoding: "utf-8"
9741
+ }))) !== null && _a !== void 0 ? _a : {});
9742
+ } catch (error) {
9743
+ console.warn(`⚠️ ignoring invalid ${exports.CATLADDER_STORE_FILE} (rerun "catladder project setup" to regenerate it): ${error instanceof Error ? error.message : error}`);
9744
+ return {};
9745
+ }
9710
9746
  };
9711
9747
  exports.readCatladderStore = readCatladderStore;
9712
9748
  /**
@@ -587,6 +587,77 @@ exports.projectConfigSecrets = projectConfigSecrets;
587
587
 
588
588
  /***/ }),
589
589
 
590
+ /***/ 22661:
591
+ /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
592
+
593
+ "use strict";
594
+
595
+
596
+ Object.defineProperty(exports, "__esModule", ({
597
+ value: true
598
+ }));
599
+ exports.ensureGcloudProjectNumbers = void 0;
600
+ const pipeline_1 = __nccwpck_require__(60241);
601
+ const getProjectConfig_1 = __nccwpck_require__(50001);
602
+ const getProjectNumber_1 = __nccwpck_require__(68666);
603
+ const updateCatladderStore_1 = __nccwpck_require__(66487);
604
+ const projects_1 = __nccwpck_require__(57414);
605
+ /**
606
+ * fetches the gcloud project numbers of all cloud run deploys into the
607
+ * catladder store.
608
+ *
609
+ * This must run BEFORE any pipeline context is created: context creation
610
+ * computes the deterministic cloud run urls, which read the project
611
+ * number from the store and throw when it is missing — on a fresh
612
+ * project that would make `project setup` fail with the very error it is
613
+ * supposed to fix (chicken-and-egg).
614
+ */
615
+ const ensureGcloudProjectNumbers = async instance => {
616
+ var _a;
617
+ const config = await (0, getProjectConfig_1.getProjectConfig)();
618
+ if (!config) return;
619
+ const projectIds = new Set();
620
+ for (const {
621
+ componentName,
622
+ env
623
+ } of await (0, getProjectConfig_1.getAllComponentsWithAllEnvsFlat)()) {
624
+ const {
625
+ deploy
626
+ } = (0, pipeline_1.getEnvConfig)(config, componentName, env);
627
+ if (deploy && deploy.type === "google-cloudrun") {
628
+ projectIds.add(deploy.projectId);
629
+ }
630
+ }
631
+ const root = (_a = await (0, projects_1.getGitRoot)()) !== null && _a !== void 0 ? _a : process.cwd();
632
+ const store = (0, pipeline_1.readCatladderStore)(root);
633
+ const missing = [...projectIds].filter(projectId => {
634
+ var _a, _b;
635
+ return !((_b = (_a = store.gcloudProjects) === null || _a === void 0 ? void 0 : _a[projectId]) === null || _b === void 0 ? void 0 : _b.projectNumber);
636
+ });
637
+ for (const projectId of missing) {
638
+ instance.log(`fetch gcloud project number for ${projectId}...`);
639
+ const projectNumber = await (0, getProjectNumber_1.fetchGcloudProjectNumber)(projectId);
640
+ instance.log(`project number: ${projectNumber}`);
641
+ await (0, updateCatladderStore_1.updateCatladderStore)(current => ({
642
+ ...current,
643
+ gcloudProjects: {
644
+ ...current.gcloudProjects,
645
+ [projectId]: {
646
+ projectNumber
647
+ }
648
+ }
649
+ }));
650
+ }
651
+ if (missing.length > 0) {
652
+ // the store is attached to the config at read time; drop the cached
653
+ // config so contexts created after this pre-pass see the new values
654
+ (0, getProjectConfig_1.invalidateProjectConfig)();
655
+ }
656
+ };
657
+ exports.ensureGcloudProjectNumbers = ensureGcloudProjectNumbers;
658
+
659
+ /***/ }),
660
+
590
661
  /***/ 80426:
591
662
  /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
592
663
 
@@ -603,7 +674,10 @@ const setupContext_1 = __nccwpck_require__(63516);
603
674
  const setupTopic_1 = __nccwpck_require__(66992);
604
675
  const setupAgents_1 = __nccwpck_require__(73861);
605
676
  const logSection_1 = __nccwpck_require__(87105);
677
+ const ensureGcloudProjectNumbers_1 = __nccwpck_require__(22661);
606
678
  const setupProject = async (instance, onlyComponents) => {
679
+ // must come first: creating contexts already requires the store
680
+ await (0, ensureGcloudProjectNumbers_1.ensureGcloudProjectNumbers)(instance);
607
681
  const allContext = await (0, getProjectConfig_1.getAllPipelineContexts)(onlyComponents);
608
682
  instance.log("will setup those contexts:");
609
683
  allContext.forEach(context => {
@@ -4373,7 +4447,7 @@ exports.uninstallCompletions = uninstallCompletions;
4373
4447
  Object.defineProperty(exports, "__esModule", ({
4374
4448
  value: true
4375
4449
  }));
4376
- exports.getJobOnlyEnvVarsResolved = exports.getEnvVarsResolved = exports.getGitlabVar = exports.getEnvironment = exports.getAllPipelineContexts = exports.getAllComponentsWithAllEnvsHierarchical = exports.getAllComponentsWithAllEnvsFlat = exports.getPipelineContextByChoice = exports.getProjectComponents = exports.getProjectConfig = exports.parseChoice = void 0;
4450
+ exports.getJobOnlyEnvVarsResolved = exports.getEnvVarsResolved = exports.getGitlabVar = exports.getEnvironment = exports.getAllPipelineContexts = exports.getAllComponentsWithAllEnvsHierarchical = exports.getAllComponentsWithAllEnvsFlat = exports.getPipelineContextByChoice = exports.getProjectComponents = exports.invalidateProjectConfig = exports.getProjectConfig = exports.parseChoice = void 0;
4377
4451
  const pipeline_1 = __nccwpck_require__(60241);
4378
4452
  const gitlab_1 = __nccwpck_require__(4508);
4379
4453
  const projects_1 = __nccwpck_require__(57414);
@@ -4403,6 +4477,15 @@ const getProjectConfig = async () => {
4403
4477
  return currentConfig;
4404
4478
  };
4405
4479
  exports.getProjectConfig = getProjectConfig;
4480
+ /**
4481
+ * drops the cached config so the next access re-reads it from disk —
4482
+ * needed after writing the catladder store, which is attached to the
4483
+ * config (`config.store`) at read time
4484
+ */
4485
+ const invalidateProjectConfig = () => {
4486
+ currentConfig = null;
4487
+ };
4488
+ exports.invalidateProjectConfig = invalidateProjectConfig;
4406
4489
  const getProjectComponents = async () => {
4407
4490
  const config = await (0, exports.getProjectConfig)();
4408
4491
  if (!config) return [];
@@ -4661,8 +4744,12 @@ const createCopyDbScript = ({
4661
4744
  const copyDBScript = `
4662
4745
  set -e
4663
4746
 
4664
- ${targetPSQL(`-c 'drop database "${targetDbName}" WITH (FORCE)' 1> /dev/null || true`)}
4665
- ${targetPSQL(`-c 'create database "${targetDbName}"' 1> /dev/null`)}
4747
+ ${targetPSQL(
4748
+ // connect to the always-existing "postgres" maintenance database:
4749
+ // without an explicit dbname, psql falls back to the username and
4750
+ // fails with e.g. 'FATAL: database "user" does not exist'
4751
+ `--dbname=postgres -c 'drop database "${targetDbName}" WITH (FORCE)' 1> /dev/null || true`)}
4752
+ ${targetPSQL(`--dbname=postgres -c 'create database "${targetDbName}"' 1> /dev/null`)}
4666
4753
  echo "Estimating database size..."
4667
4754
  DB_SIZE=$(PGPASSWORD=${encodedSourcePassword} psql --dbname=postgres://${encodedSourceUsername}:${encodedSourcePassword}@localhost:${sourcePort}/${sourceDbName} -t -A -c "SELECT pg_database_size('${sourceDbName}')")
4668
4755
  # pg_database_size includes indexes, TOAST, and free space — pg_dump output is roughly 40% of that
@@ -10309,7 +10396,7 @@ Object.defineProperty(exports, "__esModule", ({
10309
10396
  value: true
10310
10397
  }));
10311
10398
  exports.DOCKER_REGISTRY = exports.PIPELINE_IMAGE_TAG = void 0;
10312
- exports.PIPELINE_IMAGE_TAG = "next-1cd29c1f" || 0;
10399
+ exports.PIPELINE_IMAGE_TAG = "next-52feb889" || 0;
10313
10400
  exports.DOCKER_REGISTRY = "git.panter.ch:5001/catladder/catladder" || 0;
10314
10401
 
10315
10402
  /***/ }),
@@ -10920,6 +11007,7 @@ Object.defineProperty(exports, "__esModule", ({
10920
11007
  value: true
10921
11008
  }));
10922
11009
  __exportStar(__nccwpck_require__(14847), exports);
11010
+ __exportStar(__nccwpck_require__(57044), exports);
10923
11011
  __exportStar(__nccwpck_require__(14956), exports);
10924
11012
  __exportStar(__nccwpck_require__(85855), exports);
10925
11013
 
@@ -11324,7 +11412,9 @@ exports.RUNNER_IMAGE_BUILD_CONTEXT = {
11324
11412
  */
11325
11413
  const getShippedImagesDir = () => {
11326
11414
  const candidates = [
11327
- // built package: dist/customImages -> dist/runner-images
11415
+ // built pipeline package: dist/customImages -> dist/runner-images
11416
+ // bundled cli package (what consumers install): the ncc bundles live
11417
+ // in dist/bundles/<name>, so both resolve to dist/bundles/runner-images
11328
11418
  (0, path_1.join)(__dirname, "..", "runner-images"),
11329
11419
  // repository: pipeline/src/customImages -> <root>/runner-images
11330
11420
  (0, path_1.join)(__dirname, "..", "..", "..", "runner-images")];
@@ -12205,8 +12295,11 @@ const getCreateScheduleScript = context => {
12205
12295
  config
12206
12296
  }, jobIndex) => {
12207
12297
  var _a;
12298
+ // `headers` is pulled out of the shared args because the flag name differs
12299
+ // between create (`--headers`) and update (`--update-headers`).
12208
12300
  const {
12209
12301
  uri,
12302
+ headers,
12210
12303
  ...args
12211
12304
  } = getSchedulerArgs(config, context);
12212
12305
  const argsString = (0, createArgsString_1.createArgsString)({
@@ -12217,12 +12310,15 @@ const getCreateScheduleScript = context => {
12217
12310
  schedule: `"${config.schedule}"`,
12218
12311
  "max-retry-attempts": (_a = config.maxRetryAttempts) !== null && _a !== void 0 ? _a : 0
12219
12312
  });
12220
- return [jobIndex === 0 ? `exist_scheduler_names="$(\n ${(0, common_1.gcloudSchedulerCmd)()} jobs list --filter='httpTarget.uri ~ ${context.env}.*${context.name}' --format='value(name)' --limit=999 --location='${location}' --project='${project}'\n)"` : null, `current_job_uri="${uri}"`, `current_scheduler_name="${fullName}"`, `if echo "$exist_scheduler_names" | grep -Fx "$current_scheduler_name" >/dev/null; then`, ` ${(0, common_1.gcloudSchedulerCmd)()} jobs update http "$current_scheduler_name" ${argsString}`, `else`, ` ${(0, common_1.gcloudSchedulerCmd)()} jobs create http "$current_scheduler_name" ${argsString}`, `fi`].filter(utils_1.notNil).join("\n");
12313
+ const headersValue = headers ? `"${(0, bash_1.bashEscape)(headers)}"` : undefined;
12314
+ const createHeadersArg = headersValue ? ` --headers=${headersValue}` : "";
12315
+ const updateHeadersArg = headersValue ? ` --update-headers=${headersValue}` : "";
12316
+ return [jobIndex === 0 ? `exist_scheduler_names="$(\n ${(0, common_1.gcloudSchedulerCmd)()} jobs list --filter='httpTarget.uri ~ ${context.env}.*${context.name}' --format='value(name)' --limit=999 --location='${location}' --project='${project}'\n)"` : null, `current_job_uri="${uri}"`, `current_scheduler_name="${fullName}"`, `if echo "$exist_scheduler_names" | grep -Fx "$current_scheduler_name" >/dev/null; then`, ` ${(0, common_1.gcloudSchedulerCmd)()} jobs update http "$current_scheduler_name" ${argsString}${updateHeadersArg}`, `else`, ` ${(0, common_1.gcloudSchedulerCmd)()} jobs create http "$current_scheduler_name" ${argsString}${createHeadersArg}`, `fi`].filter(utils_1.notNil).join("\n");
12221
12317
  });
12222
12318
  };
12223
12319
  exports.getCreateScheduleScript = getCreateScheduleScript;
12224
12320
  const getSchedulerArgs = (scheduler, context) => {
12225
- var _a;
12321
+ var _a, _b;
12226
12322
  if (scheduler.type === "job") {
12227
12323
  const {
12228
12324
  projectId,
@@ -12250,10 +12346,19 @@ const getSchedulerArgs = (scheduler, context) => {
12250
12346
  };
12251
12347
  }
12252
12348
  if (scheduler.type === "http") {
12349
+ // default the Content-Type to application/json when a body is sent and the
12350
+ // user didn't set one explicitly. Otherwise Cloud Scheduler falls back to
12351
+ // application/octet-stream, which is rarely what's intended.
12352
+ const hasContentType = Object.keys((_b = scheduler.headers) !== null && _b !== void 0 ? _b : {}).some(k => k.toLowerCase() === "content-type");
12353
+ const headers = scheduler.body && !hasContentType ? {
12354
+ "Content-Type": "application/json",
12355
+ ...scheduler.headers
12356
+ } : scheduler.headers;
12253
12357
  return {
12254
12358
  uri: scheduler.url,
12255
- "message-body": scheduler.body,
12359
+ "message-body": scheduler.body ? '"' + (0, bash_1.bashEscape)(scheduler.body) + '"' : undefined,
12256
12360
  "http-method": scheduler.method,
12361
+ headers: headers ? Object.entries(headers).map(([k, v]) => `${k}=${v}`).join(",") : undefined,
12257
12362
  "oidc-service-account-email": `"${(0, common_1.getComputeServiceAccountEmail)(context)}"`
12258
12363
  };
12259
12364
  }
@@ -14870,6 +14975,10 @@ exports.getCatladderStorePath = getCatladderStorePath;
14870
14975
  /**
14871
14976
  * reads and validates the catladder store. Returns an empty store when the
14872
14977
  * file does not exist (project setup has not run yet).
14978
+ *
14979
+ * An unreadable or invalid store is treated the same as a missing one
14980
+ * (with a warning): the store only holds machine-fetched values, so the
14981
+ * remedy is always rerunning project setup — not hand-editing the file.
14873
14982
  */
14874
14983
  const readCatladderStore = (directory = process.cwd()) => {
14875
14984
  var _a;
@@ -14877,9 +14986,14 @@ const readCatladderStore = (directory = process.cwd()) => {
14877
14986
  if (!(0, fs_1.existsSync)(path)) {
14878
14987
  return {};
14879
14988
  }
14880
- return exports.catladderStoreSchema.parse((_a = (0, yaml_1.parse)((0, fs_1.readFileSync)(path, {
14881
- encoding: "utf-8"
14882
- }))) !== null && _a !== void 0 ? _a : {});
14989
+ try {
14990
+ return exports.catladderStoreSchema.parse((_a = (0, yaml_1.parse)((0, fs_1.readFileSync)(path, {
14991
+ encoding: "utf-8"
14992
+ }))) !== null && _a !== void 0 ? _a : {});
14993
+ } catch (error) {
14994
+ console.warn(`⚠️ ignoring invalid ${exports.CATLADDER_STORE_FILE} (rerun "catladder project setup" to regenerate it): ${error instanceof Error ? error.message : error}`);
14995
+ return {};
14996
+ }
14883
14997
  };
14884
14998
  exports.readCatladderStore = readCatladderStore;
14885
14999
  /**
@@ -0,0 +1,5 @@
1
+ FROM node:24-alpine3.21
2
+
3
+ RUN apk update && apk add --no-cache git curl bash
4
+
5
+ RUN npm install -g @anthropic-ai/claude-code@2.1.139 @zereight/mcp-gitlab@2.1.10
@@ -0,0 +1,26 @@
1
+
2
+ FROM docker:29.5.1
3
+
4
+ # add bash
5
+ RUN apk add --no-cache bash
6
+
7
+ # for glcoud
8
+ ARG GCLOUD_SDK_VERSION=525.0.0
9
+
10
+ RUN apk --update add curl python3 py3-crcmod libc6-compat
11
+ RUN curl -O https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-${GCLOUD_SDK_VERSION}-linux-x86_64.tar.gz && \
12
+ tar zxvf google-cloud-sdk-${GCLOUD_SDK_VERSION}-linux-x86_64.tar.gz && \
13
+ rm google-cloud-sdk-${GCLOUD_SDK_VERSION}-linux-x86_64.tar.gz && \
14
+ ./google-cloud-sdk/install.sh
15
+ ENV PATH="/google-cloud-sdk/bin:${PATH}"
16
+
17
+ # end gcloud
18
+
19
+ # for scripts
20
+
21
+ RUN mkdir p /scripts
22
+ COPY ./scripts/* /scripts/
23
+ RUN chmod +x /scripts/*
24
+
25
+ ENV PATH="/scripts:${PATH}"
26
+
@@ -0,0 +1,55 @@
1
+ #!/bin/bash
2
+
3
+ if [ ! -f $APP_DIR/.dockerignore ]; then
4
+
5
+ cat >$APP_DIR/.dockerignore <<EOF
6
+ $APP_DIR/node_modules
7
+ **/__snapshots__/**
8
+ .git
9
+
10
+ EOF
11
+ fi
12
+
13
+ if [ ! -f $APP_DIR/Dockerfile ]; then
14
+ echo "Creating Dockerfile"
15
+ if [[ ! -z "$METEOR_OVERRIDE_NODE_VERSION" ]]; then
16
+ NODE_VERSION=$METEOR_OVERRIDE_NODE_VERSION
17
+ else
18
+ NODE_VERSION_FULL=$(cat $APP_DIR/dist/bundle/.node_version.txt)
19
+ NODE_VERSION=${NODE_VERSION_FULL/v/} # remove v
20
+ fi
21
+ if [ "$NODE_VERSION" = "14.21.4" ]; then
22
+ DOCKER_IMAGE="meteor/node:$NODE_VERSION" # meteor maintenance for because of fibers
23
+ else
24
+ DOCKER_IMAGE="node:$NODE_VERSION"
25
+ fi
26
+ cat >$APP_DIR/Dockerfile <<EOF
27
+ FROM $DOCKER_IMAGE
28
+
29
+ # install yarn. new meteor image has no yarn installed
30
+ # only install if it does not exist
31
+ RUN command -v yarn || npm install --global yarn
32
+
33
+
34
+ $DOCKERFILE_ADDITIONS
35
+
36
+ # we copy also source code and scripts for commands
37
+ # This is technically not required for meteor, but useful if we have additional scripts
38
+ WORKDIR /src
39
+ $METEOR_INSTALL_SCRIPTS
40
+
41
+
42
+ # copy the bundle
43
+ COPY $APP_DIR/dist /src/dist
44
+
45
+ # now install meteor deps
46
+ RUN cd /src/dist/bundle/programs/server && npm install
47
+
48
+ $DOCKERFILE_ADDITIONS_END
49
+
50
+ WORKDIR /src/dist/bundle
51
+
52
+ CMD ["node", "main.js"]
53
+ EOF
54
+
55
+ fi
@@ -0,0 +1,85 @@
1
+ #!/bin/bash
2
+
3
+ # ensure nginx config
4
+ echo "ensureNginxDockerfile in $APP_DIR"
5
+
6
+ if [ ! -f $APP_DIR/nginx.conf ]; then
7
+ echo "Creating nginx.conf"
8
+
9
+ cat >$APP_DIR/nginx.conf <<NGINX
10
+
11
+ server {
12
+ listen 8080;
13
+ server_name localhost;
14
+ error_page 404 =200 /index.html;
15
+
16
+ charset utf-8;
17
+
18
+ add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
19
+ add_header Referrer-Policy "strict-origin-when-cross-origin";
20
+ add_header X-Content-Type-Options "nosniff";
21
+ add_header X-Frame-Options "SAMEORIGIN";
22
+
23
+ location / {
24
+ root /usr/share/nginx/html;
25
+ index index.html index.htm;
26
+ }
27
+
28
+ location /__health {
29
+ access_log off;
30
+ types { } default_type "text/html; charset=utf-8";
31
+ return 200 "ok\n";
32
+ }
33
+
34
+ # https://trac.nginx.org/nginx/ticket/2216
35
+ include mime.types;
36
+ types
37
+ {
38
+ application/javascript mjs;
39
+ }
40
+ }
41
+
42
+ NGINX
43
+
44
+ fi
45
+ # ensure docker ignore
46
+ if [ ! -f $APP_DIR/.dockerignore ]; then
47
+
48
+ cat >.dockerignore <<EOF
49
+ **/node_modules
50
+ **/__snapshots__/**
51
+ .git
52
+
53
+ EOF
54
+
55
+ fi
56
+
57
+ if [ ! -f $APP_DIR/Dockerfile ]; then
58
+ echo "Creating Dockerfile"
59
+
60
+ cat >$APP_DIR/Dockerfile <<EOF
61
+
62
+ $DOCKERFILE_ADDITIONS
63
+
64
+ FROM nginx:stable
65
+ WORKDIR /app
66
+
67
+ RUN sed --in-place "s/^\s*user .*//" /etc/nginx/nginx.conf && \
68
+ chown -R nginx:nginx /app && \
69
+ chmod -R 755 /app && \
70
+ chown -R nginx:nginx /var/cache/nginx && \
71
+ chown -R nginx:nginx /var/log/nginx && \
72
+ chown -R nginx:nginx /etc/nginx/conf.d && \
73
+ touch /var/run/nginx.pid && \
74
+ chown -R nginx:nginx /var/run/nginx.pid
75
+
76
+ COPY $APP_DIR/nginx.conf /etc/nginx/conf.d/default.conf
77
+ COPY $APP_DIR/dist/ /usr/share/nginx/html/
78
+
79
+ $DOCKERFILE_ADDITIONS_END
80
+
81
+ USER nginx
82
+ EXPOSE 8080
83
+
84
+ EOF
85
+ fi
@@ -0,0 +1,50 @@
1
+ #!/bin/bash
2
+
3
+ # the default dockerfile includes node alpine
4
+
5
+ # the dockerignore ignores node_modules as these have to be rebuilt anyway
6
+ # as well as __snapshots__ are used for unitests (if any)
7
+
8
+ if [ ! -f $APP_DIR/.dockerignore ]; then
9
+
10
+ cat >$APP_DIR/.dockerignore <<EOF
11
+ **/node_modules
12
+ **/__snapshots__/**
13
+ .git
14
+
15
+ EOF
16
+
17
+ fi
18
+
19
+ if [ -f $APP_DIR/.nvmrc ]; then
20
+ NODE_VERSION="$(cat $APP_DIR/.nvmrc | sed '/^$/d' | sed 's/[a-z-]//g')"
21
+ elif [ -f .nvmrc ]; then
22
+ NODE_VERSION="$(cat .nvmrc | sed '/^$/d' | sed 's/[a-z-]//g')"
23
+ else
24
+ NODE_VERSION=14
25
+ fi
26
+
27
+ if [ ! -f $APP_DIR/Dockerfile ]; then
28
+ echo "Creating Dockerfile"
29
+
30
+ cat >$APP_DIR/Dockerfile <<EOF
31
+ FROM node:$NODE_VERSION-alpine
32
+
33
+
34
+
35
+ $DOCKERFILE_ADDITIONS
36
+
37
+ RUN apk add --no-cache git curl
38
+ USER node
39
+
40
+ $DOCKER_COPY_WORKSPACE_FILES
41
+
42
+ WORKDIR /app/$APP_DIR
43
+
44
+ $DOCKER_COPY_AND_INSTALL_APP
45
+
46
+
47
+ $DOCKERFILE_ADDITIONS_END
48
+
49
+ EOF
50
+ fi
@@ -0,0 +1,3 @@
1
+
2
+ FROM google/cloud-sdk:latest
3
+
@@ -0,0 +1,22 @@
1
+
2
+
3
+ FROM node:18
4
+
5
+ RUN rm /bin/sh && \
6
+ ln -s /bin/bash /bin/sh && \
7
+ mkdir -p /root/.nvm
8
+
9
+ # set high timeout for yarn, see https://github.com/dhis2/notes/issues/29
10
+ RUN yarn config set network-timeout 600000 -g
11
+
12
+ # install nvm && some common node versions
13
+ RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash && \
14
+ source /root/.nvm/nvm.sh && \
15
+ chmod +x /root/.nvm/nvm.sh && \
16
+ /root/.nvm/nvm.sh install 12 && \
17
+ /root/.nvm/nvm.sh install 14 && \
18
+ /root/.nvm/nvm.sh install 16 && \
19
+ /root/.nvm/nvm.sh install 18 && \
20
+ /root/.nvm/nvm.sh install 20 && \
21
+ /root/.nvm/nvm.sh install 22 && \
22
+ /root/.nvm/nvm.sh install 24
@@ -0,0 +1,7 @@
1
+ # syntax = docker.io/devthefuture/dockerfile-x
2
+
3
+
4
+ INCLUDE ./jobs-default/Dockerfile
5
+
6
+ # add meteor (used by some apps)
7
+ RUN curl https://install.meteor.com/?release=2.13.3 | sh
@@ -0,0 +1,15 @@
1
+ # syntax = docker.io/devthefuture/dockerfile-x
2
+
3
+ INCLUDE ./jobs-default/Dockerfile
4
+
5
+ # add sources
6
+ # Google Chrome (for testing purposes)
7
+ RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \
8
+ sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
9
+
10
+ # install some sources
11
+ # not sure if libxss1 is required
12
+ RUN apt-get update && apt-get install -y \
13
+ libxss1 \
14
+ google-chrome-stable
15
+
@@ -0,0 +1,26 @@
1
+
2
+ FROM alpine:3.15
3
+
4
+ # add bash curl and git
5
+ RUN apk add --no-cache bash curl git
6
+
7
+
8
+ # kubernetes & helm
9
+ ENV KUBERNETES_VERSION 1.19.14
10
+ RUN curl -L -o /usr/bin/kubectl "https://storage.googleapis.com/kubernetes-release/release/v${KUBERNETES_VERSION}/bin/linux/amd64/kubectl" ;\
11
+ chmod +x /usr/bin/kubectl ;\
12
+ kubectl version --client
13
+
14
+ # helm 3
15
+ ENV HELM_VERSION 3.10.0
16
+ RUN curl "https://get.helm.sh/helm-v${HELM_VERSION}-linux-amd64.tar.gz" | tar zx ;\
17
+ mv linux-amd64/helm /usr/bin/helm ;\
18
+ helm version --client
19
+
20
+
21
+ COPY ./scripts/* /scripts/
22
+ RUN chmod +x /scripts/*
23
+
24
+ ENV PATH="/scripts:${PATH}"
25
+
26
+ COPY ./helm-charts /helm-charts