@catladder/cli 0.0.0-next-d71e41ba → 0.0.0-next-dccc0a36

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 (91) hide show
  1. package/dist/apps/cli/src/scripts/generateCliSkillReference.js +3 -2
  2. package/dist/apps/cli/src/scripts/generateCliSkillReference.js.map +1 -1
  3. package/dist/bundles/catenv/index.js +790 -272
  4. package/dist/bundles/cli/index.js +790 -272
  5. package/dist/bundles/runner-images/docker-build/scripts/ensureNodeDockerfile +8 -1
  6. package/dist/bundles/runner-images/jobs-default/Dockerfile +4 -0
  7. package/dist/bundles/skills/catladder-builds/SKILL.md +68 -5
  8. package/dist/bundles/skills/catladder-builds/references/build-types.md +8 -6
  9. package/dist/bundles/skills/catladder-cli/references/commands.md +3 -2
  10. package/dist/bundles/skills/catladder-config/SKILL.md +5 -0
  11. package/dist/bundles/skills/catladder-deploys/SKILL.md +1 -1
  12. package/dist/bundles/skills/catladder-deploys/references/deploy-types.md +2 -2
  13. package/dist/bundles/skills/catladder-pipelines/SKILL.md +16 -4
  14. package/dist/packages/pipeline/src/backends/github/GithubBackend.js +4 -4
  15. package/dist/packages/pipeline/src/backends/github/GithubBackend.js.map +1 -1
  16. package/dist/packages/pipeline/src/backends/gitlab/GitlabBackend.js +4 -4
  17. package/dist/packages/pipeline/src/backends/gitlab/GitlabBackend.js.map +1 -1
  18. package/dist/packages/pipeline/src/build/base/createAppBuildJob.js +2 -2
  19. package/dist/packages/pipeline/src/build/base/createAppBuildJob.js.map +1 -1
  20. package/dist/packages/pipeline/src/build/index.d.ts +3 -3
  21. package/dist/packages/pipeline/src/build/index.js +16 -11
  22. package/dist/packages/pipeline/src/build/index.js.map +1 -1
  23. package/dist/packages/pipeline/src/build/node/buildJob.js +49 -8
  24. package/dist/packages/pipeline/src/build/node/buildJob.js.map +1 -1
  25. package/dist/packages/pipeline/src/build/node/cache.d.ts +5 -0
  26. package/dist/packages/pipeline/src/build/node/cache.js +58 -19
  27. package/dist/packages/pipeline/src/build/node/cache.js.map +1 -1
  28. package/dist/packages/pipeline/src/build/node/meteor.js +9 -4
  29. package/dist/packages/pipeline/src/build/node/meteor.js.map +1 -1
  30. package/dist/packages/pipeline/src/build/node/packageManagerInstall.d.ts +14 -0
  31. package/dist/packages/pipeline/src/build/node/packageManagerInstall.js +145 -0
  32. package/dist/packages/pipeline/src/build/node/packageManagerInstall.js.map +1 -0
  33. package/dist/packages/pipeline/src/build/node/testJob.js +9 -11
  34. package/dist/packages/pipeline/src/build/node/testJob.js.map +1 -1
  35. package/dist/packages/pipeline/src/build/types.d.ts +6 -5
  36. package/dist/packages/pipeline/src/build/types.js.map +1 -1
  37. package/dist/packages/pipeline/src/context/createComponentContext.js +3 -2
  38. package/dist/packages/pipeline/src/context/createComponentContext.js.map +1 -1
  39. package/dist/packages/pipeline/src/context/createWorkspaceContext.js +3 -2
  40. package/dist/packages/pipeline/src/context/createWorkspaceContext.js.map +1 -1
  41. package/dist/packages/pipeline/src/customImages/hash.d.ts +9 -0
  42. package/dist/packages/pipeline/src/customImages/hash.js +41 -16
  43. package/dist/packages/pipeline/src/customImages/hash.js.map +1 -1
  44. package/dist/packages/pipeline/src/customImages/jobImagesPlan.d.ts +23 -5
  45. package/dist/packages/pipeline/src/customImages/jobImagesPlan.js +177 -43
  46. package/dist/packages/pipeline/src/customImages/jobImagesPlan.js.map +1 -1
  47. package/dist/packages/pipeline/src/customImages/projectImages.d.ts +67 -0
  48. package/dist/packages/pipeline/src/customImages/projectImages.js +9 -0
  49. package/dist/packages/pipeline/src/customImages/projectImages.js.map +1 -0
  50. package/dist/packages/pipeline/src/deploy/custom/deployJob.js +7 -6
  51. package/dist/packages/pipeline/src/deploy/custom/deployJob.js.map +1 -1
  52. package/dist/packages/pipeline/src/deploy/pages/deployJob.js +6 -4
  53. package/dist/packages/pipeline/src/deploy/pages/deployJob.js.map +1 -1
  54. package/dist/packages/pipeline/src/deploy/types/custom.d.ts +9 -3
  55. package/dist/packages/pipeline/src/deploy/types/index.d.ts +4 -4
  56. package/dist/packages/pipeline/src/deploy/types/pages.d.ts +9 -3
  57. package/dist/packages/pipeline/src/index.d.ts +2 -0
  58. package/dist/packages/pipeline/src/index.js +2 -0
  59. package/dist/packages/pipeline/src/index.js.map +1 -1
  60. package/dist/packages/pipeline/src/pipeline/detectPackageManager.d.ts +18 -0
  61. package/dist/packages/pipeline/src/pipeline/detectPackageManager.js +76 -0
  62. package/dist/packages/pipeline/src/pipeline/detectPackageManager.js.map +1 -0
  63. package/dist/packages/pipeline/src/pipeline/packageManager.d.ts +1 -1
  64. package/dist/packages/pipeline/src/pipeline/packageManager.js +43 -9
  65. package/dist/packages/pipeline/src/pipeline/packageManager.js.map +1 -1
  66. package/dist/packages/pipeline/src/pipeline/pnpm/pnpmUtils.d.ts +14 -0
  67. package/dist/packages/pipeline/src/pipeline/pnpm/pnpmUtils.js +93 -0
  68. package/dist/packages/pipeline/src/pipeline/pnpm/pnpmUtils.js.map +1 -0
  69. package/dist/packages/pipeline/src/types/config.d.ts +16 -1
  70. package/dist/packages/pipeline/src/types/config.js.map +1 -1
  71. package/dist/packages/pipeline/src/types/context.d.ts +11 -3
  72. package/dist/packages/pipeline/src/types/context.js.map +1 -1
  73. package/dist/packages/pipeline/src/types/jobs.d.ts +2 -1
  74. package/dist/packages/pipeline/src/types/jobs.js.map +1 -1
  75. package/dist/packages/pipeline/src/verify/createVerifyJobs.js +5 -5
  76. package/dist/packages/pipeline/src/verify/createVerifyJobs.js.map +1 -1
  77. package/dist/runner-images/docker-build/scripts/ensureNodeDockerfile +8 -1
  78. package/dist/runner-images/jobs-default/Dockerfile +4 -0
  79. package/dist/skills/catladder-builds/SKILL.md +68 -5
  80. package/dist/skills/catladder-builds/references/build-types.md +8 -6
  81. package/dist/skills/catladder-cli/references/commands.md +3 -2
  82. package/dist/skills/catladder-config/SKILL.md +5 -0
  83. package/dist/skills/catladder-deploys/SKILL.md +1 -1
  84. package/dist/skills/catladder-deploys/references/deploy-types.md +2 -2
  85. package/dist/skills/catladder-pipelines/SKILL.md +16 -4
  86. package/dist/tsconfig.tsbuildinfo +1 -1
  87. package/package.json +1 -1
  88. package/src/scripts/generateCliSkillReference.ts +3 -2
  89. package/dist/packages/pipeline/src/build/node/yarn.d.ts +0 -8
  90. package/dist/packages/pipeline/src/build/node/yarn.js +0 -78
  91. package/dist/packages/pipeline/src/build/node/yarn.js.map +0 -1
@@ -2321,7 +2321,7 @@ class GithubBackend {
2321
2321
  await (0, promises_1.rm)(scriptFiles_1.GITHUB_SCRIPTS_FOLDER, { recursive: true, force: true });
2322
2322
  }
2323
2323
  async createFiles(config) {
2324
- const images = this.createImagesPlan();
2324
+ const images = this.createImagesPlan(config);
2325
2325
  const scripts = new scriptFiles_1.GithubScriptFiles();
2326
2326
  const workflows = await this.createWorkflows(config, images, scripts);
2327
2327
  return [
@@ -2336,13 +2336,13 @@ class GithubBackend {
2336
2336
  ...(0, shippedCatci_1.getCatciGeneratedFiles)(),
2337
2337
  ];
2338
2338
  }
2339
- createImagesPlan() {
2340
- return new jobImagesPlan_1.JobImagesPlan(this.type);
2339
+ createImagesPlan(config) {
2340
+ return new jobImagesPlan_1.JobImagesPlan(this.type, config.images);
2341
2341
  }
2342
2342
  /**
2343
2343
  * all workflows keyed by file name, mainly for testing purposes
2344
2344
  */
2345
- async createWorkflows(config, images = this.createImagesPlan(), scripts = new scriptFiles_1.GithubScriptFiles()) {
2345
+ async createWorkflows(config, images = this.createImagesPlan(config), scripts = new scriptFiles_1.GithubScriptFiles()) {
2346
2346
  var _a, _b, _c, _d;
2347
2347
  const workflows = {};
2348
2348
  // per-pipeline-type variables (pipelines.github.runnerVariables);
@@ -3311,7 +3311,7 @@ class GitlabBackend {
3311
3311
  await (0, promises_1.rm)(this.generatedFolder, { force: true, recursive: true });
3312
3312
  }
3313
3313
  async createFiles(config) {
3314
- const images = this.createImagesPlan();
3314
+ const images = this.createImagesPlan(config);
3315
3315
  const includes = await this.createIncludes(config, images);
3316
3316
  const mainFile = {
3317
3317
  path: ".gitlab-ci.yml",
@@ -3328,15 +3328,15 @@ class GitlabBackend {
3328
3328
  ...(0, shippedCatci_1.getCatciGeneratedFiles)(),
3329
3329
  ];
3330
3330
  }
3331
- createImagesPlan() {
3332
- return new jobImagesPlan_1.JobImagesPlan(this.type);
3331
+ createImagesPlan(config) {
3332
+ return new jobImagesPlan_1.JobImagesPlan(this.type, config.images);
3333
3333
  }
3334
3334
  /**
3335
3335
  * the complete pipeline as one object (all includes merged into one),
3336
3336
  * mainly for testing purposes
3337
3337
  */
3338
3338
  async createCompletePipeline(config) {
3339
- const includes = await this.createIncludes(config, this.createImagesPlan());
3339
+ const includes = await this.createIncludes(config, this.createImagesPlan(config));
3340
3340
  return includes.reduce((acc, { content }) => {
3341
3341
  return {
3342
3342
  ...acc,
@@ -4428,7 +4428,7 @@ const jobs_1 = __nccwpck_require__(28006);
4428
4428
  const utils_1 = __nccwpck_require__(24516);
4429
4429
  const removeUndefined_1 = __nccwpck_require__(54420);
4430
4430
  const createBuildJobArtifact_1 = __nccwpck_require__(98820);
4431
- const yarn_1 = __nccwpck_require__(59874);
4431
+ const packageManagerInstall_1 = __nccwpck_require__(18600);
4432
4432
  const constants_1 = __nccwpck_require__(69302);
4433
4433
  const writeBuildInfo_1 = __nccwpck_require__(92254);
4434
4434
  const writeDotEnv_1 = __nccwpck_require__(76670);
@@ -4468,7 +4468,7 @@ class AppBuildJob extends jobs_1.CatladderJob {
4468
4468
  .flatMap((c) => (0, writeDotEnv_1.writeDotEnv)(c))
4469
4469
  : []),
4470
4470
  ...(context.type === "component" ? (0, writeBuildInfo_1.writeBuildInfo)(context) : []),
4471
- ...(0, yarn_1.ensureNodeVersion)(context), // in pure node repos, we might want to have the nvmrc file in top-level
4471
+ ...(0, packageManagerInstall_1.ensureNodeVersion)(context), // in pure node repos, we might want to have the nvmrc file in top-level
4472
4472
  `cd ${context.build.dir}`,
4473
4473
  ...(0, utils_1.ensureArray)(script),
4474
4474
  ],
@@ -5165,27 +5165,32 @@ const node_1 = __nccwpck_require__(23114);
5165
5165
  const rails_1 = __nccwpck_require__(42427);
5166
5166
  __exportStar(__nccwpck_require__(23114), exports);
5167
5167
  __exportStar(__nccwpck_require__(40632), exports);
5168
+ /**
5169
+ * run a package.json script with the project's package manager
5170
+ * (`yarn build` / `pnpm build`)
5171
+ */
5172
+ const runScript = (packageManager, script) => `${packageManager} ${script}`;
5168
5173
  exports.BUILD_TYPES = {
5169
5174
  node: {
5170
5175
  jobs: node_1.createNodeJobs,
5171
- defaults: () => ({
5172
- buildCommand: "yarn build",
5173
- startCommand: "yarn start",
5176
+ defaults: (_, pm) => ({
5177
+ buildCommand: runScript(pm, "build"),
5178
+ startCommand: runScript(pm, "start"),
5174
5179
  artifactsPaths: ["dist", ".next"],
5175
5180
  artifactsExcludePaths: [".next/cache/**/*"],
5176
5181
  }),
5177
5182
  },
5178
5183
  "node-static": {
5179
5184
  jobs: node_1.createNodeJobs,
5180
- defaults: () => ({
5181
- buildCommand: "yarn build",
5185
+ defaults: (_, pm) => ({
5186
+ buildCommand: runScript(pm, "build"),
5182
5187
  artifactsPaths: ["dist"],
5183
5188
  }),
5184
5189
  },
5185
5190
  storybook: {
5186
5191
  jobs: node_1.createStorybookJobs,
5187
- defaults: () => ({
5188
- buildCommand: ["yarn build-storybook --quiet -o ./dist"],
5192
+ defaults: (_, pm) => ({
5193
+ buildCommand: [runScript(pm, "build-storybook --quiet -o ./dist")],
5189
5194
  artifactsPaths: ["dist"],
5190
5195
  }),
5191
5196
  },
@@ -5215,13 +5220,13 @@ exports.BUILD_TYPES = {
5215
5220
  exports.WORKSPACE_BUILD_TYPES = {
5216
5221
  node: {
5217
5222
  jobs: node_1.createNodeJobs,
5218
- defaults: () => ({
5219
- buildCommand: "yarn build",
5223
+ defaults: (pm) => ({
5224
+ buildCommand: runScript(pm, "build"),
5220
5225
  lint: {
5221
- command: "yarn lint",
5226
+ command: runScript(pm, "lint"),
5222
5227
  },
5223
5228
  test: {
5224
- command: "yarn test",
5229
+ command: runScript(pm, "test"),
5225
5230
  },
5226
5231
  }),
5227
5232
  },
@@ -5242,7 +5247,7 @@ const base_1 = __nccwpck_require__(61619);
5242
5247
  const createBuildJobDefinition_1 = __nccwpck_require__(88685);
5243
5248
  const docker_1 = __nccwpck_require__(83777);
5244
5249
  const cache_1 = __nccwpck_require__(21100);
5245
- const yarn_1 = __nccwpck_require__(59874);
5250
+ const packageManagerInstall_1 = __nccwpck_require__(18600);
5246
5251
  const createNodeBuildJobs = async (context) => {
5247
5252
  if (context.type === "workspace") {
5248
5253
  return (0, base_1.createWorkspaceBuildJobs)(context, {
@@ -5259,18 +5264,17 @@ const createNodeBuildJobs = async (context) => {
5259
5264
  exports.createNodeBuildJobs = createNodeBuildJobs;
5260
5265
  const createNodeBuildJobDefinition = async (context) => {
5261
5266
  const buildConfig = context.build.config;
5262
- const [yarnInstall, nodeCache] = await Promise.all([
5263
- (0, yarn_1.getYarnInstall)(context),
5267
+ const [packageManagerInstall, nodeCache] = await Promise.all([
5268
+ (0, packageManagerInstall_1.getPackageManagerInstall)(context),
5264
5269
  (0, cache_1.getNodeCache)(context),
5265
5270
  ]);
5266
5271
  return (0, createBuildJobDefinition_1.createBuildJobDefinition)(context, buildConfig, {
5267
- prescript: yarnInstall,
5272
+ prescript: packageManagerInstall,
5268
5273
  cache: nodeCache,
5269
5274
  });
5270
5275
  };
5271
5276
  exports.createNodeBuildJobDefinition = createNodeBuildJobDefinition;
5272
5277
  const createNodeDockerJobDefinition = async (context) => {
5273
- var _a;
5274
5278
  // get the default docker built-in type based on the build type
5275
5279
  const dockerDefaultBuiltIn = context.build.buildType === "node-static" ||
5276
5280
  context.build.buildType === "storybook"
@@ -5278,16 +5282,58 @@ const createNodeDockerJobDefinition = async (context) => {
5278
5282
  : "node";
5279
5283
  const [yarnCache, dockerAppCopyAndBuildScript, packageManagerInfo] = await Promise.all([
5280
5284
  (0, cache_1.getYarnCache)(context, "pull"),
5281
- (0, yarn_1.getDockerAppCopyAndBuildScript)(context),
5285
+ (0, packageManagerInstall_1.getDockerAppCopyAndBuildScript)(context),
5282
5286
  context.packageManagerInfo,
5283
5287
  ]);
5288
+ // the pnpm store (pulled via the cache above) is copied into the
5289
+ // image so the prod install works offline — like the yarn zip cache,
5290
+ // which travels inside the copied `.yarn` config folder
5291
+ const copyPnpmStore = packageManagerInfo.type === "pnpm" &&
5292
+ packageManagerInfo.componentIsInWorkspace;
5293
+ // pnpm copies every workspace manifest into the image — as individual
5294
+ // COPY instructions that many layers exceed docker's depth limit, so
5295
+ // the job tars them up and a single ADD extracts them
5296
+ const isPnpm = packageManagerInfo.type === "pnpm";
5297
+ const WORKSPACE_FILES_TAR = ".catladder-workspace-files.tar";
5284
5298
  return {
5285
- script: (0, docker_1.getDockerBuildScriptWithBuiltInDockerFile)(context, dockerDefaultBuiltIn),
5299
+ script: [
5300
+ // the COPY source must exist even when the cache was cold
5301
+ ...(copyPnpmStore ? ["mkdir -p .pnpm-store"] : []),
5302
+ ...(isPnpm
5303
+ ? [
5304
+ `tar -cf ${WORKSPACE_FILES_TAR} ${packageManagerInfo.pathsToCopyInDocker.join(" ")}`,
5305
+ ]
5306
+ : []),
5307
+ ...(0, docker_1.getDockerBuildScriptWithBuiltInDockerFile)(context, dockerDefaultBuiltIn),
5308
+ ],
5286
5309
  cache: [...yarnCache],
5287
5310
  variables: {
5288
5311
  // only required for non static
5289
5312
  DOCKER_COPY_AND_INSTALL_APP: dockerAppCopyAndBuildScript,
5290
- DOCKER_COPY_WORKSPACE_FILES: (_a = packageManagerInfo === null || packageManagerInfo === void 0 ? void 0 : packageManagerInfo.pathsToCopyInDocker.map((dir) => `COPY --chown=node:node ${dir} /app/${dir}`)) === null || _a === void 0 ? void 0 : _a.join("\n"),
5313
+ DOCKER_COPY_WORKSPACE_FILES: isPnpm
5314
+ ? [
5315
+ `ADD ${WORKSPACE_FILES_TAR} /app/`,
5316
+ // ADD does not apply --chown to extracted tars, and parent
5317
+ // dirs of the entries come out root-owned — fix ownership
5318
+ // while the stage still runs as root (store not copied yet,
5319
+ // so this only touches the small manifest tree). Custom
5320
+ // base images without a node user run as root and don't
5321
+ // need it, hence the fallback
5322
+ `RUN chown -R node:node /app || true`,
5323
+ ...(copyPnpmStore
5324
+ ? [`COPY --chown=node:node .pnpm-store /app/.pnpm-store`]
5325
+ : []),
5326
+ ].join("\n")
5327
+ : packageManagerInfo.pathsToCopyInDocker
5328
+ .map((dir) => `COPY --chown=node:node ${dir} /app/${dir}`)
5329
+ .join("\n"),
5330
+ // pnpm is not preinstalled in the node base images; installed as
5331
+ // root before the image switches to the node user
5332
+ ...(isPnpm
5333
+ ? {
5334
+ DOCKER_SETUP_PACKAGE_MANAGER: `RUN npm install -g pnpm@${packageManagerInfo.version}`,
5335
+ }
5336
+ : {}),
5291
5337
  },
5292
5338
  };
5293
5339
  };
@@ -5306,12 +5352,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5306
5352
  };
5307
5353
  Object.defineProperty(exports, "__esModule", ({ value: true }));
5308
5354
  exports.getNodeCache = exports.getNodeModulesCache = exports.getYarnCache = void 0;
5355
+ const lodash_es_1 = __nccwpck_require__(50866);
5309
5356
  const path_1 = __nccwpck_require__(16928);
5310
5357
  const slugify_1 = __importDefault(__nccwpck_require__(21396));
5311
5358
  /**
5312
- * stable reference between the two node caches: the yarn (zip) cache
5313
- * declares itself redundant when the node_modules cache scored an
5314
- * exact-lockfile hit (github skips the ~0.6GB download on warm runs)
5359
+ * stable reference between the two node caches: the package-manager
5360
+ * (yarn zip / pnpm store) cache declares itself redundant when the
5361
+ * node_modules cache scored an exact-lockfile hit (github skips the
5362
+ * ~0.6GB download on warm runs)
5315
5363
  */
5316
5364
  const NODE_MODULES_CACHE_ID = "node-modules";
5317
5365
  /**
@@ -5338,23 +5386,37 @@ const getCacheBaseDir = async (context) => {
5338
5386
  ? ((_a = context.build.workspaceBuildConfig.dir) !== null && _a !== void 0 ? _a : ".")
5339
5387
  : ".";
5340
5388
  };
5389
+ /**
5390
+ * the package manager's download cache: yarn's `.yarn` zip cache, or
5391
+ * pnpm's content-addressable store (which catladder points at a
5392
+ * project-local `.pnpm-store`, see the install script)
5393
+ */
5341
5394
  const getYarnCache = async (context, policy = "pull-push") => {
5395
+ const packageManagerInfo = await context.packageManagerInfo;
5396
+ const isPnpm = packageManagerInfo.type === "pnpm";
5342
5397
  const baseDir = await getCacheBaseDir(context);
5398
+ // pnpm keeps its store in a format-versioned subdir (v10, v11, ...)
5399
+ // and never cleans old ones up — scope the cache slot by major so a
5400
+ // pnpm upgrade starts a fresh slot instead of dragging the dead old
5401
+ // store tree along in every cache transfer (formats change only on
5402
+ // majors)
5403
+ const pnpmStoreKey = `pnpm-v${packageManagerInfo.version.split(".")[0]}`;
5343
5404
  return [
5344
5405
  {
5345
5406
  scope: "buildDir",
5346
5407
  pathMode: "relative",
5347
5408
  buildDir: baseDir,
5348
- key: "yarn",
5409
+ key: isPnpm ? pnpmStoreKey : "yarn",
5349
5410
  policy,
5350
- paths: [".yarn"],
5411
+ paths: [isPnpm ? ".pnpm-store" : ".yarn"],
5351
5412
  // content-key for immutable-cache backends (github); the lockfile
5352
5413
  // decides whether the cached content could have changed
5353
- keyFiles: ["yarn.lock"],
5354
- // the .yarn zips (~hundreds of MB) are only read when yarn has to
5355
- // (re)install packages. When the node_modules cache hit for the
5356
- // same lockfile, install verifies via install-state.gz and never
5357
- // opens a zip — so github skips downloading this cache entirely
5414
+ keyFiles: [isPnpm ? "pnpm-lock.yaml" : "yarn.lock"],
5415
+ // the package manager's download cache (~hundreds of MB) is only
5416
+ // read when packages have to be (re)installed. When the
5417
+ // node_modules cache hit for the same lockfile, install verifies
5418
+ // its state file and never touches the store — so github skips
5419
+ // downloading this cache entirely
5358
5420
  redundantOnExactHitOf: NODE_MODULES_CACHE_ID,
5359
5421
  },
5360
5422
  ];
@@ -5363,27 +5425,50 @@ exports.getYarnCache = getYarnCache;
5363
5425
  const getNodeModulesCache = async (context, policy = "pull-push") => {
5364
5426
  const packageManagerInfo = await context.packageManagerInfo;
5365
5427
  const baseDir = await getCacheBaseDir(context);
5366
- const { isClassic } = packageManagerInfo;
5367
- // We intentionally do not use the contents of yarn.lock as a cache key, as yarn install should always guarantee that the files are updated, but it can still use part of the cache if not all packages are up-to-date.
5428
+ const { workspaces } = packageManagerInfo;
5429
+ const isPnpm = packageManagerInfo.type === "pnpm";
5430
+ const lockFileName = isPnpm ? "pnpm-lock.yaml" : "yarn.lock";
5431
+ // yarn berry tracks install state in .yarn/install-state.gz (pnpm's
5432
+ // equivalent lives inside node_modules and is covered by the paths)
5433
+ const hasInstallState = packageManagerInfo.type === "yarn" && !packageManagerInfo.isClassic;
5434
+ // We intentionally do not use the contents of the lockfile as a cache key, as install should always guarantee that the files are updated, but it can still use part of the cache if not all packages are up-to-date.
5368
5435
  // It would slow down all pipelines whenever one adds a new dependency as it will need to download all node_modules again.
5369
5436
  return [
5370
5437
  {
5371
5438
  scope: "global",
5372
5439
  pathMode: "absolute",
5373
5440
  // we use the dirname, not the component name, because in certain cases we have two apps in the same directory and want to share the cache, e.g. when having storybook in the same package.json
5374
- key: (0, slugify_1.default)(baseDir) + "-node-modules",
5441
+ //
5442
+ // pnpm gets its own, lockfile-keyed cache: node_modules layouts
5443
+ // are not compatible between package managers (a migrating
5444
+ // project must not inherit the yarn slot), and unlike yarn, a
5445
+ // pnpm install on top of a node_modules from a different lockfile
5446
+ // leaves orphaned .pnpm dirs behind that break type identity —
5447
+ // so the slot changes whenever the lockfile changes
5448
+ key: isPnpm
5449
+ ? {
5450
+ prefix: "pnpm-" + (0, slugify_1.default)(baseDir) + "-node-modules",
5451
+ files: [(0, path_1.join)(baseDir, "pnpm-lock.yaml")],
5452
+ }
5453
+ : (0, slugify_1.default)(baseDir) + "-node-modules",
5375
5454
  // content-key for immutable-cache backends (github); the lockfile
5376
5455
  // decides whether the cached content could have changed (absolute
5377
5456
  // pathMode: resolve the lockfile explicitly)
5378
- keyFiles: [(0, path_1.join)(baseDir, "yarn.lock")],
5379
- // referenced by the yarn cache: an exact hit here makes the yarn
5380
- // zips unnecessary (see redundantOnExactHitOf on getYarnCache)
5457
+ keyFiles: [(0, path_1.join)(baseDir, lockFileName)],
5458
+ // referenced by the package-manager cache: an exact hit here makes
5459
+ // it unnecessary (see redundantOnExactHitOf on getYarnCache)
5381
5460
  cacheId: NODE_MODULES_CACHE_ID,
5382
5461
  policy,
5383
- paths: [
5462
+ paths: (0, lodash_es_1.uniq)([
5384
5463
  (0, path_1.join)(baseDir, "node_modules"),
5385
- ...(!isClassic ? [(0, path_1.join)(baseDir, ".yarn/install-state.gz")] : []),
5386
- ],
5464
+ // pnpm's per-package node_modules are symlink farms worth
5465
+ // keeping warm (yarn hoists into the root, so root-only
5466
+ // matches its historical behavior)
5467
+ ...(isPnpm
5468
+ ? workspaces.map((w) => (0, path_1.join)(w.location, "node_modules"))
5469
+ : []),
5470
+ ...(hasInstallState ? [(0, path_1.join)(baseDir, ".yarn/install-state.gz")] : []),
5471
+ ]),
5387
5472
  },
5388
5473
  ];
5389
5474
  };
@@ -5462,7 +5547,7 @@ const base_1 = __nccwpck_require__(61619);
5462
5547
  const docker_1 = __nccwpck_require__(83777);
5463
5548
  const types_1 = __nccwpck_require__(40632);
5464
5549
  const cache_1 = __nccwpck_require__(21100);
5465
- const yarn_1 = __nccwpck_require__(59874);
5550
+ const packageManagerInstall_1 = __nccwpck_require__(18600);
5466
5551
  const getMeteorCache = (context) => [
5467
5552
  {
5468
5553
  key: "meteor-build-cache",
@@ -5477,6 +5562,11 @@ const getMeteorCache = (context) => [
5477
5562
  ];
5478
5563
  const getMeteorDockerInstallScripts = async (context) => {
5479
5564
  const packageManagerInfo = await context.packageManagerInfo;
5565
+ if (packageManagerInfo.type === "pnpm") {
5566
+ // not a meteor limitation — catladder's meteor docker install path
5567
+ // is only implemented for yarn so far
5568
+ throw new Error("the meteor build type is only implemented for yarn in catladder");
5569
+ }
5480
5570
  if (packageManagerInfo.isClassic) {
5481
5571
  return new bash_1.BashExpression(`
5482
5572
  COPY $APP_DIR/package.json $APP_DIR/yarn.lock ./
@@ -5503,8 +5593,8 @@ const createMeteorBuildJobs = async (context) => {
5503
5593
  if (!(0, types_1.isOfBuildType)(buildConfig, "meteor")) {
5504
5594
  throw new Error("deploy config is not meteor");
5505
5595
  }
5506
- const [yarnInstall, nodeCache, meteorInstallScripts] = await Promise.all([
5507
- (0, yarn_1.getYarnInstall)(context),
5596
+ const [packageManagerInstall, nodeCache, meteorInstallScripts] = await Promise.all([
5597
+ (0, packageManagerInstall_1.getPackageManagerInstall)(context),
5508
5598
  (0, cache_1.getNodeCache)(context),
5509
5599
  buildConfig.installScripts
5510
5600
  ? getMeteorDockerInstallScripts(context)
@@ -5519,7 +5609,7 @@ const createMeteorBuildJobs = async (context) => {
5519
5609
  METEOR_DISABLE_OPTIMISTIC_CACHING: "1", // see https://forums.meteor.com/t/veeery-long-building-time-inside-docker-container/58673/17?u=macrozone
5520
5610
  },
5521
5611
  script: [
5522
- ...yarnInstall,
5612
+ ...packageManagerInstall,
5523
5613
  'TOOL_NODE_FLAGS="--max_old_space_size=3584 --min_semi_space_size=8 --max_semi_space_size=256 --optimize_for_size" meteor build ./dist --architecture os.linux.x86_64 --allow-superuser --server-only --directory',
5524
5614
  "cp ./__build_info.json ./dist/bundle/programs/server",
5525
5615
  ],
@@ -5538,6 +5628,158 @@ exports.createMeteorBuildJobs = createMeteorBuildJobs;
5538
5628
 
5539
5629
  /***/ }),
5540
5630
 
5631
+ /***/ 18600:
5632
+ /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
5633
+
5634
+ "use strict";
5635
+
5636
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
5637
+ exports.getDockerAppCopyAndBuildScript = exports.getPackageManagerInstall = exports.ensureNodeVersion = exports.getDefaultAuditCommand = void 0;
5638
+ const bash_1 = __nccwpck_require__(92390);
5639
+ const utils_1 = __nccwpck_require__(24516);
5640
+ const gitlab_1 = __nccwpck_require__(37393);
5641
+ const YARN_INSTALL_CLASSIC = `yarn install --frozen-lockfile`;
5642
+ const YARN_BERRY_PROD_INSTALL = `yarn workspaces focus --production`;
5643
+ // FIXME: check why and when rebuild is needed
5644
+ const YARN_BERRY_PROD_REBUILD = `yarn rebuild`;
5645
+ const getYarnInstallCommand = (packageManagerInfo) => {
5646
+ if (packageManagerInfo.isClassic) {
5647
+ return YARN_INSTALL_CLASSIC;
5648
+ }
5649
+ // inline builds make debugging easier as it prints it out in the logs, instead of writing it in temp files
5650
+ return `yarn install --immutable --inline-builds`;
5651
+ };
5652
+ const isInWorkspace = (context, packageManagerInfo) => context.type === "workspace" ||
5653
+ ("componentIsInWorkspace" in packageManagerInfo &&
5654
+ packageManagerInfo.componentIsInWorkspace);
5655
+ /**
5656
+ * make sure pnpm is available (job images ship it, older/custom images
5657
+ * fall back to corepack or a pinned global install)
5658
+ */
5659
+ const getEnsurePnpmCommand = (version) => `if ! command -v pnpm &> /dev/null; then corepack enable pnpm 2>/dev/null || npm install -g pnpm@${version}; fi`;
5660
+ /**
5661
+ * pnpm's store is global by default; point it at a project-local
5662
+ * directory so CI can cache it (the pnpm equivalent of the `.yarn`
5663
+ * zip cache). Passed as the --store-dir flag: pnpm 11 stopped reading
5664
+ * the npm_config_store_dir env var (settings only come from
5665
+ * pnpm-workspace.yaml / global config / CLI flags), the flag works on
5666
+ * v10 and v11
5667
+ */
5668
+ const getPnpmStoreDirExpression = (inWorkspace) => inWorkspace
5669
+ ? `"$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.pnpm-store"`
5670
+ : `"$PWD/.pnpm-store"`;
5671
+ const getPnpmInstallCommands = (context, packageManagerInfo) => [
5672
+ getEnsurePnpmCommand(packageManagerInfo.version),
5673
+ `pnpm install --frozen-lockfile --store-dir ${getPnpmStoreDirExpression(isInWorkspace(context, packageManagerInfo))}`,
5674
+ ];
5675
+ /**
5676
+ * default `audit` job command per package manager. Exhaustive on the
5677
+ * package-manager type and throws for anything unsupported, so adding a
5678
+ * new package manager surfaces every place that needs a command here.
5679
+ */
5680
+ const getDefaultAuditCommand = (packageManagerInfo) => {
5681
+ switch (packageManagerInfo.type) {
5682
+ case "pnpm":
5683
+ return "pnpm audit --prod --audit-level critical";
5684
+ case "yarn":
5685
+ return packageManagerInfo.isClassic
5686
+ ? "yarn audit --level critical"
5687
+ : "yarn npm audit --environment production --severity critical"; // yarn 2+
5688
+ default:
5689
+ throw new Error(`no audit command implemented for package manager "${packageManagerInfo.type}"`);
5690
+ }
5691
+ };
5692
+ exports.getDefaultAuditCommand = getDefaultAuditCommand;
5693
+ const ensureNodeVersion = (context) => (0, gitlab_1.collapseableSection)("nodeinstall", "Ensure node version")([
5694
+ // github actions overrides HOME in container jobs, so also look
5695
+ // for nvm where the catladder images install it (/root/.nvm)
5696
+ 'if [ -f "$HOME/.nvm/nvm.sh" ]; then source "$HOME/.nvm/nvm.sh"; elif [ -f /root/.nvm/nvm.sh ]; then export NVM_DIR=/root/.nvm; source /root/.nvm/nvm.sh; fi',
5697
+ "if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi",
5698
+ ]);
5699
+ exports.ensureNodeVersion = ensureNodeVersion;
5700
+ const getPackageManagerInstall = async (context, options) => {
5701
+ const packageManagerInfo = await context.packageManagerInfo;
5702
+ const postInstall = context.type !== "workspace" &&
5703
+ context.build.type !== "disabled" &&
5704
+ "postInstall" in context.build.config
5705
+ ? context.build.config.postInstall
5706
+ : null;
5707
+ const installSection = packageManagerInfo.type === "pnpm"
5708
+ ? (0, gitlab_1.collapseableSection)("pnpminstall", "pnpm install")(getPnpmInstallCommands(context, packageManagerInfo))
5709
+ : (0, gitlab_1.collapseableSection)("yarninstall", "Yarn install")([getYarnInstallCommand(packageManagerInfo)]);
5710
+ return [
5711
+ ...(0, exports.ensureNodeVersion)(context),
5712
+ ...installSection,
5713
+ ...(postInstall && !(options === null || options === void 0 ? void 0 : options.noCustomPostInstall)
5714
+ ? (0, gitlab_1.collapseableSection)("postinstall", "Custom post install")((0, utils_1.ensureArray)(postInstall))
5715
+ : []),
5716
+ ];
5717
+ };
5718
+ exports.getPackageManagerInstall = getPackageManagerInstall;
5719
+ const DOCKER_COPY_FILES = `COPY --chown=node:node $APP_DIR .`;
5720
+ const getPnpmDockerAppCopyAndBuildScript = (packageManagerInfo) => {
5721
+ // the store was copied into the image (like the yarn zip cache), so
5722
+ // the prod install links from it instead of hitting the registry
5723
+ const storeDir = packageManagerInfo.componentIsInWorkspace
5724
+ ? "/app/.pnpm-store"
5725
+ : "/app/$APP_DIR/.pnpm-store";
5726
+ // in a workspace, only install the component (and its workspace
5727
+ // dependencies) — the pnpm equivalent of `yarn workspaces focus`.
5728
+ // npm package names are shell-safe unquoted (the whole script is
5729
+ // embedded in a double-quoted bash export, so inner quotes would nest)
5730
+ const filter = packageManagerInfo.componentIsInWorkspace &&
5731
+ packageManagerInfo.currentWorkspace
5732
+ ? ` --filter ${packageManagerInfo.currentWorkspace.name}...`
5733
+ : "";
5734
+ return new bash_1.BashExpression(`
5735
+ ${DOCKER_COPY_FILES}
5736
+ RUN command -v pnpm >/dev/null 2>&1 || npm install -g pnpm@${packageManagerInfo.version}
5737
+ RUN pnpm install --prod --frozen-lockfile --store-dir ${storeDir}${filter}
5738
+ `.trim());
5739
+ };
5740
+ const getDockerAppCopyAndBuildScript = async (context) => {
5741
+ var _a, _b, _c;
5742
+ const packageManagerInfo = await context.packageManagerInfo;
5743
+ if (packageManagerInfo.type === "pnpm") {
5744
+ return getPnpmDockerAppCopyAndBuildScript(packageManagerInfo);
5745
+ }
5746
+ if (packageManagerInfo.isClassic) {
5747
+ return new bash_1.BashExpression(`
5748
+ RUN ${YARN_INSTALL_CLASSIC} --production --ignore-scripts
5749
+ ${DOCKER_COPY_FILES}
5750
+ RUN ${YARN_INSTALL_CLASSIC} --production
5751
+ `.trim());
5752
+ }
5753
+ const yarnRebuildEnabledDefault = context.build.type === "fromWorkspace"
5754
+ ? ((_b = (_a = context.build.workspaceBuildConfig.dockerDefaults) === null || _a === void 0 ? void 0 : _a.yarnRebuildEnabled) !== null && _b !== void 0 ? _b : true)
5755
+ : true;
5756
+ const yarnRebuildEnabled = "docker" in context.build.config &&
5757
+ context.build.config.docker &&
5758
+ "yarnRebuildEnabled" in context.build.config.docker
5759
+ ? ((_c = context.build.config.docker.yarnRebuildEnabled) !== null && _c !== void 0 ? _c : yarnRebuildEnabledDefault)
5760
+ : yarnRebuildEnabledDefault;
5761
+ // yarn >= 4 ships with build in plugins, see https://github.com/yarnpkg/berry/pull/4253
5762
+ // trying to import those fail on this version
5763
+ const doesNotShipWithBuiltInPlugins = ["2", "3"].some((v) => packageManagerInfo.version.startsWith(v));
5764
+ const maybeAddWorkspaceToolsCommand = doesNotShipWithBuiltInPlugins
5765
+ ? "RUN yarn plugin import workspace-tools"
5766
+ : "";
5767
+ // copy first everything and then install
5768
+ // rebuild first does not work as it will run postinstall and that might require files in the app
5769
+ return new bash_1.BashExpression(`
5770
+ ENV YARN_ENABLE_INLINE_BUILDS=1
5771
+ ${DOCKER_COPY_FILES}
5772
+ ${maybeAddWorkspaceToolsCommand}
5773
+ RUN ${YARN_BERRY_PROD_INSTALL}
5774
+ ${yarnRebuildEnabled ? `RUN ${YARN_BERRY_PROD_REBUILD}` : ""}
5775
+
5776
+ `.trim());
5777
+ };
5778
+ exports.getDockerAppCopyAndBuildScript = getDockerAppCopyAndBuildScript;
5779
+ //# sourceMappingURL=packageManagerInstall.js.map
5780
+
5781
+ /***/ }),
5782
+
5541
5783
  /***/ 79769:
5542
5784
  /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
5543
5785
 
@@ -5552,7 +5794,7 @@ const utils_1 = __nccwpck_require__(24516);
5552
5794
  const createArtifactsConfig_1 = __nccwpck_require__(24494);
5553
5795
  const cache_1 = __nccwpck_require__(21100);
5554
5796
  const constants_1 = __nccwpck_require__(97627);
5555
- const yarn_1 = __nccwpck_require__(59874);
5797
+ const packageManagerInstall_1 = __nccwpck_require__(18600);
5556
5798
  const createNodeTestJobs = async (context) => {
5557
5799
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3;
5558
5800
  // don't run tests after release
@@ -5579,8 +5821,8 @@ const createNodeTestJobs = async (context) => {
5579
5821
  needs: [],
5580
5822
  };
5581
5823
  const buildConfig = context.build.config;
5582
- const [yarnInstall, packageManagerInfo, nodeCache] = await Promise.all([
5583
- (0, yarn_1.getYarnInstall)(context),
5824
+ const [packageManagerInstall, packageManagerInfo, nodeCache] = await Promise.all([
5825
+ (0, packageManagerInstall_1.getPackageManagerInstall)(context),
5584
5826
  context.packageManagerInfo,
5585
5827
  // pull-only: the build job is the designated cache writer — lint and
5586
5828
  // test produce equivalent content from the same lockfile, so their
@@ -5596,13 +5838,11 @@ const createNodeTestJobs = async (context) => {
5596
5838
  ...((_b = (_a = buildConfig.audit) === null || _a === void 0 ? void 0 : _a.runnerVariables) !== null && _b !== void 0 ? _b : {}),
5597
5839
  },
5598
5840
  image: (_d = (_c = buildConfig.audit) === null || _c === void 0 ? void 0 : _c.jobImage) !== null && _d !== void 0 ? _d : defaultImage,
5599
- caches: undefined, // audit does not need yarn install and no cache
5841
+ caches: undefined, // audit does not need an install and no cache
5600
5842
  script: [
5601
5843
  `cd ${context.build.dir}`,
5602
5844
  ...((_f = (0, utils_1.ensureArrayOrNull)((_e = buildConfig.audit) === null || _e === void 0 ? void 0 : _e.command)) !== null && _f !== void 0 ? _f : [
5603
- packageManagerInfo.isClassic
5604
- ? "yarn audit --level critical"
5605
- : "yarn npm audit --environment production --severity critical", // yarn 2
5845
+ (0, packageManagerInstall_1.getDefaultAuditCommand)(packageManagerInfo),
5606
5846
  ]),
5607
5847
  ],
5608
5848
  allow_failure: (_h = (_g = buildConfig.audit) === null || _g === void 0 ? void 0 : _g.allowFailure) !== null && _h !== void 0 ? _h : true,
@@ -5620,9 +5860,9 @@ const createNodeTestJobs = async (context) => {
5620
5860
  image: (_p = (_o = buildConfig.lint) === null || _o === void 0 ? void 0 : _o.jobImage) !== null && _p !== void 0 ? _p : defaultImage,
5621
5861
  caches: nodeCache,
5622
5862
  script: [
5623
- ...(0, yarn_1.ensureNodeVersion)(context),
5863
+ ...(0, packageManagerInstall_1.ensureNodeVersion)(context),
5624
5864
  `cd ${context.build.dir}`,
5625
- ...yarnInstall,
5865
+ ...packageManagerInstall,
5626
5866
  ...((_r = (0, utils_1.ensureArrayOrNull)((_q = buildConfig.lint) === null || _q === void 0 ? void 0 : _q.command)) !== null && _r !== void 0 ? _r : ["yarn lint"]),
5627
5867
  ],
5628
5868
  allow_failure: (_s = buildConfig.lint) === null || _s === void 0 ? void 0 : _s.allowFailure,
@@ -5640,9 +5880,9 @@ const createNodeTestJobs = async (context) => {
5640
5880
  image: (_y = (_x = buildConfig.test) === null || _x === void 0 ? void 0 : _x.jobImage) !== null && _y !== void 0 ? _y : (0, runner_1.getRunnerImage)("jobs-testing-chrome"),
5641
5881
  caches: nodeCache,
5642
5882
  script: [
5643
- ...(0, yarn_1.ensureNodeVersion)(context),
5883
+ ...(0, packageManagerInstall_1.ensureNodeVersion)(context),
5644
5884
  `cd ${context.build.dir}`,
5645
- ...yarnInstall,
5885
+ ...packageManagerInstall,
5646
5886
  ...((_0 = (0, utils_1.ensureArrayOrNull)((_z = buildConfig.test) === null || _z === void 0 ? void 0 : _z.command)) !== null && _0 !== void 0 ? _0 : ["yarn test"]),
5647
5887
  ],
5648
5888
  allow_failure: (_1 = buildConfig.test) === null || _1 === void 0 ? void 0 : _1.allowFailure,
@@ -5656,91 +5896,6 @@ exports.createNodeTestJobs = createNodeTestJobs;
5656
5896
 
5657
5897
  /***/ }),
5658
5898
 
5659
- /***/ 59874:
5660
- /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
5661
-
5662
- "use strict";
5663
-
5664
- Object.defineProperty(exports, "__esModule", ({ value: true }));
5665
- exports.getDockerAppCopyAndBuildScript = exports.getYarnInstall = exports.ensureNodeVersion = void 0;
5666
- const bash_1 = __nccwpck_require__(92390);
5667
- const utils_1 = __nccwpck_require__(24516);
5668
- const gitlab_1 = __nccwpck_require__(37393);
5669
- const YARN_INSTALL_CLASSIC = `yarn install --frozen-lockfile`;
5670
- const YARN_BERRY_PROD_INSTALL = `yarn workspaces focus --production`;
5671
- // FIXME: check why and when rebuild is needed
5672
- const YARN_BERRY_PROD_REBUILD = `yarn rebuild`;
5673
- const getYarnInstallCommand = async (context) => {
5674
- const packageManagerInfo = await context.packageManagerInfo;
5675
- if (packageManagerInfo.isClassic) {
5676
- return YARN_INSTALL_CLASSIC;
5677
- }
5678
- // inline builds make debugging easier as it prints it out in the logs, instead of writing it in temp files
5679
- return `yarn install --immutable --inline-builds`;
5680
- };
5681
- const ensureNodeVersion = (context) => (0, gitlab_1.collapseableSection)("nodeinstall", "Ensure node version")([
5682
- // github actions overrides HOME in container jobs, so also look
5683
- // for nvm where the catladder images install it (/root/.nvm)
5684
- 'if [ -f "$HOME/.nvm/nvm.sh" ]; then source "$HOME/.nvm/nvm.sh"; elif [ -f /root/.nvm/nvm.sh ]; then export NVM_DIR=/root/.nvm; source /root/.nvm/nvm.sh; fi',
5685
- "if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi",
5686
- ]);
5687
- exports.ensureNodeVersion = ensureNodeVersion;
5688
- const getYarnInstall = async (context, options) => {
5689
- const postInstall = context.type !== "workspace" &&
5690
- context.build.type !== "disabled" &&
5691
- "postInstall" in context.build.config
5692
- ? context.build.config.postInstall
5693
- : null;
5694
- return [
5695
- ...(0, exports.ensureNodeVersion)(context),
5696
- ...(0, gitlab_1.collapseableSection)("yarninstall", "Yarn install")([await getYarnInstallCommand(context)]),
5697
- ...(postInstall && !(options === null || options === void 0 ? void 0 : options.noCustomPostInstall)
5698
- ? (0, gitlab_1.collapseableSection)("postinstall", "Custom post install")((0, utils_1.ensureArray)(postInstall))
5699
- : []),
5700
- ];
5701
- };
5702
- exports.getYarnInstall = getYarnInstall;
5703
- const DOCKER_COPY_FILES = `COPY --chown=node:node $APP_DIR .`;
5704
- const getDockerAppCopyAndBuildScript = async (context) => {
5705
- var _a, _b, _c;
5706
- const packageManagerInfo = await context.packageManagerInfo;
5707
- if (packageManagerInfo.isClassic) {
5708
- return new bash_1.BashExpression(`
5709
- RUN ${YARN_INSTALL_CLASSIC} --production --ignore-scripts
5710
- ${DOCKER_COPY_FILES}
5711
- RUN ${YARN_INSTALL_CLASSIC} --production
5712
- `.trim());
5713
- }
5714
- const yarnRebuildEnabledDefault = context.build.type === "fromWorkspace"
5715
- ? ((_b = (_a = context.build.workspaceBuildConfig.dockerDefaults) === null || _a === void 0 ? void 0 : _a.yarnRebuildEnabled) !== null && _b !== void 0 ? _b : true)
5716
- : true;
5717
- const yarnRebuildEnabled = "docker" in context.build.config &&
5718
- context.build.config.docker &&
5719
- "yarnRebuildEnabled" in context.build.config.docker
5720
- ? ((_c = context.build.config.docker.yarnRebuildEnabled) !== null && _c !== void 0 ? _c : yarnRebuildEnabledDefault)
5721
- : yarnRebuildEnabledDefault;
5722
- // yarn >= 4 ships with build in plugins, see https://github.com/yarnpkg/berry/pull/4253
5723
- // trying to import those fail on this version
5724
- const doesNotShipWithBuiltInPlugins = ["2", "3"].some((v) => packageManagerInfo.version.startsWith(v));
5725
- const maybeAddWorkspaceToolsCommand = doesNotShipWithBuiltInPlugins
5726
- ? "RUN yarn plugin import workspace-tools"
5727
- : "";
5728
- // copy first everything and then install
5729
- // rebuild first does not work as it will run postinstall and that might require files in the app
5730
- return new bash_1.BashExpression(`
5731
- ENV YARN_ENABLE_INLINE_BUILDS=1
5732
- ${DOCKER_COPY_FILES}
5733
- ${maybeAddWorkspaceToolsCommand}
5734
- RUN ${YARN_BERRY_PROD_INSTALL}
5735
- ${yarnRebuildEnabled ? `RUN ${YARN_BERRY_PROD_REBUILD}` : ""}
5736
-
5737
- `.trim());
5738
- };
5739
- exports.getDockerAppCopyAndBuildScript = getDockerAppCopyAndBuildScript;
5740
- //# sourceMappingURL=yarn.js.map
5741
-
5742
- /***/ }),
5743
-
5744
5899
  /***/ 50663:
5745
5900
  /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
5746
5901
 
@@ -6206,6 +6361,7 @@ const createComponentContext = async (ctx) => {
6206
6361
  throw new Error("componentName may only contain lower case letters, numbers and -");
6207
6362
  }
6208
6363
  const packageManagerInfoPromise = (0, packageManager_1.getPackageManagerInfoForComponent)(ctx.config, ctx.componentName);
6364
+ const { type: packageManagerType } = await packageManagerInfoPromise;
6209
6365
  const envContext = (0, getEnvironmentContext_1.getEnvironmentContext)(ctx);
6210
6366
  const componentConfigWithoutDefaults = envContext.envConfigRaw;
6211
6367
  const resolvedBuildType = componentConfigWithoutDefaults.build === false
@@ -6219,12 +6375,12 @@ const createComponentContext = async (ctx) => {
6219
6375
  const defaults = componentConfigWithoutDefaults.deploy
6220
6376
  ? {
6221
6377
  build: resolvedBuildType &&
6222
- build_1.BUILD_TYPES[resolvedBuildType].defaults(envContext),
6378
+ build_1.BUILD_TYPES[resolvedBuildType].defaults(envContext, packageManagerType),
6223
6379
  deploy: deploy_1.DEPLOY_TYPES[componentConfigWithoutDefaults.deploy.type].defaults(envContext),
6224
6380
  }
6225
6381
  : {
6226
6382
  build: resolvedBuildType &&
6227
- build_1.BUILD_TYPES[resolvedBuildType].defaults(envContext),
6383
+ build_1.BUILD_TYPES[resolvedBuildType].defaults(envContext, packageManagerType),
6228
6384
  deploy: {},
6229
6385
  };
6230
6386
  const componentConfig = (0, utils_1.mergeWithMergingArrays)(defaults, componentConfigWithoutDefaults);
@@ -6321,7 +6477,8 @@ async function createWorkspaceContext({ env, components, workspaceName, config,
6321
6477
  if (!workspaceConfigRaw) {
6322
6478
  throw new Error(`Workspace ${workspaceName} not found in config`);
6323
6479
  }
6324
- const defaults = __1.WORKSPACE_BUILD_TYPES[workspaceConfigRaw.type].defaults();
6480
+ const packageManagerInfo = (0, packageManager_1.getPackageManagerInfoBase)(config);
6481
+ const defaults = __1.WORKSPACE_BUILD_TYPES[workspaceConfigRaw.type].defaults((await packageManagerInfo).type);
6325
6482
  const workspaceConfig = (0, utils_1.mergeWithMergingArrays)(defaults, workspaceConfigRaw);
6326
6483
  return {
6327
6484
  name: workspaceName,
@@ -6332,7 +6489,7 @@ async function createWorkspaceContext({ env, components, workspaceName, config,
6332
6489
  env,
6333
6490
  components,
6334
6491
  fullConfig: config,
6335
- packageManagerInfo: (0, packageManager_1.getPackageManagerInfoBase)(),
6492
+ packageManagerInfo,
6336
6493
  build: {
6337
6494
  type: "workspace",
6338
6495
  dir: (_b = workspaceConfig.dir) !== null && _b !== void 0 ? _b : ".",
@@ -6824,7 +6981,7 @@ exports.makeSecretEnvVarMapping = makeSecretEnvVarMapping;
6824
6981
  "use strict";
6825
6982
 
6826
6983
  Object.defineProperty(exports, "__esModule", ({ value: true }));
6827
- exports.computeCustomImageHash = void 0;
6984
+ exports.computeInlineImageHash = exports.computeCustomImageHash = void 0;
6828
6985
  const crypto_1 = __nccwpck_require__(76982);
6829
6986
  const fs_1 = __nccwpck_require__(79896);
6830
6987
  const path_1 = __nccwpck_require__(16928);
@@ -6845,6 +7002,29 @@ function listFilesRecursive(dir) {
6845
7002
  })
6846
7003
  .sort();
6847
7004
  }
7005
+ /**
7006
+ * the parts every image definition hashes on top of its content:
7007
+ * files outside the definition, and the build args
7008
+ */
7009
+ function hashExtras(hash, config) {
7010
+ const watchedPaths = [];
7011
+ // Hash extra paths (for files outside the dir)
7012
+ if (config.hashExtraPaths) {
7013
+ // Extra paths are literal file paths (not globs) for simplicity
7014
+ const extraFiles = [...config.hashExtraPaths].sort();
7015
+ for (const file of extraFiles) {
7016
+ hash.update(file);
7017
+ hash.update((0, fs_1.readFileSync)(file));
7018
+ }
7019
+ watchedPaths.push(...config.hashExtraPaths);
7020
+ }
7021
+ // Hash build args (sorted keys for determinism)
7022
+ if (config.buildArgs) {
7023
+ const sorted = Object.entries(config.buildArgs).sort(([a], [b]) => a.localeCompare(b));
7024
+ hash.update(JSON.stringify(sorted));
7025
+ }
7026
+ return watchedPaths;
7027
+ }
6848
7028
  function computeCustomImageHash(config) {
6849
7029
  var _a;
6850
7030
  const hash = (0, crypto_1.createHash)("sha256");
@@ -6865,27 +7045,29 @@ function computeCustomImageHash(config) {
6865
7045
  }
6866
7046
  watchedPaths.push(`${extraDir}/**/*`);
6867
7047
  }
6868
- // Hash extra paths (for files outside the dir)
6869
- if (config.hashExtraPaths) {
6870
- // Extra paths are literal file paths (not globs) for simplicity
6871
- const extraFiles = [...config.hashExtraPaths].sort();
6872
- for (const file of extraFiles) {
6873
- hash.update(file);
6874
- hash.update((0, fs_1.readFileSync)(file));
6875
- }
6876
- watchedPaths.push(...config.hashExtraPaths);
6877
- }
6878
- // Hash build args (sorted keys for determinism)
6879
- if (config.buildArgs) {
6880
- const sorted = Object.entries(config.buildArgs).sort(([a], [b]) => a.localeCompare(b));
6881
- hash.update(JSON.stringify(sorted));
6882
- }
7048
+ watchedPaths.push(...hashExtras(hash, config));
6883
7049
  return {
6884
7050
  hash: hash.digest("hex").slice(0, 12),
6885
7051
  watchedPaths,
6886
7052
  };
6887
7053
  }
6888
7054
  exports.computeCustomImageHash = computeCustomImageHash;
7055
+ /**
7056
+ * the hash of an image defined by an inline Dockerfile: its content
7057
+ * stands in for the definition dir. The build context is deliberately
7058
+ * NOT hashed (it may be the whole repository) — `hashExtraPaths` is how
7059
+ * context files opt into the hash.
7060
+ */
7061
+ function computeInlineImageHash(config) {
7062
+ const hash = (0, crypto_1.createHash)("sha256");
7063
+ hash.update(config.dockerfileContent);
7064
+ const watchedPaths = hashExtras(hash, config);
7065
+ return {
7066
+ hash: hash.digest("hex").slice(0, 12),
7067
+ watchedPaths,
7068
+ };
7069
+ }
7070
+ exports.computeInlineImageHash = computeInlineImageHash;
6889
7071
  //# sourceMappingURL=hash.js.map
6890
7072
 
6891
7073
  /***/ }),
@@ -6896,7 +7078,7 @@ exports.computeCustomImageHash = computeCustomImageHash;
6896
7078
  "use strict";
6897
7079
 
6898
7080
  Object.defineProperty(exports, "__esModule", ({ value: true }));
6899
- exports.JobImagesPlan = exports.GENERATED_IMAGES_FOLDER = void 0;
7081
+ exports.JobImagesPlan = exports.PROJECT_IMAGES_FOLDER = exports.GENERATED_IMAGES_FOLDER = void 0;
6900
7082
  const fs_1 = __nccwpck_require__(79896);
6901
7083
  const path_1 = __nccwpck_require__(16928);
6902
7084
  const ciVariables_1 = __nccwpck_require__(72700);
@@ -6904,6 +7086,7 @@ const docker_1 = __nccwpck_require__(83777);
6904
7086
  const runner_1 = __nccwpck_require__(71065);
6905
7087
  const gitlab_1 = __nccwpck_require__(37393);
6906
7088
  const hash_1 = __nccwpck_require__(34092);
7089
+ const projectImages_1 = __nccwpck_require__(55537);
6907
7090
  const shippedImages_1 = __nccwpck_require__(28687);
6908
7091
  exports.GENERATED_IMAGES_FOLDER = ".catladder-generated/images";
6909
7092
  /**
@@ -6911,7 +7094,44 @@ exports.GENERATED_IMAGES_FOLDER = ".catladder-generated/images";
6911
7094
  * catladder image, so building images never depends on one (bootstrap)
6912
7095
  */
6913
7096
  const BUILDER_IMAGE = "docker.io/docker:29.5.1";
6914
- const ensureJobName = (name) => `🐳 job image ${name}`;
7097
+ /**
7098
+ * every planned image is consumed the same way: its url, plus an
7099
+ * optional dependency on its build job
7100
+ */
7101
+ const toResolvedJobImage = ({ imageRef, jobName, }) => ({
7102
+ image: imageRef,
7103
+ fromRepoRegistry: true,
7104
+ need: {
7105
+ job: jobName,
7106
+ artifacts: false,
7107
+ optional: true,
7108
+ global: true,
7109
+ },
7110
+ });
7111
+ /**
7112
+ * materializes an image definition directory into the generated files
7113
+ * (used for the definitions catladder ships)
7114
+ */
7115
+ const materializeDir = (sourceDir, targetDir) => listFilesRecursive(sourceDir).map((file) => ({
7116
+ path: (0, path_1.join)(targetDir, file),
7117
+ content: (0, fs_1.readFileSync)((0, path_1.join)(sourceDir, file), "utf-8"),
7118
+ }));
7119
+ // built-in (catladder-shipped) images carry the catladder marker in
7120
+ // their job name; project-declared images get the short plain name
7121
+ const ensureJobName = (name) => `🐳 catladder image ${name}`;
7122
+ const projectEnsureJobName = (name) => `🐳 image ${name}`;
7123
+ /**
7124
+ * the config file whose content feeds the project image hashes
7125
+ * (`buildArgs`, `hashExtraPaths`): the gitlab change detection has to
7126
+ * watch it, because a config-only change alters the image tag without
7127
+ * touching the image dir
7128
+ */
7129
+ const CONFIG_FILE = "catladder.ts";
7130
+ /**
7131
+ * where inline project Dockerfiles are materialized — a subfolder, so a
7132
+ * project image can carry the same name as a shipped one
7133
+ */
7134
+ exports.PROJECT_IMAGES_FOLDER = `${exports.GENERATED_IMAGES_FOLDER}/project`;
6915
7135
  /**
6916
7136
  * plans the catladder job images of one backend run: resolves image
6917
7137
  * references, collects the image build jobs, and the image definitions
@@ -6922,33 +7142,30 @@ const ensureJobName = (name) => `🐳 job image ${name}`;
6922
7142
  * Reference-driven: only images actually used by a job are built.
6923
7143
  */
6924
7144
  class JobImagesPlan {
6925
- constructor(pipelineType) {
7145
+ constructor(pipelineType, projectImages = {}) {
6926
7146
  this.pipelineType = pipelineType;
7147
+ this.projectImages = projectImages;
6927
7148
  this.used = new Map();
7149
+ this.usedProject = new Map();
6928
7150
  }
6929
7151
  /**
6930
7152
  * resolves a job image (marker or concrete) to a concrete image url
6931
7153
  * plus the build job dependency
6932
7154
  */
6933
7155
  resolve(image) {
6934
- if (!(0, runner_1.isCatladderImageRef)(image)) {
6935
- return { image };
7156
+ if ((0, runner_1.isCatladderImageRef)(image)) {
7157
+ return this.resolveRef(image);
7158
+ }
7159
+ if ((0, projectImages_1.isProjectImageRef)(image)) {
7160
+ return this.resolveProjectRef(image);
6936
7161
  }
6937
- return this.resolveRef(image);
7162
+ return { image };
6938
7163
  }
6939
7164
  resolveRef(ref) {
6940
- const name = ref.catladderImage;
6941
- const { hash } = this.use(name);
6942
- return {
6943
- image: `${this.registryImageRef()}/catladder/${name}:${hash}`,
6944
- fromRepoRegistry: true,
6945
- need: {
6946
- job: ensureJobName(name),
6947
- artifacts: false,
6948
- optional: true,
6949
- global: true,
6950
- },
6951
- };
7165
+ return toResolvedJobImage(this.use(ref.catladderImage));
7166
+ }
7167
+ resolveProjectRef(ref) {
7168
+ return toResolvedJobImage(this.useProject(ref.image));
6952
7169
  }
6953
7170
  /**
6954
7171
  * the registry image prefix. On github, container images can't use
@@ -6959,6 +7176,85 @@ class JobImagesPlan {
6959
7176
  ? "ghcr.io/${{ github.repository }}"
6960
7177
  : `${(0, ciVariables_1.getCiVariable)({ pipelineType: this.pipelineType }, "registryImage")}`;
6961
7178
  }
7179
+ useProject(name) {
7180
+ const existing = this.usedProject.get(name);
7181
+ if (existing) {
7182
+ return existing;
7183
+ }
7184
+ const imageConfig = this.projectImages[name];
7185
+ if (!imageConfig) {
7186
+ const declared = Object.keys(this.projectImages);
7187
+ throw new Error(`unknown job image "${name}" — ${declared.length > 0
7188
+ ? `images declared in config.images: ${declared.join(", ")}`
7189
+ : "no images are declared in config.images"}`);
7190
+ }
7191
+ const source = this.planProjectSource(name, imageConfig);
7192
+ const planned = {
7193
+ ...source,
7194
+ jobName: projectEnsureJobName(name),
7195
+ buildArgs: imageConfig.buildArgs,
7196
+ // `job-images/` keeps the project's job images apart from its
7197
+ // deployable component images (registry root) and build caches
7198
+ imageRef: `${this.registryImageRef()}/job-images/${name}:${source.hash}`,
7199
+ };
7200
+ this.usedProject.set(name, planned);
7201
+ return planned;
7202
+ }
7203
+ /**
7204
+ * the source-dependent half of a project image: an inline Dockerfile
7205
+ * is materialized into the generated files and hashed by its content,
7206
+ * a directory is hashed and watched in place
7207
+ */
7208
+ planProjectSource(name, imageConfig) {
7209
+ var _a, _b;
7210
+ if (imageConfig.dockerfile !== undefined) {
7211
+ const content = toDockerfileContent(imageConfig.dockerfile);
7212
+ const dockerfilePath = `${exports.PROJECT_IMAGES_FOLDER}/${name}/Dockerfile`;
7213
+ const { hash, watchedPaths } = (0, hash_1.computeInlineImageHash)({
7214
+ dockerfileContent: content,
7215
+ hashExtraPaths: imageConfig.hashExtraPaths,
7216
+ buildArgs: imageConfig.buildArgs,
7217
+ });
7218
+ return {
7219
+ hash,
7220
+ dockerfilePath,
7221
+ // an inline definition carries no directory of its own — the
7222
+ // repository root is the sensible default context
7223
+ contextDir: (_a = imageConfig.context) !== null && _a !== void 0 ? _a : ".",
7224
+ watchedPaths: [
7225
+ `${exports.PROJECT_IMAGES_FOLDER}/${name}/**/*`,
7226
+ ...watchedPaths,
7227
+ CONFIG_FILE,
7228
+ ],
7229
+ files: [{ path: dockerfilePath, content }],
7230
+ };
7231
+ }
7232
+ const dir = imageConfig.dir;
7233
+ // fail at generation time with the offending image named: an
7234
+ // unreadable dir would otherwise surface as a bare fs ENOENT, and a
7235
+ // missing Dockerfile only as a docker build failure in CI
7236
+ if (!(0, fs_1.existsSync)(dir)) {
7237
+ throw new Error(`job image "${name}": the directory "${dir}" does not exist (config.images.${name}.dir, relative to the repository root)`);
7238
+ }
7239
+ if (!(0, fs_1.existsSync)((0, path_1.join)(dir, "Dockerfile"))) {
7240
+ throw new Error(`job image "${name}": no Dockerfile in "${dir}" (config.images.${name}.dir)`);
7241
+ }
7242
+ const { hash, watchedPaths } = (0, hash_1.computeCustomImageHash)({
7243
+ dir,
7244
+ hashExtraPaths: imageConfig.hashExtraPaths,
7245
+ buildArgs: imageConfig.buildArgs,
7246
+ });
7247
+ return {
7248
+ hash,
7249
+ dockerfilePath: `${dir}/Dockerfile`,
7250
+ contextDir: (_b = imageConfig.context) !== null && _b !== void 0 ? _b : dir,
7251
+ // the dir is committed in the project — watched in place, nothing
7252
+ // is materialized. The config file is watched too: buildArgs /
7253
+ // hashExtraPaths changes alter the tag without touching the dir
7254
+ watchedPaths: [...watchedPaths, CONFIG_FILE],
7255
+ files: [],
7256
+ };
7257
+ }
6962
7258
  use(name) {
6963
7259
  var _a;
6964
7260
  const existing = this.used.get(name);
@@ -6973,27 +7269,43 @@ class JobImagesPlan {
6973
7269
  dir: (0, shippedImages_1.getShippedImageDir)(name),
6974
7270
  extraDirs: dependencies.map((dependency) => (0, shippedImages_1.getShippedImageDir)(dependency)),
6975
7271
  });
6976
- const entry = { hash };
6977
- this.used.set(name, entry);
6978
- return entry;
7272
+ const targetDir = `${exports.GENERATED_IMAGES_FOLDER}/${name}`;
7273
+ const planned = {
7274
+ hash,
7275
+ jobName: ensureJobName(name),
7276
+ imageRef: `${this.registryImageRef()}/catladder/${name}:${hash}`,
7277
+ dockerfilePath: `${targetDir}/Dockerfile`,
7278
+ // the jobs family INCLUDEs sibling images, so it builds from the
7279
+ // images root; the others from their own dir
7280
+ contextDir: shippedImages_1.RUNNER_IMAGE_BUILD_CONTEXT[name] === "root"
7281
+ ? exports.GENERATED_IMAGES_FOLDER
7282
+ : targetDir,
7283
+ watchedPaths: [name, ...dependencies].map((dir) => `${exports.GENERATED_IMAGES_FOLDER}/${dir}/**/*`),
7284
+ // pipelines build from committed, reviewable files (and gitlab's
7285
+ // rules:changes can watch them)
7286
+ files: materializeDir((0, shippedImages_1.getShippedImageDir)(name), targetDir),
7287
+ };
7288
+ this.used.set(name, planned);
7289
+ return planned;
6979
7290
  }
6980
7291
  /**
6981
7292
  * the image build jobs for all used images
6982
7293
  */
6983
7294
  getEnsureJobs() {
6984
- return [...this.used.entries()].map(([name, { hash }]) => this.createEnsureJob(name, hash));
7295
+ return [...this.used.values(), ...this.usedProject.values()].map((planned) => this.createImageBuildJob(planned));
6985
7296
  }
6986
- createEnsureJob(name, hash) {
6987
- var _a;
7297
+ createImageBuildJob({ jobName, imageRef, watchedPaths, dockerfilePath, contextDir, buildArgs, }) {
7298
+ const buildArgFlags = Object.entries(buildArgs !== null && buildArgs !== void 0 ? buildArgs : {})
7299
+ .map(([key, value]) => ` --build-arg '${key}=${value}'`)
7300
+ .join("");
7301
+ const buildCommand = `DOCKER_BUILDKIT=1 docker build -t ${imageRef}${buildArgFlags} -f ${dockerfilePath} ${contextDir}`;
6988
7302
  const ctx = { pipelineType: this.pipelineType };
6989
7303
  const registryUser = (0, ciVariables_1.getCiVariable)(ctx, "registryUser");
6990
7304
  const jobToken = (0, ciVariables_1.getCiVariable)(ctx, "jobToken");
6991
7305
  const registry = (0, ciVariables_1.getCiVariable)(ctx, "registry");
6992
- const imageRef = `${this.registryImageRef()}/catladder/${name}:${hash}`;
6993
- const watchedDirs = [name, ...((_a = shippedImages_1.RUNNER_IMAGE_DEPENDENCIES[name]) !== null && _a !== void 0 ? _a : [])];
6994
7306
  const { services, runnerVariables } = (0, docker_1.getDockerJobBaseProps)();
6995
7307
  return {
6996
- name: ensureJobName(name),
7308
+ name: jobName,
6997
7309
  stage: "setup",
6998
7310
  image: BUILDER_IMAGE,
6999
7311
  services,
@@ -7003,7 +7315,9 @@ class JobImagesPlan {
7003
7315
  // no equivalent and always runs (the existence check is fast)
7004
7316
  rules: [
7005
7317
  {
7006
- changes: watchedDirs.map((dir) => `${exports.GENERATED_IMAGES_FOLDER}/${dir}/**/*`),
7318
+ // a fresh array per job: the yaml serializer anchors repeated
7319
+ // objects, and a shared reference would reshuffle anchors
7320
+ changes: [...watchedPaths],
7007
7321
  },
7008
7322
  ],
7009
7323
  variables: {},
@@ -7017,31 +7331,33 @@ class JobImagesPlan {
7017
7331
  ` exit 0`,
7018
7332
  `fi`,
7019
7333
  ]),
7020
- ...(0, gitlab_1.collapseableSection)("docker-build", "Building image")([
7021
- `DOCKER_BUILDKIT=1 docker build -t ${imageRef} -f ${exports.GENERATED_IMAGES_FOLDER}/${name}/Dockerfile ${shippedImages_1.RUNNER_IMAGE_BUILD_CONTEXT[name] === "root"
7022
- ? exports.GENERATED_IMAGES_FOLDER
7023
- : `${exports.GENERATED_IMAGES_FOLDER}/${name}`}`,
7024
- ]),
7334
+ ...(0, gitlab_1.collapseableSection)("docker-build", "Building image")([buildCommand]),
7025
7335
  ...(0, gitlab_1.collapseableSection)("docker-push", "Pushing image")([`docker push ${imageRef}`]),
7026
7336
  ],
7027
7337
  };
7028
7338
  }
7029
7339
  /**
7030
- * the image definitions of all used images, materialized into the
7031
- * generated files (so pipelines build from committed, reviewable
7032
- * files and gitlab's rules:changes can watch them)
7340
+ * the image definitions to materialize into the generated files (so
7341
+ * pipelines build from committed, reviewable files and gitlab's
7342
+ * rules:changes can watch them): the definitions catladder ships and
7343
+ * the project's inline Dockerfiles. A project image directory is
7344
+ * already committed and contributes nothing.
7033
7345
  */
7034
7346
  getGeneratedFiles() {
7035
- return [...this.used.keys()].flatMap((name) => {
7036
- const dir = (0, shippedImages_1.getShippedImageDir)(name);
7037
- return listFilesRecursive(dir).map((file) => ({
7038
- path: (0, path_1.join)(exports.GENERATED_IMAGES_FOLDER, name, file),
7039
- content: (0, fs_1.readFileSync)((0, path_1.join)(dir, file), "utf-8"),
7040
- }));
7041
- });
7347
+ return [...this.used.values(), ...this.usedProject.values()].flatMap(({ files }) => files);
7042
7348
  }
7043
7349
  }
7044
7350
  exports.JobImagesPlan = JobImagesPlan;
7351
+ /**
7352
+ * an inline Dockerfile is written as given — as one string, or as lines
7353
+ * joined with newlines (always newline-terminated)
7354
+ */
7355
+ const toDockerfileContent = (dockerfile) => {
7356
+ const content = Array.isArray(dockerfile)
7357
+ ? dockerfile.join("\n")
7358
+ : dockerfile;
7359
+ return content.endsWith("\n") ? content : `${content}\n`;
7360
+ };
7045
7361
  const IGNORED_FILES = new Set([".DS_Store", "Thumbs.db"]);
7046
7362
  const listFilesRecursive = (dir) => (0, fs_1.readdirSync)(dir, { recursive: true, encoding: "utf-8" })
7047
7363
  .filter((entry) => {
@@ -7055,6 +7371,22 @@ const listFilesRecursive = (dir) => (0, fs_1.readdirSync)(dir, { recursive: true
7055
7371
 
7056
7372
  /***/ }),
7057
7373
 
7374
+ /***/ 55537:
7375
+ /***/ ((__unused_webpack_module, exports) => {
7376
+
7377
+ "use strict";
7378
+
7379
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
7380
+ exports.isProjectImageRef = void 0;
7381
+ const isProjectImageRef = (value) => typeof value === "object" &&
7382
+ value !== null &&
7383
+ "image" in value &&
7384
+ typeof value.image === "string";
7385
+ exports.isProjectImageRef = isProjectImageRef;
7386
+ //# sourceMappingURL=projectImages.js.map
7387
+
7388
+ /***/ }),
7389
+
7058
7390
  /***/ 28687:
7059
7391
  /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
7060
7392
 
@@ -8806,19 +9138,18 @@ exports.getFullDbName = getFullDbName;
8806
9138
  Object.defineProperty(exports, "__esModule", ({ value: true }));
8807
9139
  exports.createCustomDeployJobs = void 0;
8808
9140
  const getAllCacheConfigsFromConfig_1 = __nccwpck_require__(19034);
8809
- const yarn_1 = __nccwpck_require__(59874);
9141
+ const packageManagerInstall_1 = __nccwpck_require__(18600);
8810
9142
  const runner_1 = __nccwpck_require__(71065);
8811
9143
  const base_1 = __nccwpck_require__(93664);
8812
9144
  const types_1 = __nccwpck_require__(71446);
8813
9145
  const createCustomDeployJobs = async (context) => {
8814
- var _a, _b, _c;
9146
+ var _a, _b, _c, _d;
8815
9147
  const deployConfig = (_a = context.deploy) === null || _a === void 0 ? void 0 : _a.config;
8816
9148
  if (!(0, types_1.isOfDeployType)(deployConfig, "custom")) {
8817
9149
  // should not happen
8818
9150
  throw new Error("deploy config is not custom");
8819
9151
  }
8820
- // FIXME: custom deploy currently assumes yarn-based project
8821
- const yarnInstall = await (0, yarn_1.getYarnInstall)(context, {
9152
+ const packageManagerInstall = await (0, packageManagerInstall_1.getPackageManagerInstall)(context, {
8822
9153
  noCustomPostInstall: true,
8823
9154
  });
8824
9155
  const result = (0, base_1.createDeployementJobs)(context, {
@@ -8830,14 +9161,16 @@ const createCustomDeployJobs = async (context) => {
8830
9161
  : undefined,
8831
9162
  script: [
8832
9163
  `cd ${context.build.dir}`,
8833
- ...(deployConfig.requiresYarnInstall ? yarnInstall : []),
9164
+ ...(((_c = deployConfig.requiresInstall) !== null && _c !== void 0 ? _c : deployConfig.requiresYarnInstall)
9165
+ ? packageManagerInstall
9166
+ : []),
8834
9167
  ...deployConfig.script,
8835
9168
  ],
8836
9169
  variables: {},
8837
9170
  },
8838
9171
  stop: deployConfig.stopScript
8839
9172
  ? {
8840
- image: (_c = deployConfig.jobImage) !== null && _c !== void 0 ? _c : (0, runner_1.getRunnerImage)("jobs-default"),
9173
+ image: (_d = deployConfig.jobImage) !== null && _d !== void 0 ? _d : (0, runner_1.getRunnerImage)("jobs-default"),
8841
9174
  script: [...deployConfig.stopScript],
8842
9175
  variables: {},
8843
9176
  }
@@ -9513,12 +9846,12 @@ exports.NPM_PACKAGE_DEPLOY_TYPE = {
9513
9846
  Object.defineProperty(exports, "__esModule", ({ value: true }));
9514
9847
  exports.createPagesDeployJobs = void 0;
9515
9848
  const getAllCacheConfigsFromConfig_1 = __nccwpck_require__(19034);
9516
- const yarn_1 = __nccwpck_require__(59874);
9849
+ const packageManagerInstall_1 = __nccwpck_require__(18600);
9517
9850
  const runner_1 = __nccwpck_require__(71065);
9518
9851
  const base_1 = __nccwpck_require__(93664);
9519
9852
  const types_1 = __nccwpck_require__(71446);
9520
9853
  const createPagesDeployJobs = async (context) => {
9521
- var _a, _b, _c;
9854
+ var _a, _b, _c, _d;
9522
9855
  const deployConfig = (_a = context.deploy) === null || _a === void 0 ? void 0 : _a.config;
9523
9856
  if (!(0, types_1.isOfDeployType)(deployConfig, "pages")) {
9524
9857
  // should not happen
@@ -9533,7 +9866,7 @@ const createPagesDeployJobs = async (context) => {
9533
9866
  // parallel deployments) — every merge request gets a site preview
9534
9867
  const pathPrefix = context.environment.envType === "review" ? "mr-$CI_MERGE_REQUEST_IID" : "";
9535
9868
  const publishDir = (_b = deployConfig.publishDir) !== null && _b !== void 0 ? _b : "public";
9536
- const yarnInstall = await (0, yarn_1.getYarnInstall)(context, {
9869
+ const packageManagerInstall = await (0, packageManagerInstall_1.getPackageManagerInstall)(context, {
9537
9870
  noCustomPostInstall: true,
9538
9871
  });
9539
9872
  return (0, base_1.createDeployementJobs)(context, {
@@ -9544,7 +9877,9 @@ const createPagesDeployJobs = async (context) => {
9544
9877
  pages: { path_prefix: pathPrefix },
9545
9878
  script: [
9546
9879
  `cd ${context.build.dir}`,
9547
- ...(deployConfig.requiresYarnInstall ? yarnInstall : []),
9880
+ ...(((_d = deployConfig.requiresInstall) !== null && _d !== void 0 ? _d : deployConfig.requiresYarnInstall)
9881
+ ? packageManagerInstall
9882
+ : []),
9548
9883
  ...deployConfig.script,
9549
9884
  // the gitlab environment url should point at the published site
9550
9885
  // (the base deploy job reports $ROOT_URL as environment url)
@@ -9765,6 +10100,8 @@ __exportStar(__nccwpck_require__(68906), exports);
9765
10100
  __exportStar(__nccwpck_require__(23040), exports);
9766
10101
  __exportStar(__nccwpck_require__(35086), exports);
9767
10102
  __exportStar(__nccwpck_require__(71065), exports);
10103
+ __exportStar(__nccwpck_require__(55537), exports);
10104
+ __exportStar(__nccwpck_require__(47864), exports);
9768
10105
  __exportStar(__nccwpck_require__(80769), exports);
9769
10106
  __exportStar(__nccwpck_require__(7732), exports);
9770
10107
  __exportStar(__nccwpck_require__(66526), exports);
@@ -10421,6 +10758,89 @@ exports.createJobsForWorkspace = createJobsForWorkspace;
10421
10758
 
10422
10759
  /***/ }),
10423
10760
 
10761
+ /***/ 7633:
10762
+ /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
10763
+
10764
+ "use strict";
10765
+
10766
+ var __importDefault = (this && this.__importDefault) || function (mod) {
10767
+ return (mod && mod.__esModule) ? mod : { "default": mod };
10768
+ };
10769
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
10770
+ exports.detectPackageManager = void 0;
10771
+ const child_process_promise_1 = __nccwpck_require__(42242);
10772
+ const fs_1 = __nccwpck_require__(79896);
10773
+ const promises_1 = __nccwpck_require__(91943);
10774
+ const path_1 = __nccwpck_require__(16928);
10775
+ const memoizee_1 = __importDefault(__nccwpck_require__(14199));
10776
+ const readPackageManagerField = async (dir) => {
10777
+ try {
10778
+ const pkg = JSON.parse(await (0, promises_1.readFile)((0, path_1.join)(dir, "package.json"), "utf-8"));
10779
+ const match = /^(yarn|pnpm)@(.+)$/.exec(pkg.packageManager);
10780
+ if (!match)
10781
+ return null;
10782
+ return { type: match[1], version: match[2] };
10783
+ }
10784
+ catch (_a) {
10785
+ return null;
10786
+ }
10787
+ };
10788
+ const detectByLockfile = (dir) => {
10789
+ if ((0, fs_1.existsSync)((0, path_1.join)(dir, "pnpm-lock.yaml")))
10790
+ return "pnpm";
10791
+ if ((0, fs_1.existsSync)((0, path_1.join)(dir, "yarn.lock")))
10792
+ return "yarn";
10793
+ return null;
10794
+ };
10795
+ const getGitRoot = async () => {
10796
+ try {
10797
+ return (await (0, child_process_promise_1.exec)("git rev-parse --show-toplevel")).stdout.trim();
10798
+ }
10799
+ catch (_a) {
10800
+ return null;
10801
+ }
10802
+ };
10803
+ const getInstalledVersion = async (type) => {
10804
+ try {
10805
+ return (await (0, child_process_promise_1.exec)(`${type} --version`)).stdout.trim();
10806
+ }
10807
+ catch (_a) {
10808
+ return "";
10809
+ }
10810
+ };
10811
+ /**
10812
+ * detect which package manager the project uses (and its version).
10813
+ *
10814
+ * Order: the `packageManager` field in package.json (cwd, then git root)
10815
+ * wins, then the lockfile present (pnpm-lock.yaml → pnpm, yarn.lock →
10816
+ * yarn), then falling back to yarn (the historical default).
10817
+ *
10818
+ * An `explicitType` (from `packageManager` in catladder.ts) overrides the
10819
+ * detected type; the version is still taken from the `packageManager`
10820
+ * field when it pins the same manager, otherwise from the installed CLI.
10821
+ */
10822
+ exports.detectPackageManager = (0, memoizee_1.default)(async (explicitType) => {
10823
+ var _a, _b;
10824
+ const roots = [process.cwd()];
10825
+ const gitRoot = await getGitRoot();
10826
+ if (gitRoot && gitRoot !== process.cwd())
10827
+ roots.push(gitRoot);
10828
+ let fromField = null;
10829
+ for (const root of roots) {
10830
+ fromField = await readPackageManagerField(root);
10831
+ if (fromField)
10832
+ break;
10833
+ }
10834
+ const detectedType = (_b = (_a = explicitType !== null && explicitType !== void 0 ? explicitType : fromField === null || fromField === void 0 ? void 0 : fromField.type) !== null && _a !== void 0 ? _a : roots.map(detectByLockfile).find(Boolean)) !== null && _b !== void 0 ? _b : "yarn";
10835
+ const version = (fromField === null || fromField === void 0 ? void 0 : fromField.type) === detectedType
10836
+ ? fromField.version
10837
+ : await getInstalledVersion(detectedType);
10838
+ return { type: detectedType, version };
10839
+ }, { promise: true });
10840
+ //# sourceMappingURL=detectPackageManager.js.map
10841
+
10842
+ /***/ }),
10843
+
10424
10844
  /***/ 43249:
10425
10845
  /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
10426
10846
 
@@ -10528,12 +10948,23 @@ exports.getPackageManagerInfoBase = exports.getPackageManagerInfoForComponent =
10528
10948
  const fs_1 = __nccwpck_require__(79896);
10529
10949
  const path_1 = __nccwpck_require__(16928);
10530
10950
  const path_equal_1 = __nccwpck_require__(43882);
10951
+ const detectPackageManager_1 = __nccwpck_require__(7633);
10952
+ const pnpmUtils_1 = __nccwpck_require__(3497);
10531
10953
  const yarnUtils_1 = __nccwpck_require__(94191);
10532
10954
  const memoizee_1 = __importDefault(__nccwpck_require__(14199));
10955
+ const PACKAGE_MANAGER_FILES = {
10956
+ yarn: {
10957
+ lockFile: "yarn.lock",
10958
+ configFiles: [".yarnrc", ".yarnrc.yml", ".npmrc", ".yarn"], // ".yarn" is yarn 2 folder
10959
+ },
10960
+ pnpm: {
10961
+ lockFile: "pnpm-lock.yaml",
10962
+ configFiles: ["pnpm-workspace.yaml", ".npmrc", ".pnpmfile.cjs"],
10963
+ },
10964
+ };
10533
10965
  const getPackageManagerInfoForComponent = async (config, componentName) => {
10534
- const baseInfo = await (0, exports.getPackageManagerInfoBase)();
10966
+ const baseInfo = await (0, exports.getPackageManagerInfoBase)(config);
10535
10967
  const { workspaces } = baseInfo;
10536
- // currently only supports yarn
10537
10968
  const component = config.components[componentName];
10538
10969
  const currentWorkspace = workspaces.find((w) => (0, path_equal_1.pathEqual)(component.dir, w.location));
10539
10970
  const componentIsInWorkspace = Boolean(currentWorkspace);
@@ -10542,10 +10973,10 @@ const getPackageManagerInfoForComponent = async (config, componentName) => {
10542
10973
  const workspacePackageJson = componentIsInWorkspace
10543
10974
  ? (0, path_1.join)(workspaceRoot, "package.json")
10544
10975
  : null;
10976
+ const { lockFile: lockFileName, configFiles } = PACKAGE_MANAGER_FILES[baseInfo.type];
10545
10977
  const lockFile = componentIsInWorkspace
10546
- ? (0, path_1.join)(workspaceRoot, "yarn.lock")
10547
- : (0, path_1.join)(component.dir, "yarn.lock");
10548
- const configFiles = [".yarnrc", ".yarnrc.yml", ".npmrc", ".yarn"]; // ".yarn" is yarn 2 folder
10978
+ ? (0, path_1.join)(workspaceRoot, lockFileName)
10979
+ : (0, path_1.join)(component.dir, lockFileName);
10549
10980
  // copy all those configFiles from workspace root and/or component folder
10550
10981
  const configFilePaths = [
10551
10982
  ...configFiles,
@@ -10556,12 +10987,27 @@ const getPackageManagerInfoForComponent = async (config, componentName) => {
10556
10987
  const currentWorkspaceDependencies = currentWorkspace
10557
10988
  ? (0, yarnUtils_1.getWorkspaceDependencies)(currentWorkspace, workspaces)
10558
10989
  : [];
10990
+ // pnpm's --frozen-lockfile check requires every importer of the
10991
+ // lockfile to exist on disk, so all workspace manifests (not just the
10992
+ // dependency workspaces, which are copied entirely) go into the image
10993
+ const allWorkspaceManifests = baseInfo.type === "pnpm" && componentIsInWorkspace
10994
+ ? workspaces
10995
+ .map((w) => (0, path_1.join)(w.location, "package.json"))
10996
+ .filter((f) => (0, fs_1.existsSync)(f))
10997
+ : [];
10998
+ // patch files referenced by patchedDependencies must exist in the
10999
+ // image, or pnpm's frozen install fails verifying them
11000
+ const patchFiles = baseInfo.type === "pnpm"
11001
+ ? (0, pnpmUtils_1.getPnpmPatchFiles)(componentIsInWorkspace ? workspaceRoot : component.dir)
11002
+ : [];
10559
11003
  const pathsToCopyInDocker = [
10560
11004
  ...new Set([
10561
11005
  packageJson,
10562
11006
  ...(workspacePackageJson ? [workspacePackageJson] : []),
10563
11007
  lockFile,
10564
11008
  ...configFilePaths,
11009
+ ...allWorkspaceManifests,
11010
+ ...patchFiles,
10565
11011
  ...currentWorkspaceDependencies,
10566
11012
  ]),
10567
11013
  ];
@@ -10574,11 +11020,17 @@ const getPackageManagerInfoForComponent = async (config, componentName) => {
10574
11020
  };
10575
11021
  };
10576
11022
  exports.getPackageManagerInfoForComponent = getPackageManagerInfoForComponent;
10577
- const _getPackageManagerInfoBase = async () => {
10578
- // currently only supports yarn
10579
- const version = await (0, yarnUtils_1.getYarnVersion)();
11023
+ const _getPackageManagerInfoBase = async (config) => {
11024
+ const { type, version } = await (0, detectPackageManager_1.detectPackageManager)(config === null || config === void 0 ? void 0 : config.packageManager);
10580
11025
  if (!version)
10581
- throw new Error("could not get yarn version");
11026
+ throw new Error(`could not get ${type} version`);
11027
+ if (type === "pnpm") {
11028
+ return {
11029
+ type: "pnpm",
11030
+ workspaces: await (0, pnpmUtils_1.getPnpmWorkspaces)(),
11031
+ version,
11032
+ };
11033
+ }
10582
11034
  const isClassic = version.startsWith("1");
10583
11035
  const workspaces = await (0, yarnUtils_1.getWorkspaces)(isClassic);
10584
11036
  return {
@@ -10590,11 +11042,113 @@ const _getPackageManagerInfoBase = async () => {
10590
11042
  };
10591
11043
  exports.getPackageManagerInfoBase = (0, memoizee_1.default)(_getPackageManagerInfoBase, {
10592
11044
  promise: true,
11045
+ // memoize per explicit packageManager choice, not per config identity
11046
+ normalizer: ([config]) => { var _a; return (_a = config === null || config === void 0 ? void 0 : config.packageManager) !== null && _a !== void 0 ? _a : ""; },
10593
11047
  });
10594
11048
  //# sourceMappingURL=packageManager.js.map
10595
11049
 
10596
11050
  /***/ }),
10597
11051
 
11052
+ /***/ 3497:
11053
+ /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
11054
+
11055
+ "use strict";
11056
+
11057
+ var __importDefault = (this && this.__importDefault) || function (mod) {
11058
+ return (mod && mod.__esModule) ? mod : { "default": mod };
11059
+ };
11060
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
11061
+ exports.getPnpmWorkspaces = exports.getPnpmPatchFiles = void 0;
11062
+ const child_process_promise_1 = __nccwpck_require__(42242);
11063
+ const fs_1 = __nccwpck_require__(79896);
11064
+ const promises_1 = __nccwpck_require__(91943);
11065
+ const path_1 = __nccwpck_require__(16928);
11066
+ const memoizee_1 = __importDefault(__nccwpck_require__(14199));
11067
+ const yaml_1 = __nccwpck_require__(33483);
11068
+ const jsonParse_1 = __nccwpck_require__(99461);
11069
+ const readWorkspaceDependencyLocations = async (location, locationByName) => {
11070
+ var _a, _b, _c;
11071
+ try {
11072
+ const pkg = JSON.parse(await (0, promises_1.readFile)((0, path_1.join)(location, "package.json"), "utf-8"));
11073
+ const depNames = [
11074
+ ...Object.keys((_a = pkg.dependencies) !== null && _a !== void 0 ? _a : {}),
11075
+ ...Object.keys((_b = pkg.devDependencies) !== null && _b !== void 0 ? _b : {}),
11076
+ ...Object.keys((_c = pkg.optionalDependencies) !== null && _c !== void 0 ? _c : {}),
11077
+ ];
11078
+ return [
11079
+ ...new Set(depNames
11080
+ .map((name) => locationByName.get(name))
11081
+ .filter((l) => Boolean(l) && l !== location)),
11082
+ ];
11083
+ }
11084
+ catch (_d) {
11085
+ return [];
11086
+ }
11087
+ };
11088
+ /**
11089
+ * patch files referenced by `patchedDependencies` (pnpm-workspace.yaml
11090
+ * or the root package.json's `pnpm` section) — they must travel into
11091
+ * the docker build context, or the prod install fails to verify them
11092
+ */
11093
+ const getPnpmPatchFiles = (root = ".") => {
11094
+ var _a, _b, _c;
11095
+ const patchedDependencies = {};
11096
+ try {
11097
+ const ws = (0, yaml_1.parse)((0, fs_1.readFileSync)((0, path_1.join)(root, "pnpm-workspace.yaml"), "utf-8"));
11098
+ Object.assign(patchedDependencies, (_a = ws === null || ws === void 0 ? void 0 : ws.patchedDependencies) !== null && _a !== void 0 ? _a : {});
11099
+ }
11100
+ catch (_d) {
11101
+ // no workspace file
11102
+ }
11103
+ try {
11104
+ const pkg = JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(root, "package.json"), "utf-8"));
11105
+ Object.assign(patchedDependencies, (_c = (_b = pkg === null || pkg === void 0 ? void 0 : pkg.pnpm) === null || _b === void 0 ? void 0 : _b.patchedDependencies) !== null && _c !== void 0 ? _c : {});
11106
+ }
11107
+ catch (_e) {
11108
+ // no package.json
11109
+ }
11110
+ return [
11111
+ ...new Set(Object.values(patchedDependencies)
11112
+ .map((p) => (0, path_1.join)(root, p))
11113
+ .filter((p) => (0, fs_1.existsSync)(p))),
11114
+ ];
11115
+ };
11116
+ exports.getPnpmPatchFiles = getPnpmPatchFiles;
11117
+ /**
11118
+ * list pnpm workspace projects in the same shape yarn berry reports them
11119
+ * (locations relative to the project root, workspace dependencies as
11120
+ * locations). Outside a pnpm workspace this returns [].
11121
+ */
11122
+ // export for mocking
11123
+ exports.getPnpmWorkspaces = (0, memoizee_1.default)(async () => {
11124
+ let output;
11125
+ try {
11126
+ output = (await (0, child_process_promise_1.exec)("pnpm m ls --json --depth -1")).stdout;
11127
+ }
11128
+ catch (_a) {
11129
+ return [];
11130
+ }
11131
+ const projects = (0, jsonParse_1.jsonParseOrThrow)(output.trim() || "[]");
11132
+ if (!Array.isArray(projects))
11133
+ return [];
11134
+ const withLocations = projects
11135
+ .filter((p) => p.name && p.path)
11136
+ .map((p) => ({
11137
+ name: p.name,
11138
+ location: (0, path_1.relative)(process.cwd(), p.path) || ".",
11139
+ }));
11140
+ const locationByName = new Map(withLocations.map((p) => [p.name, p.location]));
11141
+ return Promise.all(withLocations.map(async ({ name, location }) => ({
11142
+ name,
11143
+ location,
11144
+ workspaceDependencies: await readWorkspaceDependencyLocations(location, locationByName),
11145
+ mismatchedWorkspaceDependencies: [],
11146
+ })));
11147
+ }, { promise: true });
11148
+ //# sourceMappingURL=pnpmUtils.js.map
11149
+
11150
+ /***/ }),
11151
+
10598
11152
  /***/ 77257:
10599
11153
  /***/ ((__unused_webpack_module, exports) => {
10600
11154
 
@@ -10706,10 +11260,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
10706
11260
  return (mod && mod.__esModule) ? mod : { "default": mod };
10707
11261
  };
10708
11262
  Object.defineProperty(exports, "__esModule", ({ value: true }));
10709
- exports.getWorkspaceDependencies = exports.getWorkspaces = exports.getYarnVersion = void 0;
11263
+ exports.getWorkspaceDependencies = exports.getWorkspaces = void 0;
10710
11264
  const child_process_promise_1 = __nccwpck_require__(42242);
10711
- const promises_1 = __nccwpck_require__(91943);
10712
- const path_1 = __nccwpck_require__(16928);
10713
11265
  const memoizee_1 = __importDefault(__nccwpck_require__(14199));
10714
11266
  const jsonParse_1 = __nccwpck_require__(99461);
10715
11267
  const execOrFail = async (cmd, onFail) => {
@@ -10720,40 +11272,6 @@ const execOrFail = async (cmd, onFail) => {
10720
11272
  return onFail !== null && onFail !== void 0 ? onFail : null;
10721
11273
  }
10722
11274
  };
10723
- const readPackageManagerVersion = async (dir) => {
10724
- var _a;
10725
- try {
10726
- const pkg = JSON.parse(await (0, promises_1.readFile)((0, path_1.join)(dir, "package.json"), "utf-8"));
10727
- const match = /^yarn@(.+)$/.exec(pkg.packageManager);
10728
- return (_a = match === null || match === void 0 ? void 0 : match[1]) !== null && _a !== void 0 ? _a : null;
10729
- }
10730
- catch (_b) {
10731
- return null;
10732
- }
10733
- };
10734
- const getGitRoot = async () => {
10735
- try {
10736
- return (await (0, child_process_promise_1.exec)("git rev-parse --show-toplevel")).stdout.trim();
10737
- }
10738
- catch (_a) {
10739
- return null;
10740
- }
10741
- };
10742
- // export for mocking
10743
- exports.getYarnVersion = (0, memoizee_1.default)(async () => {
10744
- // Fast path: read from package.json packageManager field
10745
- const fromCwd = await readPackageManagerVersion(process.cwd());
10746
- if (fromCwd)
10747
- return fromCwd;
10748
- const gitRoot = await getGitRoot();
10749
- if (gitRoot && gitRoot !== process.cwd()) {
10750
- const fromGitRoot = await readPackageManagerVersion(gitRoot);
10751
- if (fromGitRoot)
10752
- return fromGitRoot;
10753
- }
10754
- // Fallback: invoke yarn CLI
10755
- return await execOrFail("yarn --version", "");
10756
- }, { promise: true });
10757
11275
  // export for mocking
10758
11276
  exports.getWorkspaces = (0, memoizee_1.default)(async (isClassic) => {
10759
11277
  var _a, _b;
@@ -11404,7 +11922,7 @@ exports.createVerifyJobs = exports.VERIFY_JOB_NAME = void 0;
11404
11922
  const createArtifactsConfig_1 = __nccwpck_require__(24494);
11405
11923
  const cache_1 = __nccwpck_require__(21100);
11406
11924
  const constants_1 = __nccwpck_require__(97627);
11407
- const yarn_1 = __nccwpck_require__(59874);
11925
+ const packageManagerInstall_1 = __nccwpck_require__(18600);
11408
11926
  const deploy_1 = __nccwpck_require__(19752);
11409
11927
  const runner_1 = __nccwpck_require__(71065);
11410
11928
  const utils_1 = __nccwpck_require__(24516);
@@ -11421,9 +11939,9 @@ const createVerifyJobs = async (context) => {
11421
11939
  return [];
11422
11940
  }
11423
11941
  const isNodeBuild = context.build.type !== "disabled" && context.build.buildType === "node";
11424
- const [yarnInstall, nodeCache] = isNodeBuild
11942
+ const [packageManagerInstall, nodeCache] = isNodeBuild
11425
11943
  ? await Promise.all([
11426
- (0, yarn_1.getYarnInstall)(context),
11944
+ (0, packageManagerInstall_1.getPackageManagerInstall)(context),
11427
11945
  (0, cache_1.getNodeCache)(context, "pull"),
11428
11946
  ])
11429
11947
  : [null, null];
@@ -11459,9 +11977,9 @@ const createVerifyJobs = async (context) => {
11459
11977
  },
11460
11978
  script: [
11461
11979
  ...setupScript,
11462
- ...(yarnInstall ? (0, yarn_1.ensureNodeVersion)(context) : []),
11980
+ ...(packageManagerInstall ? (0, packageManagerInstall_1.ensureNodeVersion)(context) : []),
11463
11981
  `cd ${context.build.dir}`,
11464
- ...(yarnInstall !== null && yarnInstall !== void 0 ? yarnInstall : []),
11982
+ ...(packageManagerInstall !== null && packageManagerInstall !== void 0 ? packageManagerInstall : []),
11465
11983
  ...(0, utils_1.ensureArray)(verifyConfig.command),
11466
11984
  ],
11467
11985
  allow_failure: verifyConfig.allowFailure,