@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
@@ -8314,7 +8314,7 @@ class GithubBackend {
8314
8314
  await (0, promises_1.rm)(scriptFiles_1.GITHUB_SCRIPTS_FOLDER, { recursive: true, force: true });
8315
8315
  }
8316
8316
  async createFiles(config) {
8317
- const images = this.createImagesPlan();
8317
+ const images = this.createImagesPlan(config);
8318
8318
  const scripts = new scriptFiles_1.GithubScriptFiles();
8319
8319
  const workflows = await this.createWorkflows(config, images, scripts);
8320
8320
  return [
@@ -8329,13 +8329,13 @@ class GithubBackend {
8329
8329
  ...(0, shippedCatci_1.getCatciGeneratedFiles)(),
8330
8330
  ];
8331
8331
  }
8332
- createImagesPlan() {
8333
- return new jobImagesPlan_1.JobImagesPlan(this.type);
8332
+ createImagesPlan(config) {
8333
+ return new jobImagesPlan_1.JobImagesPlan(this.type, config.images);
8334
8334
  }
8335
8335
  /**
8336
8336
  * all workflows keyed by file name, mainly for testing purposes
8337
8337
  */
8338
- async createWorkflows(config, images = this.createImagesPlan(), scripts = new scriptFiles_1.GithubScriptFiles()) {
8338
+ async createWorkflows(config, images = this.createImagesPlan(config), scripts = new scriptFiles_1.GithubScriptFiles()) {
8339
8339
  var _a, _b, _c, _d;
8340
8340
  const workflows = {};
8341
8341
  // per-pipeline-type variables (pipelines.github.runnerVariables);
@@ -9304,7 +9304,7 @@ class GitlabBackend {
9304
9304
  await (0, promises_1.rm)(this.generatedFolder, { force: true, recursive: true });
9305
9305
  }
9306
9306
  async createFiles(config) {
9307
- const images = this.createImagesPlan();
9307
+ const images = this.createImagesPlan(config);
9308
9308
  const includes = await this.createIncludes(config, images);
9309
9309
  const mainFile = {
9310
9310
  path: ".gitlab-ci.yml",
@@ -9321,15 +9321,15 @@ class GitlabBackend {
9321
9321
  ...(0, shippedCatci_1.getCatciGeneratedFiles)(),
9322
9322
  ];
9323
9323
  }
9324
- createImagesPlan() {
9325
- return new jobImagesPlan_1.JobImagesPlan(this.type);
9324
+ createImagesPlan(config) {
9325
+ return new jobImagesPlan_1.JobImagesPlan(this.type, config.images);
9326
9326
  }
9327
9327
  /**
9328
9328
  * the complete pipeline as one object (all includes merged into one),
9329
9329
  * mainly for testing purposes
9330
9330
  */
9331
9331
  async createCompletePipeline(config) {
9332
- const includes = await this.createIncludes(config, this.createImagesPlan());
9332
+ const includes = await this.createIncludes(config, this.createImagesPlan(config));
9333
9333
  return includes.reduce((acc, { content }) => {
9334
9334
  return {
9335
9335
  ...acc,
@@ -10421,7 +10421,7 @@ const jobs_1 = __nccwpck_require__(28006);
10421
10421
  const utils_1 = __nccwpck_require__(24516);
10422
10422
  const removeUndefined_1 = __nccwpck_require__(54420);
10423
10423
  const createBuildJobArtifact_1 = __nccwpck_require__(98820);
10424
- const yarn_1 = __nccwpck_require__(59874);
10424
+ const packageManagerInstall_1 = __nccwpck_require__(18600);
10425
10425
  const constants_1 = __nccwpck_require__(69302);
10426
10426
  const writeBuildInfo_1 = __nccwpck_require__(92254);
10427
10427
  const writeDotEnv_1 = __nccwpck_require__(76670);
@@ -10461,7 +10461,7 @@ class AppBuildJob extends jobs_1.CatladderJob {
10461
10461
  .flatMap((c) => (0, writeDotEnv_1.writeDotEnv)(c))
10462
10462
  : []),
10463
10463
  ...(context.type === "component" ? (0, writeBuildInfo_1.writeBuildInfo)(context) : []),
10464
- ...(0, yarn_1.ensureNodeVersion)(context), // in pure node repos, we might want to have the nvmrc file in top-level
10464
+ ...(0, packageManagerInstall_1.ensureNodeVersion)(context), // in pure node repos, we might want to have the nvmrc file in top-level
10465
10465
  `cd ${context.build.dir}`,
10466
10466
  ...(0, utils_1.ensureArray)(script),
10467
10467
  ],
@@ -11158,27 +11158,32 @@ const node_1 = __nccwpck_require__(23114);
11158
11158
  const rails_1 = __nccwpck_require__(42427);
11159
11159
  __exportStar(__nccwpck_require__(23114), exports);
11160
11160
  __exportStar(__nccwpck_require__(40632), exports);
11161
+ /**
11162
+ * run a package.json script with the project's package manager
11163
+ * (`yarn build` / `pnpm build`)
11164
+ */
11165
+ const runScript = (packageManager, script) => `${packageManager} ${script}`;
11161
11166
  exports.BUILD_TYPES = {
11162
11167
  node: {
11163
11168
  jobs: node_1.createNodeJobs,
11164
- defaults: () => ({
11165
- buildCommand: "yarn build",
11166
- startCommand: "yarn start",
11169
+ defaults: (_, pm) => ({
11170
+ buildCommand: runScript(pm, "build"),
11171
+ startCommand: runScript(pm, "start"),
11167
11172
  artifactsPaths: ["dist", ".next"],
11168
11173
  artifactsExcludePaths: [".next/cache/**/*"],
11169
11174
  }),
11170
11175
  },
11171
11176
  "node-static": {
11172
11177
  jobs: node_1.createNodeJobs,
11173
- defaults: () => ({
11174
- buildCommand: "yarn build",
11178
+ defaults: (_, pm) => ({
11179
+ buildCommand: runScript(pm, "build"),
11175
11180
  artifactsPaths: ["dist"],
11176
11181
  }),
11177
11182
  },
11178
11183
  storybook: {
11179
11184
  jobs: node_1.createStorybookJobs,
11180
- defaults: () => ({
11181
- buildCommand: ["yarn build-storybook --quiet -o ./dist"],
11185
+ defaults: (_, pm) => ({
11186
+ buildCommand: [runScript(pm, "build-storybook --quiet -o ./dist")],
11182
11187
  artifactsPaths: ["dist"],
11183
11188
  }),
11184
11189
  },
@@ -11208,13 +11213,13 @@ exports.BUILD_TYPES = {
11208
11213
  exports.WORKSPACE_BUILD_TYPES = {
11209
11214
  node: {
11210
11215
  jobs: node_1.createNodeJobs,
11211
- defaults: () => ({
11212
- buildCommand: "yarn build",
11216
+ defaults: (pm) => ({
11217
+ buildCommand: runScript(pm, "build"),
11213
11218
  lint: {
11214
- command: "yarn lint",
11219
+ command: runScript(pm, "lint"),
11215
11220
  },
11216
11221
  test: {
11217
- command: "yarn test",
11222
+ command: runScript(pm, "test"),
11218
11223
  },
11219
11224
  }),
11220
11225
  },
@@ -11235,7 +11240,7 @@ const base_1 = __nccwpck_require__(61619);
11235
11240
  const createBuildJobDefinition_1 = __nccwpck_require__(88685);
11236
11241
  const docker_1 = __nccwpck_require__(83777);
11237
11242
  const cache_1 = __nccwpck_require__(21100);
11238
- const yarn_1 = __nccwpck_require__(59874);
11243
+ const packageManagerInstall_1 = __nccwpck_require__(18600);
11239
11244
  const createNodeBuildJobs = async (context) => {
11240
11245
  if (context.type === "workspace") {
11241
11246
  return (0, base_1.createWorkspaceBuildJobs)(context, {
@@ -11252,18 +11257,17 @@ const createNodeBuildJobs = async (context) => {
11252
11257
  exports.createNodeBuildJobs = createNodeBuildJobs;
11253
11258
  const createNodeBuildJobDefinition = async (context) => {
11254
11259
  const buildConfig = context.build.config;
11255
- const [yarnInstall, nodeCache] = await Promise.all([
11256
- (0, yarn_1.getYarnInstall)(context),
11260
+ const [packageManagerInstall, nodeCache] = await Promise.all([
11261
+ (0, packageManagerInstall_1.getPackageManagerInstall)(context),
11257
11262
  (0, cache_1.getNodeCache)(context),
11258
11263
  ]);
11259
11264
  return (0, createBuildJobDefinition_1.createBuildJobDefinition)(context, buildConfig, {
11260
- prescript: yarnInstall,
11265
+ prescript: packageManagerInstall,
11261
11266
  cache: nodeCache,
11262
11267
  });
11263
11268
  };
11264
11269
  exports.createNodeBuildJobDefinition = createNodeBuildJobDefinition;
11265
11270
  const createNodeDockerJobDefinition = async (context) => {
11266
- var _a;
11267
11271
  // get the default docker built-in type based on the build type
11268
11272
  const dockerDefaultBuiltIn = context.build.buildType === "node-static" ||
11269
11273
  context.build.buildType === "storybook"
@@ -11271,16 +11275,58 @@ const createNodeDockerJobDefinition = async (context) => {
11271
11275
  : "node";
11272
11276
  const [yarnCache, dockerAppCopyAndBuildScript, packageManagerInfo] = await Promise.all([
11273
11277
  (0, cache_1.getYarnCache)(context, "pull"),
11274
- (0, yarn_1.getDockerAppCopyAndBuildScript)(context),
11278
+ (0, packageManagerInstall_1.getDockerAppCopyAndBuildScript)(context),
11275
11279
  context.packageManagerInfo,
11276
11280
  ]);
11281
+ // the pnpm store (pulled via the cache above) is copied into the
11282
+ // image so the prod install works offline — like the yarn zip cache,
11283
+ // which travels inside the copied `.yarn` config folder
11284
+ const copyPnpmStore = packageManagerInfo.type === "pnpm" &&
11285
+ packageManagerInfo.componentIsInWorkspace;
11286
+ // pnpm copies every workspace manifest into the image — as individual
11287
+ // COPY instructions that many layers exceed docker's depth limit, so
11288
+ // the job tars them up and a single ADD extracts them
11289
+ const isPnpm = packageManagerInfo.type === "pnpm";
11290
+ const WORKSPACE_FILES_TAR = ".catladder-workspace-files.tar";
11277
11291
  return {
11278
- script: (0, docker_1.getDockerBuildScriptWithBuiltInDockerFile)(context, dockerDefaultBuiltIn),
11292
+ script: [
11293
+ // the COPY source must exist even when the cache was cold
11294
+ ...(copyPnpmStore ? ["mkdir -p .pnpm-store"] : []),
11295
+ ...(isPnpm
11296
+ ? [
11297
+ `tar -cf ${WORKSPACE_FILES_TAR} ${packageManagerInfo.pathsToCopyInDocker.join(" ")}`,
11298
+ ]
11299
+ : []),
11300
+ ...(0, docker_1.getDockerBuildScriptWithBuiltInDockerFile)(context, dockerDefaultBuiltIn),
11301
+ ],
11279
11302
  cache: [...yarnCache],
11280
11303
  variables: {
11281
11304
  // only required for non static
11282
11305
  DOCKER_COPY_AND_INSTALL_APP: dockerAppCopyAndBuildScript,
11283
- 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"),
11306
+ DOCKER_COPY_WORKSPACE_FILES: isPnpm
11307
+ ? [
11308
+ `ADD ${WORKSPACE_FILES_TAR} /app/`,
11309
+ // ADD does not apply --chown to extracted tars, and parent
11310
+ // dirs of the entries come out root-owned — fix ownership
11311
+ // while the stage still runs as root (store not copied yet,
11312
+ // so this only touches the small manifest tree). Custom
11313
+ // base images without a node user run as root and don't
11314
+ // need it, hence the fallback
11315
+ `RUN chown -R node:node /app || true`,
11316
+ ...(copyPnpmStore
11317
+ ? [`COPY --chown=node:node .pnpm-store /app/.pnpm-store`]
11318
+ : []),
11319
+ ].join("\n")
11320
+ : packageManagerInfo.pathsToCopyInDocker
11321
+ .map((dir) => `COPY --chown=node:node ${dir} /app/${dir}`)
11322
+ .join("\n"),
11323
+ // pnpm is not preinstalled in the node base images; installed as
11324
+ // root before the image switches to the node user
11325
+ ...(isPnpm
11326
+ ? {
11327
+ DOCKER_SETUP_PACKAGE_MANAGER: `RUN npm install -g pnpm@${packageManagerInfo.version}`,
11328
+ }
11329
+ : {}),
11284
11330
  },
11285
11331
  };
11286
11332
  };
@@ -11299,12 +11345,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
11299
11345
  };
11300
11346
  Object.defineProperty(exports, "__esModule", ({ value: true }));
11301
11347
  exports.getNodeCache = exports.getNodeModulesCache = exports.getYarnCache = void 0;
11348
+ const lodash_es_1 = __nccwpck_require__(50866);
11302
11349
  const path_1 = __nccwpck_require__(16928);
11303
11350
  const slugify_1 = __importDefault(__nccwpck_require__(21396));
11304
11351
  /**
11305
- * stable reference between the two node caches: the yarn (zip) cache
11306
- * declares itself redundant when the node_modules cache scored an
11307
- * exact-lockfile hit (github skips the ~0.6GB download on warm runs)
11352
+ * stable reference between the two node caches: the package-manager
11353
+ * (yarn zip / pnpm store) cache declares itself redundant when the
11354
+ * node_modules cache scored an exact-lockfile hit (github skips the
11355
+ * ~0.6GB download on warm runs)
11308
11356
  */
11309
11357
  const NODE_MODULES_CACHE_ID = "node-modules";
11310
11358
  /**
@@ -11331,23 +11379,37 @@ const getCacheBaseDir = async (context) => {
11331
11379
  ? ((_a = context.build.workspaceBuildConfig.dir) !== null && _a !== void 0 ? _a : ".")
11332
11380
  : ".";
11333
11381
  };
11382
+ /**
11383
+ * the package manager's download cache: yarn's `.yarn` zip cache, or
11384
+ * pnpm's content-addressable store (which catladder points at a
11385
+ * project-local `.pnpm-store`, see the install script)
11386
+ */
11334
11387
  const getYarnCache = async (context, policy = "pull-push") => {
11388
+ const packageManagerInfo = await context.packageManagerInfo;
11389
+ const isPnpm = packageManagerInfo.type === "pnpm";
11335
11390
  const baseDir = await getCacheBaseDir(context);
11391
+ // pnpm keeps its store in a format-versioned subdir (v10, v11, ...)
11392
+ // and never cleans old ones up — scope the cache slot by major so a
11393
+ // pnpm upgrade starts a fresh slot instead of dragging the dead old
11394
+ // store tree along in every cache transfer (formats change only on
11395
+ // majors)
11396
+ const pnpmStoreKey = `pnpm-v${packageManagerInfo.version.split(".")[0]}`;
11336
11397
  return [
11337
11398
  {
11338
11399
  scope: "buildDir",
11339
11400
  pathMode: "relative",
11340
11401
  buildDir: baseDir,
11341
- key: "yarn",
11402
+ key: isPnpm ? pnpmStoreKey : "yarn",
11342
11403
  policy,
11343
- paths: [".yarn"],
11404
+ paths: [isPnpm ? ".pnpm-store" : ".yarn"],
11344
11405
  // content-key for immutable-cache backends (github); the lockfile
11345
11406
  // decides whether the cached content could have changed
11346
- keyFiles: ["yarn.lock"],
11347
- // the .yarn zips (~hundreds of MB) are only read when yarn has to
11348
- // (re)install packages. When the node_modules cache hit for the
11349
- // same lockfile, install verifies via install-state.gz and never
11350
- // opens a zip — so github skips downloading this cache entirely
11407
+ keyFiles: [isPnpm ? "pnpm-lock.yaml" : "yarn.lock"],
11408
+ // the package manager's download cache (~hundreds of MB) is only
11409
+ // read when packages have to be (re)installed. When the
11410
+ // node_modules cache hit for the same lockfile, install verifies
11411
+ // its state file and never touches the store — so github skips
11412
+ // downloading this cache entirely
11351
11413
  redundantOnExactHitOf: NODE_MODULES_CACHE_ID,
11352
11414
  },
11353
11415
  ];
@@ -11356,27 +11418,50 @@ exports.getYarnCache = getYarnCache;
11356
11418
  const getNodeModulesCache = async (context, policy = "pull-push") => {
11357
11419
  const packageManagerInfo = await context.packageManagerInfo;
11358
11420
  const baseDir = await getCacheBaseDir(context);
11359
- const { isClassic } = packageManagerInfo;
11360
- // 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.
11421
+ const { workspaces } = packageManagerInfo;
11422
+ const isPnpm = packageManagerInfo.type === "pnpm";
11423
+ const lockFileName = isPnpm ? "pnpm-lock.yaml" : "yarn.lock";
11424
+ // yarn berry tracks install state in .yarn/install-state.gz (pnpm's
11425
+ // equivalent lives inside node_modules and is covered by the paths)
11426
+ const hasInstallState = packageManagerInfo.type === "yarn" && !packageManagerInfo.isClassic;
11427
+ // 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.
11361
11428
  // It would slow down all pipelines whenever one adds a new dependency as it will need to download all node_modules again.
11362
11429
  return [
11363
11430
  {
11364
11431
  scope: "global",
11365
11432
  pathMode: "absolute",
11366
11433
  // 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
11367
- key: (0, slugify_1.default)(baseDir) + "-node-modules",
11434
+ //
11435
+ // pnpm gets its own, lockfile-keyed cache: node_modules layouts
11436
+ // are not compatible between package managers (a migrating
11437
+ // project must not inherit the yarn slot), and unlike yarn, a
11438
+ // pnpm install on top of a node_modules from a different lockfile
11439
+ // leaves orphaned .pnpm dirs behind that break type identity —
11440
+ // so the slot changes whenever the lockfile changes
11441
+ key: isPnpm
11442
+ ? {
11443
+ prefix: "pnpm-" + (0, slugify_1.default)(baseDir) + "-node-modules",
11444
+ files: [(0, path_1.join)(baseDir, "pnpm-lock.yaml")],
11445
+ }
11446
+ : (0, slugify_1.default)(baseDir) + "-node-modules",
11368
11447
  // content-key for immutable-cache backends (github); the lockfile
11369
11448
  // decides whether the cached content could have changed (absolute
11370
11449
  // pathMode: resolve the lockfile explicitly)
11371
- keyFiles: [(0, path_1.join)(baseDir, "yarn.lock")],
11372
- // referenced by the yarn cache: an exact hit here makes the yarn
11373
- // zips unnecessary (see redundantOnExactHitOf on getYarnCache)
11450
+ keyFiles: [(0, path_1.join)(baseDir, lockFileName)],
11451
+ // referenced by the package-manager cache: an exact hit here makes
11452
+ // it unnecessary (see redundantOnExactHitOf on getYarnCache)
11374
11453
  cacheId: NODE_MODULES_CACHE_ID,
11375
11454
  policy,
11376
- paths: [
11455
+ paths: (0, lodash_es_1.uniq)([
11377
11456
  (0, path_1.join)(baseDir, "node_modules"),
11378
- ...(!isClassic ? [(0, path_1.join)(baseDir, ".yarn/install-state.gz")] : []),
11379
- ],
11457
+ // pnpm's per-package node_modules are symlink farms worth
11458
+ // keeping warm (yarn hoists into the root, so root-only
11459
+ // matches its historical behavior)
11460
+ ...(isPnpm
11461
+ ? workspaces.map((w) => (0, path_1.join)(w.location, "node_modules"))
11462
+ : []),
11463
+ ...(hasInstallState ? [(0, path_1.join)(baseDir, ".yarn/install-state.gz")] : []),
11464
+ ]),
11380
11465
  },
11381
11466
  ];
11382
11467
  };
@@ -11455,7 +11540,7 @@ const base_1 = __nccwpck_require__(61619);
11455
11540
  const docker_1 = __nccwpck_require__(83777);
11456
11541
  const types_1 = __nccwpck_require__(40632);
11457
11542
  const cache_1 = __nccwpck_require__(21100);
11458
- const yarn_1 = __nccwpck_require__(59874);
11543
+ const packageManagerInstall_1 = __nccwpck_require__(18600);
11459
11544
  const getMeteorCache = (context) => [
11460
11545
  {
11461
11546
  key: "meteor-build-cache",
@@ -11470,6 +11555,11 @@ const getMeteorCache = (context) => [
11470
11555
  ];
11471
11556
  const getMeteorDockerInstallScripts = async (context) => {
11472
11557
  const packageManagerInfo = await context.packageManagerInfo;
11558
+ if (packageManagerInfo.type === "pnpm") {
11559
+ // not a meteor limitation — catladder's meteor docker install path
11560
+ // is only implemented for yarn so far
11561
+ throw new Error("the meteor build type is only implemented for yarn in catladder");
11562
+ }
11473
11563
  if (packageManagerInfo.isClassic) {
11474
11564
  return new bash_1.BashExpression(`
11475
11565
  COPY $APP_DIR/package.json $APP_DIR/yarn.lock ./
@@ -11496,8 +11586,8 @@ const createMeteorBuildJobs = async (context) => {
11496
11586
  if (!(0, types_1.isOfBuildType)(buildConfig, "meteor")) {
11497
11587
  throw new Error("deploy config is not meteor");
11498
11588
  }
11499
- const [yarnInstall, nodeCache, meteorInstallScripts] = await Promise.all([
11500
- (0, yarn_1.getYarnInstall)(context),
11589
+ const [packageManagerInstall, nodeCache, meteorInstallScripts] = await Promise.all([
11590
+ (0, packageManagerInstall_1.getPackageManagerInstall)(context),
11501
11591
  (0, cache_1.getNodeCache)(context),
11502
11592
  buildConfig.installScripts
11503
11593
  ? getMeteorDockerInstallScripts(context)
@@ -11512,7 +11602,7 @@ const createMeteorBuildJobs = async (context) => {
11512
11602
  METEOR_DISABLE_OPTIMISTIC_CACHING: "1", // see https://forums.meteor.com/t/veeery-long-building-time-inside-docker-container/58673/17?u=macrozone
11513
11603
  },
11514
11604
  script: [
11515
- ...yarnInstall,
11605
+ ...packageManagerInstall,
11516
11606
  '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',
11517
11607
  "cp ./__build_info.json ./dist/bundle/programs/server",
11518
11608
  ],
@@ -11531,6 +11621,158 @@ exports.createMeteorBuildJobs = createMeteorBuildJobs;
11531
11621
 
11532
11622
  /***/ }),
11533
11623
 
11624
+ /***/ 18600:
11625
+ /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
11626
+
11627
+ "use strict";
11628
+
11629
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
11630
+ exports.getDockerAppCopyAndBuildScript = exports.getPackageManagerInstall = exports.ensureNodeVersion = exports.getDefaultAuditCommand = void 0;
11631
+ const bash_1 = __nccwpck_require__(92390);
11632
+ const utils_1 = __nccwpck_require__(24516);
11633
+ const gitlab_1 = __nccwpck_require__(37393);
11634
+ const YARN_INSTALL_CLASSIC = `yarn install --frozen-lockfile`;
11635
+ const YARN_BERRY_PROD_INSTALL = `yarn workspaces focus --production`;
11636
+ // FIXME: check why and when rebuild is needed
11637
+ const YARN_BERRY_PROD_REBUILD = `yarn rebuild`;
11638
+ const getYarnInstallCommand = (packageManagerInfo) => {
11639
+ if (packageManagerInfo.isClassic) {
11640
+ return YARN_INSTALL_CLASSIC;
11641
+ }
11642
+ // inline builds make debugging easier as it prints it out in the logs, instead of writing it in temp files
11643
+ return `yarn install --immutable --inline-builds`;
11644
+ };
11645
+ const isInWorkspace = (context, packageManagerInfo) => context.type === "workspace" ||
11646
+ ("componentIsInWorkspace" in packageManagerInfo &&
11647
+ packageManagerInfo.componentIsInWorkspace);
11648
+ /**
11649
+ * make sure pnpm is available (job images ship it, older/custom images
11650
+ * fall back to corepack or a pinned global install)
11651
+ */
11652
+ const getEnsurePnpmCommand = (version) => `if ! command -v pnpm &> /dev/null; then corepack enable pnpm 2>/dev/null || npm install -g pnpm@${version}; fi`;
11653
+ /**
11654
+ * pnpm's store is global by default; point it at a project-local
11655
+ * directory so CI can cache it (the pnpm equivalent of the `.yarn`
11656
+ * zip cache). Passed as the --store-dir flag: pnpm 11 stopped reading
11657
+ * the npm_config_store_dir env var (settings only come from
11658
+ * pnpm-workspace.yaml / global config / CLI flags), the flag works on
11659
+ * v10 and v11
11660
+ */
11661
+ const getPnpmStoreDirExpression = (inWorkspace) => inWorkspace
11662
+ ? `"$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.pnpm-store"`
11663
+ : `"$PWD/.pnpm-store"`;
11664
+ const getPnpmInstallCommands = (context, packageManagerInfo) => [
11665
+ getEnsurePnpmCommand(packageManagerInfo.version),
11666
+ `pnpm install --frozen-lockfile --store-dir ${getPnpmStoreDirExpression(isInWorkspace(context, packageManagerInfo))}`,
11667
+ ];
11668
+ /**
11669
+ * default `audit` job command per package manager. Exhaustive on the
11670
+ * package-manager type and throws for anything unsupported, so adding a
11671
+ * new package manager surfaces every place that needs a command here.
11672
+ */
11673
+ const getDefaultAuditCommand = (packageManagerInfo) => {
11674
+ switch (packageManagerInfo.type) {
11675
+ case "pnpm":
11676
+ return "pnpm audit --prod --audit-level critical";
11677
+ case "yarn":
11678
+ return packageManagerInfo.isClassic
11679
+ ? "yarn audit --level critical"
11680
+ : "yarn npm audit --environment production --severity critical"; // yarn 2+
11681
+ default:
11682
+ throw new Error(`no audit command implemented for package manager "${packageManagerInfo.type}"`);
11683
+ }
11684
+ };
11685
+ exports.getDefaultAuditCommand = getDefaultAuditCommand;
11686
+ const ensureNodeVersion = (context) => (0, gitlab_1.collapseableSection)("nodeinstall", "Ensure node version")([
11687
+ // github actions overrides HOME in container jobs, so also look
11688
+ // for nvm where the catladder images install it (/root/.nvm)
11689
+ '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',
11690
+ "if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi",
11691
+ ]);
11692
+ exports.ensureNodeVersion = ensureNodeVersion;
11693
+ const getPackageManagerInstall = async (context, options) => {
11694
+ const packageManagerInfo = await context.packageManagerInfo;
11695
+ const postInstall = context.type !== "workspace" &&
11696
+ context.build.type !== "disabled" &&
11697
+ "postInstall" in context.build.config
11698
+ ? context.build.config.postInstall
11699
+ : null;
11700
+ const installSection = packageManagerInfo.type === "pnpm"
11701
+ ? (0, gitlab_1.collapseableSection)("pnpminstall", "pnpm install")(getPnpmInstallCommands(context, packageManagerInfo))
11702
+ : (0, gitlab_1.collapseableSection)("yarninstall", "Yarn install")([getYarnInstallCommand(packageManagerInfo)]);
11703
+ return [
11704
+ ...(0, exports.ensureNodeVersion)(context),
11705
+ ...installSection,
11706
+ ...(postInstall && !(options === null || options === void 0 ? void 0 : options.noCustomPostInstall)
11707
+ ? (0, gitlab_1.collapseableSection)("postinstall", "Custom post install")((0, utils_1.ensureArray)(postInstall))
11708
+ : []),
11709
+ ];
11710
+ };
11711
+ exports.getPackageManagerInstall = getPackageManagerInstall;
11712
+ const DOCKER_COPY_FILES = `COPY --chown=node:node $APP_DIR .`;
11713
+ const getPnpmDockerAppCopyAndBuildScript = (packageManagerInfo) => {
11714
+ // the store was copied into the image (like the yarn zip cache), so
11715
+ // the prod install links from it instead of hitting the registry
11716
+ const storeDir = packageManagerInfo.componentIsInWorkspace
11717
+ ? "/app/.pnpm-store"
11718
+ : "/app/$APP_DIR/.pnpm-store";
11719
+ // in a workspace, only install the component (and its workspace
11720
+ // dependencies) — the pnpm equivalent of `yarn workspaces focus`.
11721
+ // npm package names are shell-safe unquoted (the whole script is
11722
+ // embedded in a double-quoted bash export, so inner quotes would nest)
11723
+ const filter = packageManagerInfo.componentIsInWorkspace &&
11724
+ packageManagerInfo.currentWorkspace
11725
+ ? ` --filter ${packageManagerInfo.currentWorkspace.name}...`
11726
+ : "";
11727
+ return new bash_1.BashExpression(`
11728
+ ${DOCKER_COPY_FILES}
11729
+ RUN command -v pnpm >/dev/null 2>&1 || npm install -g pnpm@${packageManagerInfo.version}
11730
+ RUN pnpm install --prod --frozen-lockfile --store-dir ${storeDir}${filter}
11731
+ `.trim());
11732
+ };
11733
+ const getDockerAppCopyAndBuildScript = async (context) => {
11734
+ var _a, _b, _c;
11735
+ const packageManagerInfo = await context.packageManagerInfo;
11736
+ if (packageManagerInfo.type === "pnpm") {
11737
+ return getPnpmDockerAppCopyAndBuildScript(packageManagerInfo);
11738
+ }
11739
+ if (packageManagerInfo.isClassic) {
11740
+ return new bash_1.BashExpression(`
11741
+ RUN ${YARN_INSTALL_CLASSIC} --production --ignore-scripts
11742
+ ${DOCKER_COPY_FILES}
11743
+ RUN ${YARN_INSTALL_CLASSIC} --production
11744
+ `.trim());
11745
+ }
11746
+ const yarnRebuildEnabledDefault = context.build.type === "fromWorkspace"
11747
+ ? ((_b = (_a = context.build.workspaceBuildConfig.dockerDefaults) === null || _a === void 0 ? void 0 : _a.yarnRebuildEnabled) !== null && _b !== void 0 ? _b : true)
11748
+ : true;
11749
+ const yarnRebuildEnabled = "docker" in context.build.config &&
11750
+ context.build.config.docker &&
11751
+ "yarnRebuildEnabled" in context.build.config.docker
11752
+ ? ((_c = context.build.config.docker.yarnRebuildEnabled) !== null && _c !== void 0 ? _c : yarnRebuildEnabledDefault)
11753
+ : yarnRebuildEnabledDefault;
11754
+ // yarn >= 4 ships with build in plugins, see https://github.com/yarnpkg/berry/pull/4253
11755
+ // trying to import those fail on this version
11756
+ const doesNotShipWithBuiltInPlugins = ["2", "3"].some((v) => packageManagerInfo.version.startsWith(v));
11757
+ const maybeAddWorkspaceToolsCommand = doesNotShipWithBuiltInPlugins
11758
+ ? "RUN yarn plugin import workspace-tools"
11759
+ : "";
11760
+ // copy first everything and then install
11761
+ // rebuild first does not work as it will run postinstall and that might require files in the app
11762
+ return new bash_1.BashExpression(`
11763
+ ENV YARN_ENABLE_INLINE_BUILDS=1
11764
+ ${DOCKER_COPY_FILES}
11765
+ ${maybeAddWorkspaceToolsCommand}
11766
+ RUN ${YARN_BERRY_PROD_INSTALL}
11767
+ ${yarnRebuildEnabled ? `RUN ${YARN_BERRY_PROD_REBUILD}` : ""}
11768
+
11769
+ `.trim());
11770
+ };
11771
+ exports.getDockerAppCopyAndBuildScript = getDockerAppCopyAndBuildScript;
11772
+ //# sourceMappingURL=packageManagerInstall.js.map
11773
+
11774
+ /***/ }),
11775
+
11534
11776
  /***/ 79769:
11535
11777
  /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
11536
11778
 
@@ -11545,7 +11787,7 @@ const utils_1 = __nccwpck_require__(24516);
11545
11787
  const createArtifactsConfig_1 = __nccwpck_require__(24494);
11546
11788
  const cache_1 = __nccwpck_require__(21100);
11547
11789
  const constants_1 = __nccwpck_require__(97627);
11548
- const yarn_1 = __nccwpck_require__(59874);
11790
+ const packageManagerInstall_1 = __nccwpck_require__(18600);
11549
11791
  const createNodeTestJobs = async (context) => {
11550
11792
  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;
11551
11793
  // don't run tests after release
@@ -11572,8 +11814,8 @@ const createNodeTestJobs = async (context) => {
11572
11814
  needs: [],
11573
11815
  };
11574
11816
  const buildConfig = context.build.config;
11575
- const [yarnInstall, packageManagerInfo, nodeCache] = await Promise.all([
11576
- (0, yarn_1.getYarnInstall)(context),
11817
+ const [packageManagerInstall, packageManagerInfo, nodeCache] = await Promise.all([
11818
+ (0, packageManagerInstall_1.getPackageManagerInstall)(context),
11577
11819
  context.packageManagerInfo,
11578
11820
  // pull-only: the build job is the designated cache writer — lint and
11579
11821
  // test produce equivalent content from the same lockfile, so their
@@ -11589,13 +11831,11 @@ const createNodeTestJobs = async (context) => {
11589
11831
  ...((_b = (_a = buildConfig.audit) === null || _a === void 0 ? void 0 : _a.runnerVariables) !== null && _b !== void 0 ? _b : {}),
11590
11832
  },
11591
11833
  image: (_d = (_c = buildConfig.audit) === null || _c === void 0 ? void 0 : _c.jobImage) !== null && _d !== void 0 ? _d : defaultImage,
11592
- caches: undefined, // audit does not need yarn install and no cache
11834
+ caches: undefined, // audit does not need an install and no cache
11593
11835
  script: [
11594
11836
  `cd ${context.build.dir}`,
11595
11837
  ...((_f = (0, utils_1.ensureArrayOrNull)((_e = buildConfig.audit) === null || _e === void 0 ? void 0 : _e.command)) !== null && _f !== void 0 ? _f : [
11596
- packageManagerInfo.isClassic
11597
- ? "yarn audit --level critical"
11598
- : "yarn npm audit --environment production --severity critical", // yarn 2
11838
+ (0, packageManagerInstall_1.getDefaultAuditCommand)(packageManagerInfo),
11599
11839
  ]),
11600
11840
  ],
11601
11841
  allow_failure: (_h = (_g = buildConfig.audit) === null || _g === void 0 ? void 0 : _g.allowFailure) !== null && _h !== void 0 ? _h : true,
@@ -11613,9 +11853,9 @@ const createNodeTestJobs = async (context) => {
11613
11853
  image: (_p = (_o = buildConfig.lint) === null || _o === void 0 ? void 0 : _o.jobImage) !== null && _p !== void 0 ? _p : defaultImage,
11614
11854
  caches: nodeCache,
11615
11855
  script: [
11616
- ...(0, yarn_1.ensureNodeVersion)(context),
11856
+ ...(0, packageManagerInstall_1.ensureNodeVersion)(context),
11617
11857
  `cd ${context.build.dir}`,
11618
- ...yarnInstall,
11858
+ ...packageManagerInstall,
11619
11859
  ...((_r = (0, utils_1.ensureArrayOrNull)((_q = buildConfig.lint) === null || _q === void 0 ? void 0 : _q.command)) !== null && _r !== void 0 ? _r : ["yarn lint"]),
11620
11860
  ],
11621
11861
  allow_failure: (_s = buildConfig.lint) === null || _s === void 0 ? void 0 : _s.allowFailure,
@@ -11633,9 +11873,9 @@ const createNodeTestJobs = async (context) => {
11633
11873
  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"),
11634
11874
  caches: nodeCache,
11635
11875
  script: [
11636
- ...(0, yarn_1.ensureNodeVersion)(context),
11876
+ ...(0, packageManagerInstall_1.ensureNodeVersion)(context),
11637
11877
  `cd ${context.build.dir}`,
11638
- ...yarnInstall,
11878
+ ...packageManagerInstall,
11639
11879
  ...((_0 = (0, utils_1.ensureArrayOrNull)((_z = buildConfig.test) === null || _z === void 0 ? void 0 : _z.command)) !== null && _0 !== void 0 ? _0 : ["yarn test"]),
11640
11880
  ],
11641
11881
  allow_failure: (_1 = buildConfig.test) === null || _1 === void 0 ? void 0 : _1.allowFailure,
@@ -11649,91 +11889,6 @@ exports.createNodeTestJobs = createNodeTestJobs;
11649
11889
 
11650
11890
  /***/ }),
11651
11891
 
11652
- /***/ 59874:
11653
- /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
11654
-
11655
- "use strict";
11656
-
11657
- Object.defineProperty(exports, "__esModule", ({ value: true }));
11658
- exports.getDockerAppCopyAndBuildScript = exports.getYarnInstall = exports.ensureNodeVersion = void 0;
11659
- const bash_1 = __nccwpck_require__(92390);
11660
- const utils_1 = __nccwpck_require__(24516);
11661
- const gitlab_1 = __nccwpck_require__(37393);
11662
- const YARN_INSTALL_CLASSIC = `yarn install --frozen-lockfile`;
11663
- const YARN_BERRY_PROD_INSTALL = `yarn workspaces focus --production`;
11664
- // FIXME: check why and when rebuild is needed
11665
- const YARN_BERRY_PROD_REBUILD = `yarn rebuild`;
11666
- const getYarnInstallCommand = async (context) => {
11667
- const packageManagerInfo = await context.packageManagerInfo;
11668
- if (packageManagerInfo.isClassic) {
11669
- return YARN_INSTALL_CLASSIC;
11670
- }
11671
- // inline builds make debugging easier as it prints it out in the logs, instead of writing it in temp files
11672
- return `yarn install --immutable --inline-builds`;
11673
- };
11674
- const ensureNodeVersion = (context) => (0, gitlab_1.collapseableSection)("nodeinstall", "Ensure node version")([
11675
- // github actions overrides HOME in container jobs, so also look
11676
- // for nvm where the catladder images install it (/root/.nvm)
11677
- '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',
11678
- "if command -v nvm &> /dev/null && [ -f ./.nvmrc ]; then nvm install; fi",
11679
- ]);
11680
- exports.ensureNodeVersion = ensureNodeVersion;
11681
- const getYarnInstall = async (context, options) => {
11682
- const postInstall = context.type !== "workspace" &&
11683
- context.build.type !== "disabled" &&
11684
- "postInstall" in context.build.config
11685
- ? context.build.config.postInstall
11686
- : null;
11687
- return [
11688
- ...(0, exports.ensureNodeVersion)(context),
11689
- ...(0, gitlab_1.collapseableSection)("yarninstall", "Yarn install")([await getYarnInstallCommand(context)]),
11690
- ...(postInstall && !(options === null || options === void 0 ? void 0 : options.noCustomPostInstall)
11691
- ? (0, gitlab_1.collapseableSection)("postinstall", "Custom post install")((0, utils_1.ensureArray)(postInstall))
11692
- : []),
11693
- ];
11694
- };
11695
- exports.getYarnInstall = getYarnInstall;
11696
- const DOCKER_COPY_FILES = `COPY --chown=node:node $APP_DIR .`;
11697
- const getDockerAppCopyAndBuildScript = async (context) => {
11698
- var _a, _b, _c;
11699
- const packageManagerInfo = await context.packageManagerInfo;
11700
- if (packageManagerInfo.isClassic) {
11701
- return new bash_1.BashExpression(`
11702
- RUN ${YARN_INSTALL_CLASSIC} --production --ignore-scripts
11703
- ${DOCKER_COPY_FILES}
11704
- RUN ${YARN_INSTALL_CLASSIC} --production
11705
- `.trim());
11706
- }
11707
- const yarnRebuildEnabledDefault = context.build.type === "fromWorkspace"
11708
- ? ((_b = (_a = context.build.workspaceBuildConfig.dockerDefaults) === null || _a === void 0 ? void 0 : _a.yarnRebuildEnabled) !== null && _b !== void 0 ? _b : true)
11709
- : true;
11710
- const yarnRebuildEnabled = "docker" in context.build.config &&
11711
- context.build.config.docker &&
11712
- "yarnRebuildEnabled" in context.build.config.docker
11713
- ? ((_c = context.build.config.docker.yarnRebuildEnabled) !== null && _c !== void 0 ? _c : yarnRebuildEnabledDefault)
11714
- : yarnRebuildEnabledDefault;
11715
- // yarn >= 4 ships with build in plugins, see https://github.com/yarnpkg/berry/pull/4253
11716
- // trying to import those fail on this version
11717
- const doesNotShipWithBuiltInPlugins = ["2", "3"].some((v) => packageManagerInfo.version.startsWith(v));
11718
- const maybeAddWorkspaceToolsCommand = doesNotShipWithBuiltInPlugins
11719
- ? "RUN yarn plugin import workspace-tools"
11720
- : "";
11721
- // copy first everything and then install
11722
- // rebuild first does not work as it will run postinstall and that might require files in the app
11723
- return new bash_1.BashExpression(`
11724
- ENV YARN_ENABLE_INLINE_BUILDS=1
11725
- ${DOCKER_COPY_FILES}
11726
- ${maybeAddWorkspaceToolsCommand}
11727
- RUN ${YARN_BERRY_PROD_INSTALL}
11728
- ${yarnRebuildEnabled ? `RUN ${YARN_BERRY_PROD_REBUILD}` : ""}
11729
-
11730
- `.trim());
11731
- };
11732
- exports.getDockerAppCopyAndBuildScript = getDockerAppCopyAndBuildScript;
11733
- //# sourceMappingURL=yarn.js.map
11734
-
11735
- /***/ }),
11736
-
11737
11892
  /***/ 50663:
11738
11893
  /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
11739
11894
 
@@ -12199,6 +12354,7 @@ const createComponentContext = async (ctx) => {
12199
12354
  throw new Error("componentName may only contain lower case letters, numbers and -");
12200
12355
  }
12201
12356
  const packageManagerInfoPromise = (0, packageManager_1.getPackageManagerInfoForComponent)(ctx.config, ctx.componentName);
12357
+ const { type: packageManagerType } = await packageManagerInfoPromise;
12202
12358
  const envContext = (0, getEnvironmentContext_1.getEnvironmentContext)(ctx);
12203
12359
  const componentConfigWithoutDefaults = envContext.envConfigRaw;
12204
12360
  const resolvedBuildType = componentConfigWithoutDefaults.build === false
@@ -12212,12 +12368,12 @@ const createComponentContext = async (ctx) => {
12212
12368
  const defaults = componentConfigWithoutDefaults.deploy
12213
12369
  ? {
12214
12370
  build: resolvedBuildType &&
12215
- build_1.BUILD_TYPES[resolvedBuildType].defaults(envContext),
12371
+ build_1.BUILD_TYPES[resolvedBuildType].defaults(envContext, packageManagerType),
12216
12372
  deploy: deploy_1.DEPLOY_TYPES[componentConfigWithoutDefaults.deploy.type].defaults(envContext),
12217
12373
  }
12218
12374
  : {
12219
12375
  build: resolvedBuildType &&
12220
- build_1.BUILD_TYPES[resolvedBuildType].defaults(envContext),
12376
+ build_1.BUILD_TYPES[resolvedBuildType].defaults(envContext, packageManagerType),
12221
12377
  deploy: {},
12222
12378
  };
12223
12379
  const componentConfig = (0, utils_1.mergeWithMergingArrays)(defaults, componentConfigWithoutDefaults);
@@ -12314,7 +12470,8 @@ async function createWorkspaceContext({ env, components, workspaceName, config,
12314
12470
  if (!workspaceConfigRaw) {
12315
12471
  throw new Error(`Workspace ${workspaceName} not found in config`);
12316
12472
  }
12317
- const defaults = __1.WORKSPACE_BUILD_TYPES[workspaceConfigRaw.type].defaults();
12473
+ const packageManagerInfo = (0, packageManager_1.getPackageManagerInfoBase)(config);
12474
+ const defaults = __1.WORKSPACE_BUILD_TYPES[workspaceConfigRaw.type].defaults((await packageManagerInfo).type);
12318
12475
  const workspaceConfig = (0, utils_1.mergeWithMergingArrays)(defaults, workspaceConfigRaw);
12319
12476
  return {
12320
12477
  name: workspaceName,
@@ -12325,7 +12482,7 @@ async function createWorkspaceContext({ env, components, workspaceName, config,
12325
12482
  env,
12326
12483
  components,
12327
12484
  fullConfig: config,
12328
- packageManagerInfo: (0, packageManager_1.getPackageManagerInfoBase)(),
12485
+ packageManagerInfo,
12329
12486
  build: {
12330
12487
  type: "workspace",
12331
12488
  dir: (_b = workspaceConfig.dir) !== null && _b !== void 0 ? _b : ".",
@@ -12817,7 +12974,7 @@ exports.makeSecretEnvVarMapping = makeSecretEnvVarMapping;
12817
12974
  "use strict";
12818
12975
 
12819
12976
  Object.defineProperty(exports, "__esModule", ({ value: true }));
12820
- exports.computeCustomImageHash = void 0;
12977
+ exports.computeInlineImageHash = exports.computeCustomImageHash = void 0;
12821
12978
  const crypto_1 = __nccwpck_require__(76982);
12822
12979
  const fs_1 = __nccwpck_require__(79896);
12823
12980
  const path_1 = __nccwpck_require__(16928);
@@ -12838,6 +12995,29 @@ function listFilesRecursive(dir) {
12838
12995
  })
12839
12996
  .sort();
12840
12997
  }
12998
+ /**
12999
+ * the parts every image definition hashes on top of its content:
13000
+ * files outside the definition, and the build args
13001
+ */
13002
+ function hashExtras(hash, config) {
13003
+ const watchedPaths = [];
13004
+ // Hash extra paths (for files outside the dir)
13005
+ if (config.hashExtraPaths) {
13006
+ // Extra paths are literal file paths (not globs) for simplicity
13007
+ const extraFiles = [...config.hashExtraPaths].sort();
13008
+ for (const file of extraFiles) {
13009
+ hash.update(file);
13010
+ hash.update((0, fs_1.readFileSync)(file));
13011
+ }
13012
+ watchedPaths.push(...config.hashExtraPaths);
13013
+ }
13014
+ // Hash build args (sorted keys for determinism)
13015
+ if (config.buildArgs) {
13016
+ const sorted = Object.entries(config.buildArgs).sort(([a], [b]) => a.localeCompare(b));
13017
+ hash.update(JSON.stringify(sorted));
13018
+ }
13019
+ return watchedPaths;
13020
+ }
12841
13021
  function computeCustomImageHash(config) {
12842
13022
  var _a;
12843
13023
  const hash = (0, crypto_1.createHash)("sha256");
@@ -12858,27 +13038,29 @@ function computeCustomImageHash(config) {
12858
13038
  }
12859
13039
  watchedPaths.push(`${extraDir}/**/*`);
12860
13040
  }
12861
- // Hash extra paths (for files outside the dir)
12862
- if (config.hashExtraPaths) {
12863
- // Extra paths are literal file paths (not globs) for simplicity
12864
- const extraFiles = [...config.hashExtraPaths].sort();
12865
- for (const file of extraFiles) {
12866
- hash.update(file);
12867
- hash.update((0, fs_1.readFileSync)(file));
12868
- }
12869
- watchedPaths.push(...config.hashExtraPaths);
12870
- }
12871
- // Hash build args (sorted keys for determinism)
12872
- if (config.buildArgs) {
12873
- const sorted = Object.entries(config.buildArgs).sort(([a], [b]) => a.localeCompare(b));
12874
- hash.update(JSON.stringify(sorted));
12875
- }
13041
+ watchedPaths.push(...hashExtras(hash, config));
12876
13042
  return {
12877
13043
  hash: hash.digest("hex").slice(0, 12),
12878
13044
  watchedPaths,
12879
13045
  };
12880
13046
  }
12881
13047
  exports.computeCustomImageHash = computeCustomImageHash;
13048
+ /**
13049
+ * the hash of an image defined by an inline Dockerfile: its content
13050
+ * stands in for the definition dir. The build context is deliberately
13051
+ * NOT hashed (it may be the whole repository) — `hashExtraPaths` is how
13052
+ * context files opt into the hash.
13053
+ */
13054
+ function computeInlineImageHash(config) {
13055
+ const hash = (0, crypto_1.createHash)("sha256");
13056
+ hash.update(config.dockerfileContent);
13057
+ const watchedPaths = hashExtras(hash, config);
13058
+ return {
13059
+ hash: hash.digest("hex").slice(0, 12),
13060
+ watchedPaths,
13061
+ };
13062
+ }
13063
+ exports.computeInlineImageHash = computeInlineImageHash;
12882
13064
  //# sourceMappingURL=hash.js.map
12883
13065
 
12884
13066
  /***/ }),
@@ -12889,7 +13071,7 @@ exports.computeCustomImageHash = computeCustomImageHash;
12889
13071
  "use strict";
12890
13072
 
12891
13073
  Object.defineProperty(exports, "__esModule", ({ value: true }));
12892
- exports.JobImagesPlan = exports.GENERATED_IMAGES_FOLDER = void 0;
13074
+ exports.JobImagesPlan = exports.PROJECT_IMAGES_FOLDER = exports.GENERATED_IMAGES_FOLDER = void 0;
12893
13075
  const fs_1 = __nccwpck_require__(79896);
12894
13076
  const path_1 = __nccwpck_require__(16928);
12895
13077
  const ciVariables_1 = __nccwpck_require__(72700);
@@ -12897,6 +13079,7 @@ const docker_1 = __nccwpck_require__(83777);
12897
13079
  const runner_1 = __nccwpck_require__(71065);
12898
13080
  const gitlab_1 = __nccwpck_require__(37393);
12899
13081
  const hash_1 = __nccwpck_require__(34092);
13082
+ const projectImages_1 = __nccwpck_require__(55537);
12900
13083
  const shippedImages_1 = __nccwpck_require__(28687);
12901
13084
  exports.GENERATED_IMAGES_FOLDER = ".catladder-generated/images";
12902
13085
  /**
@@ -12904,7 +13087,44 @@ exports.GENERATED_IMAGES_FOLDER = ".catladder-generated/images";
12904
13087
  * catladder image, so building images never depends on one (bootstrap)
12905
13088
  */
12906
13089
  const BUILDER_IMAGE = "docker.io/docker:29.5.1";
12907
- const ensureJobName = (name) => `🐳 job image ${name}`;
13090
+ /**
13091
+ * every planned image is consumed the same way: its url, plus an
13092
+ * optional dependency on its build job
13093
+ */
13094
+ const toResolvedJobImage = ({ imageRef, jobName, }) => ({
13095
+ image: imageRef,
13096
+ fromRepoRegistry: true,
13097
+ need: {
13098
+ job: jobName,
13099
+ artifacts: false,
13100
+ optional: true,
13101
+ global: true,
13102
+ },
13103
+ });
13104
+ /**
13105
+ * materializes an image definition directory into the generated files
13106
+ * (used for the definitions catladder ships)
13107
+ */
13108
+ const materializeDir = (sourceDir, targetDir) => listFilesRecursive(sourceDir).map((file) => ({
13109
+ path: (0, path_1.join)(targetDir, file),
13110
+ content: (0, fs_1.readFileSync)((0, path_1.join)(sourceDir, file), "utf-8"),
13111
+ }));
13112
+ // built-in (catladder-shipped) images carry the catladder marker in
13113
+ // their job name; project-declared images get the short plain name
13114
+ const ensureJobName = (name) => `🐳 catladder image ${name}`;
13115
+ const projectEnsureJobName = (name) => `🐳 image ${name}`;
13116
+ /**
13117
+ * the config file whose content feeds the project image hashes
13118
+ * (`buildArgs`, `hashExtraPaths`): the gitlab change detection has to
13119
+ * watch it, because a config-only change alters the image tag without
13120
+ * touching the image dir
13121
+ */
13122
+ const CONFIG_FILE = "catladder.ts";
13123
+ /**
13124
+ * where inline project Dockerfiles are materialized — a subfolder, so a
13125
+ * project image can carry the same name as a shipped one
13126
+ */
13127
+ exports.PROJECT_IMAGES_FOLDER = `${exports.GENERATED_IMAGES_FOLDER}/project`;
12908
13128
  /**
12909
13129
  * plans the catladder job images of one backend run: resolves image
12910
13130
  * references, collects the image build jobs, and the image definitions
@@ -12915,33 +13135,30 @@ const ensureJobName = (name) => `🐳 job image ${name}`;
12915
13135
  * Reference-driven: only images actually used by a job are built.
12916
13136
  */
12917
13137
  class JobImagesPlan {
12918
- constructor(pipelineType) {
13138
+ constructor(pipelineType, projectImages = {}) {
12919
13139
  this.pipelineType = pipelineType;
13140
+ this.projectImages = projectImages;
12920
13141
  this.used = new Map();
13142
+ this.usedProject = new Map();
12921
13143
  }
12922
13144
  /**
12923
13145
  * resolves a job image (marker or concrete) to a concrete image url
12924
13146
  * plus the build job dependency
12925
13147
  */
12926
13148
  resolve(image) {
12927
- if (!(0, runner_1.isCatladderImageRef)(image)) {
12928
- return { image };
13149
+ if ((0, runner_1.isCatladderImageRef)(image)) {
13150
+ return this.resolveRef(image);
13151
+ }
13152
+ if ((0, projectImages_1.isProjectImageRef)(image)) {
13153
+ return this.resolveProjectRef(image);
12929
13154
  }
12930
- return this.resolveRef(image);
13155
+ return { image };
12931
13156
  }
12932
13157
  resolveRef(ref) {
12933
- const name = ref.catladderImage;
12934
- const { hash } = this.use(name);
12935
- return {
12936
- image: `${this.registryImageRef()}/catladder/${name}:${hash}`,
12937
- fromRepoRegistry: true,
12938
- need: {
12939
- job: ensureJobName(name),
12940
- artifacts: false,
12941
- optional: true,
12942
- global: true,
12943
- },
12944
- };
13158
+ return toResolvedJobImage(this.use(ref.catladderImage));
13159
+ }
13160
+ resolveProjectRef(ref) {
13161
+ return toResolvedJobImage(this.useProject(ref.image));
12945
13162
  }
12946
13163
  /**
12947
13164
  * the registry image prefix. On github, container images can't use
@@ -12952,6 +13169,85 @@ class JobImagesPlan {
12952
13169
  ? "ghcr.io/${{ github.repository }}"
12953
13170
  : `${(0, ciVariables_1.getCiVariable)({ pipelineType: this.pipelineType }, "registryImage")}`;
12954
13171
  }
13172
+ useProject(name) {
13173
+ const existing = this.usedProject.get(name);
13174
+ if (existing) {
13175
+ return existing;
13176
+ }
13177
+ const imageConfig = this.projectImages[name];
13178
+ if (!imageConfig) {
13179
+ const declared = Object.keys(this.projectImages);
13180
+ throw new Error(`unknown job image "${name}" — ${declared.length > 0
13181
+ ? `images declared in config.images: ${declared.join(", ")}`
13182
+ : "no images are declared in config.images"}`);
13183
+ }
13184
+ const source = this.planProjectSource(name, imageConfig);
13185
+ const planned = {
13186
+ ...source,
13187
+ jobName: projectEnsureJobName(name),
13188
+ buildArgs: imageConfig.buildArgs,
13189
+ // `job-images/` keeps the project's job images apart from its
13190
+ // deployable component images (registry root) and build caches
13191
+ imageRef: `${this.registryImageRef()}/job-images/${name}:${source.hash}`,
13192
+ };
13193
+ this.usedProject.set(name, planned);
13194
+ return planned;
13195
+ }
13196
+ /**
13197
+ * the source-dependent half of a project image: an inline Dockerfile
13198
+ * is materialized into the generated files and hashed by its content,
13199
+ * a directory is hashed and watched in place
13200
+ */
13201
+ planProjectSource(name, imageConfig) {
13202
+ var _a, _b;
13203
+ if (imageConfig.dockerfile !== undefined) {
13204
+ const content = toDockerfileContent(imageConfig.dockerfile);
13205
+ const dockerfilePath = `${exports.PROJECT_IMAGES_FOLDER}/${name}/Dockerfile`;
13206
+ const { hash, watchedPaths } = (0, hash_1.computeInlineImageHash)({
13207
+ dockerfileContent: content,
13208
+ hashExtraPaths: imageConfig.hashExtraPaths,
13209
+ buildArgs: imageConfig.buildArgs,
13210
+ });
13211
+ return {
13212
+ hash,
13213
+ dockerfilePath,
13214
+ // an inline definition carries no directory of its own — the
13215
+ // repository root is the sensible default context
13216
+ contextDir: (_a = imageConfig.context) !== null && _a !== void 0 ? _a : ".",
13217
+ watchedPaths: [
13218
+ `${exports.PROJECT_IMAGES_FOLDER}/${name}/**/*`,
13219
+ ...watchedPaths,
13220
+ CONFIG_FILE,
13221
+ ],
13222
+ files: [{ path: dockerfilePath, content }],
13223
+ };
13224
+ }
13225
+ const dir = imageConfig.dir;
13226
+ // fail at generation time with the offending image named: an
13227
+ // unreadable dir would otherwise surface as a bare fs ENOENT, and a
13228
+ // missing Dockerfile only as a docker build failure in CI
13229
+ if (!(0, fs_1.existsSync)(dir)) {
13230
+ throw new Error(`job image "${name}": the directory "${dir}" does not exist (config.images.${name}.dir, relative to the repository root)`);
13231
+ }
13232
+ if (!(0, fs_1.existsSync)((0, path_1.join)(dir, "Dockerfile"))) {
13233
+ throw new Error(`job image "${name}": no Dockerfile in "${dir}" (config.images.${name}.dir)`);
13234
+ }
13235
+ const { hash, watchedPaths } = (0, hash_1.computeCustomImageHash)({
13236
+ dir,
13237
+ hashExtraPaths: imageConfig.hashExtraPaths,
13238
+ buildArgs: imageConfig.buildArgs,
13239
+ });
13240
+ return {
13241
+ hash,
13242
+ dockerfilePath: `${dir}/Dockerfile`,
13243
+ contextDir: (_b = imageConfig.context) !== null && _b !== void 0 ? _b : dir,
13244
+ // the dir is committed in the project — watched in place, nothing
13245
+ // is materialized. The config file is watched too: buildArgs /
13246
+ // hashExtraPaths changes alter the tag without touching the dir
13247
+ watchedPaths: [...watchedPaths, CONFIG_FILE],
13248
+ files: [],
13249
+ };
13250
+ }
12955
13251
  use(name) {
12956
13252
  var _a;
12957
13253
  const existing = this.used.get(name);
@@ -12966,27 +13262,43 @@ class JobImagesPlan {
12966
13262
  dir: (0, shippedImages_1.getShippedImageDir)(name),
12967
13263
  extraDirs: dependencies.map((dependency) => (0, shippedImages_1.getShippedImageDir)(dependency)),
12968
13264
  });
12969
- const entry = { hash };
12970
- this.used.set(name, entry);
12971
- return entry;
13265
+ const targetDir = `${exports.GENERATED_IMAGES_FOLDER}/${name}`;
13266
+ const planned = {
13267
+ hash,
13268
+ jobName: ensureJobName(name),
13269
+ imageRef: `${this.registryImageRef()}/catladder/${name}:${hash}`,
13270
+ dockerfilePath: `${targetDir}/Dockerfile`,
13271
+ // the jobs family INCLUDEs sibling images, so it builds from the
13272
+ // images root; the others from their own dir
13273
+ contextDir: shippedImages_1.RUNNER_IMAGE_BUILD_CONTEXT[name] === "root"
13274
+ ? exports.GENERATED_IMAGES_FOLDER
13275
+ : targetDir,
13276
+ watchedPaths: [name, ...dependencies].map((dir) => `${exports.GENERATED_IMAGES_FOLDER}/${dir}/**/*`),
13277
+ // pipelines build from committed, reviewable files (and gitlab's
13278
+ // rules:changes can watch them)
13279
+ files: materializeDir((0, shippedImages_1.getShippedImageDir)(name), targetDir),
13280
+ };
13281
+ this.used.set(name, planned);
13282
+ return planned;
12972
13283
  }
12973
13284
  /**
12974
13285
  * the image build jobs for all used images
12975
13286
  */
12976
13287
  getEnsureJobs() {
12977
- return [...this.used.entries()].map(([name, { hash }]) => this.createEnsureJob(name, hash));
13288
+ return [...this.used.values(), ...this.usedProject.values()].map((planned) => this.createImageBuildJob(planned));
12978
13289
  }
12979
- createEnsureJob(name, hash) {
12980
- var _a;
13290
+ createImageBuildJob({ jobName, imageRef, watchedPaths, dockerfilePath, contextDir, buildArgs, }) {
13291
+ const buildArgFlags = Object.entries(buildArgs !== null && buildArgs !== void 0 ? buildArgs : {})
13292
+ .map(([key, value]) => ` --build-arg '${key}=${value}'`)
13293
+ .join("");
13294
+ const buildCommand = `DOCKER_BUILDKIT=1 docker build -t ${imageRef}${buildArgFlags} -f ${dockerfilePath} ${contextDir}`;
12981
13295
  const ctx = { pipelineType: this.pipelineType };
12982
13296
  const registryUser = (0, ciVariables_1.getCiVariable)(ctx, "registryUser");
12983
13297
  const jobToken = (0, ciVariables_1.getCiVariable)(ctx, "jobToken");
12984
13298
  const registry = (0, ciVariables_1.getCiVariable)(ctx, "registry");
12985
- const imageRef = `${this.registryImageRef()}/catladder/${name}:${hash}`;
12986
- const watchedDirs = [name, ...((_a = shippedImages_1.RUNNER_IMAGE_DEPENDENCIES[name]) !== null && _a !== void 0 ? _a : [])];
12987
13299
  const { services, runnerVariables } = (0, docker_1.getDockerJobBaseProps)();
12988
13300
  return {
12989
- name: ensureJobName(name),
13301
+ name: jobName,
12990
13302
  stage: "setup",
12991
13303
  image: BUILDER_IMAGE,
12992
13304
  services,
@@ -12996,7 +13308,9 @@ class JobImagesPlan {
12996
13308
  // no equivalent and always runs (the existence check is fast)
12997
13309
  rules: [
12998
13310
  {
12999
- changes: watchedDirs.map((dir) => `${exports.GENERATED_IMAGES_FOLDER}/${dir}/**/*`),
13311
+ // a fresh array per job: the yaml serializer anchors repeated
13312
+ // objects, and a shared reference would reshuffle anchors
13313
+ changes: [...watchedPaths],
13000
13314
  },
13001
13315
  ],
13002
13316
  variables: {},
@@ -13010,31 +13324,33 @@ class JobImagesPlan {
13010
13324
  ` exit 0`,
13011
13325
  `fi`,
13012
13326
  ]),
13013
- ...(0, gitlab_1.collapseableSection)("docker-build", "Building image")([
13014
- `DOCKER_BUILDKIT=1 docker build -t ${imageRef} -f ${exports.GENERATED_IMAGES_FOLDER}/${name}/Dockerfile ${shippedImages_1.RUNNER_IMAGE_BUILD_CONTEXT[name] === "root"
13015
- ? exports.GENERATED_IMAGES_FOLDER
13016
- : `${exports.GENERATED_IMAGES_FOLDER}/${name}`}`,
13017
- ]),
13327
+ ...(0, gitlab_1.collapseableSection)("docker-build", "Building image")([buildCommand]),
13018
13328
  ...(0, gitlab_1.collapseableSection)("docker-push", "Pushing image")([`docker push ${imageRef}`]),
13019
13329
  ],
13020
13330
  };
13021
13331
  }
13022
13332
  /**
13023
- * the image definitions of all used images, materialized into the
13024
- * generated files (so pipelines build from committed, reviewable
13025
- * files and gitlab's rules:changes can watch them)
13333
+ * the image definitions to materialize into the generated files (so
13334
+ * pipelines build from committed, reviewable files and gitlab's
13335
+ * rules:changes can watch them): the definitions catladder ships and
13336
+ * the project's inline Dockerfiles. A project image directory is
13337
+ * already committed and contributes nothing.
13026
13338
  */
13027
13339
  getGeneratedFiles() {
13028
- return [...this.used.keys()].flatMap((name) => {
13029
- const dir = (0, shippedImages_1.getShippedImageDir)(name);
13030
- return listFilesRecursive(dir).map((file) => ({
13031
- path: (0, path_1.join)(exports.GENERATED_IMAGES_FOLDER, name, file),
13032
- content: (0, fs_1.readFileSync)((0, path_1.join)(dir, file), "utf-8"),
13033
- }));
13034
- });
13340
+ return [...this.used.values(), ...this.usedProject.values()].flatMap(({ files }) => files);
13035
13341
  }
13036
13342
  }
13037
13343
  exports.JobImagesPlan = JobImagesPlan;
13344
+ /**
13345
+ * an inline Dockerfile is written as given — as one string, or as lines
13346
+ * joined with newlines (always newline-terminated)
13347
+ */
13348
+ const toDockerfileContent = (dockerfile) => {
13349
+ const content = Array.isArray(dockerfile)
13350
+ ? dockerfile.join("\n")
13351
+ : dockerfile;
13352
+ return content.endsWith("\n") ? content : `${content}\n`;
13353
+ };
13038
13354
  const IGNORED_FILES = new Set([".DS_Store", "Thumbs.db"]);
13039
13355
  const listFilesRecursive = (dir) => (0, fs_1.readdirSync)(dir, { recursive: true, encoding: "utf-8" })
13040
13356
  .filter((entry) => {
@@ -13048,6 +13364,22 @@ const listFilesRecursive = (dir) => (0, fs_1.readdirSync)(dir, { recursive: true
13048
13364
 
13049
13365
  /***/ }),
13050
13366
 
13367
+ /***/ 55537:
13368
+ /***/ ((__unused_webpack_module, exports) => {
13369
+
13370
+ "use strict";
13371
+
13372
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
13373
+ exports.isProjectImageRef = void 0;
13374
+ const isProjectImageRef = (value) => typeof value === "object" &&
13375
+ value !== null &&
13376
+ "image" in value &&
13377
+ typeof value.image === "string";
13378
+ exports.isProjectImageRef = isProjectImageRef;
13379
+ //# sourceMappingURL=projectImages.js.map
13380
+
13381
+ /***/ }),
13382
+
13051
13383
  /***/ 28687:
13052
13384
  /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
13053
13385
 
@@ -14799,19 +15131,18 @@ exports.getFullDbName = getFullDbName;
14799
15131
  Object.defineProperty(exports, "__esModule", ({ value: true }));
14800
15132
  exports.createCustomDeployJobs = void 0;
14801
15133
  const getAllCacheConfigsFromConfig_1 = __nccwpck_require__(19034);
14802
- const yarn_1 = __nccwpck_require__(59874);
15134
+ const packageManagerInstall_1 = __nccwpck_require__(18600);
14803
15135
  const runner_1 = __nccwpck_require__(71065);
14804
15136
  const base_1 = __nccwpck_require__(93664);
14805
15137
  const types_1 = __nccwpck_require__(71446);
14806
15138
  const createCustomDeployJobs = async (context) => {
14807
- var _a, _b, _c;
15139
+ var _a, _b, _c, _d;
14808
15140
  const deployConfig = (_a = context.deploy) === null || _a === void 0 ? void 0 : _a.config;
14809
15141
  if (!(0, types_1.isOfDeployType)(deployConfig, "custom")) {
14810
15142
  // should not happen
14811
15143
  throw new Error("deploy config is not custom");
14812
15144
  }
14813
- // FIXME: custom deploy currently assumes yarn-based project
14814
- const yarnInstall = await (0, yarn_1.getYarnInstall)(context, {
15145
+ const packageManagerInstall = await (0, packageManagerInstall_1.getPackageManagerInstall)(context, {
14815
15146
  noCustomPostInstall: true,
14816
15147
  });
14817
15148
  const result = (0, base_1.createDeployementJobs)(context, {
@@ -14823,14 +15154,16 @@ const createCustomDeployJobs = async (context) => {
14823
15154
  : undefined,
14824
15155
  script: [
14825
15156
  `cd ${context.build.dir}`,
14826
- ...(deployConfig.requiresYarnInstall ? yarnInstall : []),
15157
+ ...(((_c = deployConfig.requiresInstall) !== null && _c !== void 0 ? _c : deployConfig.requiresYarnInstall)
15158
+ ? packageManagerInstall
15159
+ : []),
14827
15160
  ...deployConfig.script,
14828
15161
  ],
14829
15162
  variables: {},
14830
15163
  },
14831
15164
  stop: deployConfig.stopScript
14832
15165
  ? {
14833
- image: (_c = deployConfig.jobImage) !== null && _c !== void 0 ? _c : (0, runner_1.getRunnerImage)("jobs-default"),
15166
+ image: (_d = deployConfig.jobImage) !== null && _d !== void 0 ? _d : (0, runner_1.getRunnerImage)("jobs-default"),
14834
15167
  script: [...deployConfig.stopScript],
14835
15168
  variables: {},
14836
15169
  }
@@ -15506,12 +15839,12 @@ exports.NPM_PACKAGE_DEPLOY_TYPE = {
15506
15839
  Object.defineProperty(exports, "__esModule", ({ value: true }));
15507
15840
  exports.createPagesDeployJobs = void 0;
15508
15841
  const getAllCacheConfigsFromConfig_1 = __nccwpck_require__(19034);
15509
- const yarn_1 = __nccwpck_require__(59874);
15842
+ const packageManagerInstall_1 = __nccwpck_require__(18600);
15510
15843
  const runner_1 = __nccwpck_require__(71065);
15511
15844
  const base_1 = __nccwpck_require__(93664);
15512
15845
  const types_1 = __nccwpck_require__(71446);
15513
15846
  const createPagesDeployJobs = async (context) => {
15514
- var _a, _b, _c;
15847
+ var _a, _b, _c, _d;
15515
15848
  const deployConfig = (_a = context.deploy) === null || _a === void 0 ? void 0 : _a.config;
15516
15849
  if (!(0, types_1.isOfDeployType)(deployConfig, "pages")) {
15517
15850
  // should not happen
@@ -15526,7 +15859,7 @@ const createPagesDeployJobs = async (context) => {
15526
15859
  // parallel deployments) — every merge request gets a site preview
15527
15860
  const pathPrefix = context.environment.envType === "review" ? "mr-$CI_MERGE_REQUEST_IID" : "";
15528
15861
  const publishDir = (_b = deployConfig.publishDir) !== null && _b !== void 0 ? _b : "public";
15529
- const yarnInstall = await (0, yarn_1.getYarnInstall)(context, {
15862
+ const packageManagerInstall = await (0, packageManagerInstall_1.getPackageManagerInstall)(context, {
15530
15863
  noCustomPostInstall: true,
15531
15864
  });
15532
15865
  return (0, base_1.createDeployementJobs)(context, {
@@ -15537,7 +15870,9 @@ const createPagesDeployJobs = async (context) => {
15537
15870
  pages: { path_prefix: pathPrefix },
15538
15871
  script: [
15539
15872
  `cd ${context.build.dir}`,
15540
- ...(deployConfig.requiresYarnInstall ? yarnInstall : []),
15873
+ ...(((_d = deployConfig.requiresInstall) !== null && _d !== void 0 ? _d : deployConfig.requiresYarnInstall)
15874
+ ? packageManagerInstall
15875
+ : []),
15541
15876
  ...deployConfig.script,
15542
15877
  // the gitlab environment url should point at the published site
15543
15878
  // (the base deploy job reports $ROOT_URL as environment url)
@@ -15758,6 +16093,8 @@ __exportStar(__nccwpck_require__(68906), exports);
15758
16093
  __exportStar(__nccwpck_require__(23040), exports);
15759
16094
  __exportStar(__nccwpck_require__(35086), exports);
15760
16095
  __exportStar(__nccwpck_require__(71065), exports);
16096
+ __exportStar(__nccwpck_require__(55537), exports);
16097
+ __exportStar(__nccwpck_require__(47864), exports);
15761
16098
  __exportStar(__nccwpck_require__(80769), exports);
15762
16099
  __exportStar(__nccwpck_require__(7732), exports);
15763
16100
  __exportStar(__nccwpck_require__(66526), exports);
@@ -16414,6 +16751,89 @@ exports.createJobsForWorkspace = createJobsForWorkspace;
16414
16751
 
16415
16752
  /***/ }),
16416
16753
 
16754
+ /***/ 7633:
16755
+ /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
16756
+
16757
+ "use strict";
16758
+
16759
+ var __importDefault = (this && this.__importDefault) || function (mod) {
16760
+ return (mod && mod.__esModule) ? mod : { "default": mod };
16761
+ };
16762
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
16763
+ exports.detectPackageManager = void 0;
16764
+ const child_process_promise_1 = __nccwpck_require__(42242);
16765
+ const fs_1 = __nccwpck_require__(79896);
16766
+ const promises_1 = __nccwpck_require__(91943);
16767
+ const path_1 = __nccwpck_require__(16928);
16768
+ const memoizee_1 = __importDefault(__nccwpck_require__(14199));
16769
+ const readPackageManagerField = async (dir) => {
16770
+ try {
16771
+ const pkg = JSON.parse(await (0, promises_1.readFile)((0, path_1.join)(dir, "package.json"), "utf-8"));
16772
+ const match = /^(yarn|pnpm)@(.+)$/.exec(pkg.packageManager);
16773
+ if (!match)
16774
+ return null;
16775
+ return { type: match[1], version: match[2] };
16776
+ }
16777
+ catch (_a) {
16778
+ return null;
16779
+ }
16780
+ };
16781
+ const detectByLockfile = (dir) => {
16782
+ if ((0, fs_1.existsSync)((0, path_1.join)(dir, "pnpm-lock.yaml")))
16783
+ return "pnpm";
16784
+ if ((0, fs_1.existsSync)((0, path_1.join)(dir, "yarn.lock")))
16785
+ return "yarn";
16786
+ return null;
16787
+ };
16788
+ const getGitRoot = async () => {
16789
+ try {
16790
+ return (await (0, child_process_promise_1.exec)("git rev-parse --show-toplevel")).stdout.trim();
16791
+ }
16792
+ catch (_a) {
16793
+ return null;
16794
+ }
16795
+ };
16796
+ const getInstalledVersion = async (type) => {
16797
+ try {
16798
+ return (await (0, child_process_promise_1.exec)(`${type} --version`)).stdout.trim();
16799
+ }
16800
+ catch (_a) {
16801
+ return "";
16802
+ }
16803
+ };
16804
+ /**
16805
+ * detect which package manager the project uses (and its version).
16806
+ *
16807
+ * Order: the `packageManager` field in package.json (cwd, then git root)
16808
+ * wins, then the lockfile present (pnpm-lock.yaml → pnpm, yarn.lock →
16809
+ * yarn), then falling back to yarn (the historical default).
16810
+ *
16811
+ * An `explicitType` (from `packageManager` in catladder.ts) overrides the
16812
+ * detected type; the version is still taken from the `packageManager`
16813
+ * field when it pins the same manager, otherwise from the installed CLI.
16814
+ */
16815
+ exports.detectPackageManager = (0, memoizee_1.default)(async (explicitType) => {
16816
+ var _a, _b;
16817
+ const roots = [process.cwd()];
16818
+ const gitRoot = await getGitRoot();
16819
+ if (gitRoot && gitRoot !== process.cwd())
16820
+ roots.push(gitRoot);
16821
+ let fromField = null;
16822
+ for (const root of roots) {
16823
+ fromField = await readPackageManagerField(root);
16824
+ if (fromField)
16825
+ break;
16826
+ }
16827
+ 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";
16828
+ const version = (fromField === null || fromField === void 0 ? void 0 : fromField.type) === detectedType
16829
+ ? fromField.version
16830
+ : await getInstalledVersion(detectedType);
16831
+ return { type: detectedType, version };
16832
+ }, { promise: true });
16833
+ //# sourceMappingURL=detectPackageManager.js.map
16834
+
16835
+ /***/ }),
16836
+
16417
16837
  /***/ 43249:
16418
16838
  /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
16419
16839
 
@@ -16521,12 +16941,23 @@ exports.getPackageManagerInfoBase = exports.getPackageManagerInfoForComponent =
16521
16941
  const fs_1 = __nccwpck_require__(79896);
16522
16942
  const path_1 = __nccwpck_require__(16928);
16523
16943
  const path_equal_1 = __nccwpck_require__(43882);
16944
+ const detectPackageManager_1 = __nccwpck_require__(7633);
16945
+ const pnpmUtils_1 = __nccwpck_require__(3497);
16524
16946
  const yarnUtils_1 = __nccwpck_require__(94191);
16525
16947
  const memoizee_1 = __importDefault(__nccwpck_require__(14199));
16948
+ const PACKAGE_MANAGER_FILES = {
16949
+ yarn: {
16950
+ lockFile: "yarn.lock",
16951
+ configFiles: [".yarnrc", ".yarnrc.yml", ".npmrc", ".yarn"], // ".yarn" is yarn 2 folder
16952
+ },
16953
+ pnpm: {
16954
+ lockFile: "pnpm-lock.yaml",
16955
+ configFiles: ["pnpm-workspace.yaml", ".npmrc", ".pnpmfile.cjs"],
16956
+ },
16957
+ };
16526
16958
  const getPackageManagerInfoForComponent = async (config, componentName) => {
16527
- const baseInfo = await (0, exports.getPackageManagerInfoBase)();
16959
+ const baseInfo = await (0, exports.getPackageManagerInfoBase)(config);
16528
16960
  const { workspaces } = baseInfo;
16529
- // currently only supports yarn
16530
16961
  const component = config.components[componentName];
16531
16962
  const currentWorkspace = workspaces.find((w) => (0, path_equal_1.pathEqual)(component.dir, w.location));
16532
16963
  const componentIsInWorkspace = Boolean(currentWorkspace);
@@ -16535,10 +16966,10 @@ const getPackageManagerInfoForComponent = async (config, componentName) => {
16535
16966
  const workspacePackageJson = componentIsInWorkspace
16536
16967
  ? (0, path_1.join)(workspaceRoot, "package.json")
16537
16968
  : null;
16969
+ const { lockFile: lockFileName, configFiles } = PACKAGE_MANAGER_FILES[baseInfo.type];
16538
16970
  const lockFile = componentIsInWorkspace
16539
- ? (0, path_1.join)(workspaceRoot, "yarn.lock")
16540
- : (0, path_1.join)(component.dir, "yarn.lock");
16541
- const configFiles = [".yarnrc", ".yarnrc.yml", ".npmrc", ".yarn"]; // ".yarn" is yarn 2 folder
16971
+ ? (0, path_1.join)(workspaceRoot, lockFileName)
16972
+ : (0, path_1.join)(component.dir, lockFileName);
16542
16973
  // copy all those configFiles from workspace root and/or component folder
16543
16974
  const configFilePaths = [
16544
16975
  ...configFiles,
@@ -16549,12 +16980,27 @@ const getPackageManagerInfoForComponent = async (config, componentName) => {
16549
16980
  const currentWorkspaceDependencies = currentWorkspace
16550
16981
  ? (0, yarnUtils_1.getWorkspaceDependencies)(currentWorkspace, workspaces)
16551
16982
  : [];
16983
+ // pnpm's --frozen-lockfile check requires every importer of the
16984
+ // lockfile to exist on disk, so all workspace manifests (not just the
16985
+ // dependency workspaces, which are copied entirely) go into the image
16986
+ const allWorkspaceManifests = baseInfo.type === "pnpm" && componentIsInWorkspace
16987
+ ? workspaces
16988
+ .map((w) => (0, path_1.join)(w.location, "package.json"))
16989
+ .filter((f) => (0, fs_1.existsSync)(f))
16990
+ : [];
16991
+ // patch files referenced by patchedDependencies must exist in the
16992
+ // image, or pnpm's frozen install fails verifying them
16993
+ const patchFiles = baseInfo.type === "pnpm"
16994
+ ? (0, pnpmUtils_1.getPnpmPatchFiles)(componentIsInWorkspace ? workspaceRoot : component.dir)
16995
+ : [];
16552
16996
  const pathsToCopyInDocker = [
16553
16997
  ...new Set([
16554
16998
  packageJson,
16555
16999
  ...(workspacePackageJson ? [workspacePackageJson] : []),
16556
17000
  lockFile,
16557
17001
  ...configFilePaths,
17002
+ ...allWorkspaceManifests,
17003
+ ...patchFiles,
16558
17004
  ...currentWorkspaceDependencies,
16559
17005
  ]),
16560
17006
  ];
@@ -16567,11 +17013,17 @@ const getPackageManagerInfoForComponent = async (config, componentName) => {
16567
17013
  };
16568
17014
  };
16569
17015
  exports.getPackageManagerInfoForComponent = getPackageManagerInfoForComponent;
16570
- const _getPackageManagerInfoBase = async () => {
16571
- // currently only supports yarn
16572
- const version = await (0, yarnUtils_1.getYarnVersion)();
17016
+ const _getPackageManagerInfoBase = async (config) => {
17017
+ const { type, version } = await (0, detectPackageManager_1.detectPackageManager)(config === null || config === void 0 ? void 0 : config.packageManager);
16573
17018
  if (!version)
16574
- throw new Error("could not get yarn version");
17019
+ throw new Error(`could not get ${type} version`);
17020
+ if (type === "pnpm") {
17021
+ return {
17022
+ type: "pnpm",
17023
+ workspaces: await (0, pnpmUtils_1.getPnpmWorkspaces)(),
17024
+ version,
17025
+ };
17026
+ }
16575
17027
  const isClassic = version.startsWith("1");
16576
17028
  const workspaces = await (0, yarnUtils_1.getWorkspaces)(isClassic);
16577
17029
  return {
@@ -16583,11 +17035,113 @@ const _getPackageManagerInfoBase = async () => {
16583
17035
  };
16584
17036
  exports.getPackageManagerInfoBase = (0, memoizee_1.default)(_getPackageManagerInfoBase, {
16585
17037
  promise: true,
17038
+ // memoize per explicit packageManager choice, not per config identity
17039
+ normalizer: ([config]) => { var _a; return (_a = config === null || config === void 0 ? void 0 : config.packageManager) !== null && _a !== void 0 ? _a : ""; },
16586
17040
  });
16587
17041
  //# sourceMappingURL=packageManager.js.map
16588
17042
 
16589
17043
  /***/ }),
16590
17044
 
17045
+ /***/ 3497:
17046
+ /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
17047
+
17048
+ "use strict";
17049
+
17050
+ var __importDefault = (this && this.__importDefault) || function (mod) {
17051
+ return (mod && mod.__esModule) ? mod : { "default": mod };
17052
+ };
17053
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
17054
+ exports.getPnpmWorkspaces = exports.getPnpmPatchFiles = void 0;
17055
+ const child_process_promise_1 = __nccwpck_require__(42242);
17056
+ const fs_1 = __nccwpck_require__(79896);
17057
+ const promises_1 = __nccwpck_require__(91943);
17058
+ const path_1 = __nccwpck_require__(16928);
17059
+ const memoizee_1 = __importDefault(__nccwpck_require__(14199));
17060
+ const yaml_1 = __nccwpck_require__(33483);
17061
+ const jsonParse_1 = __nccwpck_require__(99461);
17062
+ const readWorkspaceDependencyLocations = async (location, locationByName) => {
17063
+ var _a, _b, _c;
17064
+ try {
17065
+ const pkg = JSON.parse(await (0, promises_1.readFile)((0, path_1.join)(location, "package.json"), "utf-8"));
17066
+ const depNames = [
17067
+ ...Object.keys((_a = pkg.dependencies) !== null && _a !== void 0 ? _a : {}),
17068
+ ...Object.keys((_b = pkg.devDependencies) !== null && _b !== void 0 ? _b : {}),
17069
+ ...Object.keys((_c = pkg.optionalDependencies) !== null && _c !== void 0 ? _c : {}),
17070
+ ];
17071
+ return [
17072
+ ...new Set(depNames
17073
+ .map((name) => locationByName.get(name))
17074
+ .filter((l) => Boolean(l) && l !== location)),
17075
+ ];
17076
+ }
17077
+ catch (_d) {
17078
+ return [];
17079
+ }
17080
+ };
17081
+ /**
17082
+ * patch files referenced by `patchedDependencies` (pnpm-workspace.yaml
17083
+ * or the root package.json's `pnpm` section) — they must travel into
17084
+ * the docker build context, or the prod install fails to verify them
17085
+ */
17086
+ const getPnpmPatchFiles = (root = ".") => {
17087
+ var _a, _b, _c;
17088
+ const patchedDependencies = {};
17089
+ try {
17090
+ const ws = (0, yaml_1.parse)((0, fs_1.readFileSync)((0, path_1.join)(root, "pnpm-workspace.yaml"), "utf-8"));
17091
+ Object.assign(patchedDependencies, (_a = ws === null || ws === void 0 ? void 0 : ws.patchedDependencies) !== null && _a !== void 0 ? _a : {});
17092
+ }
17093
+ catch (_d) {
17094
+ // no workspace file
17095
+ }
17096
+ try {
17097
+ const pkg = JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(root, "package.json"), "utf-8"));
17098
+ 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 : {});
17099
+ }
17100
+ catch (_e) {
17101
+ // no package.json
17102
+ }
17103
+ return [
17104
+ ...new Set(Object.values(patchedDependencies)
17105
+ .map((p) => (0, path_1.join)(root, p))
17106
+ .filter((p) => (0, fs_1.existsSync)(p))),
17107
+ ];
17108
+ };
17109
+ exports.getPnpmPatchFiles = getPnpmPatchFiles;
17110
+ /**
17111
+ * list pnpm workspace projects in the same shape yarn berry reports them
17112
+ * (locations relative to the project root, workspace dependencies as
17113
+ * locations). Outside a pnpm workspace this returns [].
17114
+ */
17115
+ // export for mocking
17116
+ exports.getPnpmWorkspaces = (0, memoizee_1.default)(async () => {
17117
+ let output;
17118
+ try {
17119
+ output = (await (0, child_process_promise_1.exec)("pnpm m ls --json --depth -1")).stdout;
17120
+ }
17121
+ catch (_a) {
17122
+ return [];
17123
+ }
17124
+ const projects = (0, jsonParse_1.jsonParseOrThrow)(output.trim() || "[]");
17125
+ if (!Array.isArray(projects))
17126
+ return [];
17127
+ const withLocations = projects
17128
+ .filter((p) => p.name && p.path)
17129
+ .map((p) => ({
17130
+ name: p.name,
17131
+ location: (0, path_1.relative)(process.cwd(), p.path) || ".",
17132
+ }));
17133
+ const locationByName = new Map(withLocations.map((p) => [p.name, p.location]));
17134
+ return Promise.all(withLocations.map(async ({ name, location }) => ({
17135
+ name,
17136
+ location,
17137
+ workspaceDependencies: await readWorkspaceDependencyLocations(location, locationByName),
17138
+ mismatchedWorkspaceDependencies: [],
17139
+ })));
17140
+ }, { promise: true });
17141
+ //# sourceMappingURL=pnpmUtils.js.map
17142
+
17143
+ /***/ }),
17144
+
16591
17145
  /***/ 77257:
16592
17146
  /***/ ((__unused_webpack_module, exports) => {
16593
17147
 
@@ -16699,10 +17253,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
16699
17253
  return (mod && mod.__esModule) ? mod : { "default": mod };
16700
17254
  };
16701
17255
  Object.defineProperty(exports, "__esModule", ({ value: true }));
16702
- exports.getWorkspaceDependencies = exports.getWorkspaces = exports.getYarnVersion = void 0;
17256
+ exports.getWorkspaceDependencies = exports.getWorkspaces = void 0;
16703
17257
  const child_process_promise_1 = __nccwpck_require__(42242);
16704
- const promises_1 = __nccwpck_require__(91943);
16705
- const path_1 = __nccwpck_require__(16928);
16706
17258
  const memoizee_1 = __importDefault(__nccwpck_require__(14199));
16707
17259
  const jsonParse_1 = __nccwpck_require__(99461);
16708
17260
  const execOrFail = async (cmd, onFail) => {
@@ -16713,40 +17265,6 @@ const execOrFail = async (cmd, onFail) => {
16713
17265
  return onFail !== null && onFail !== void 0 ? onFail : null;
16714
17266
  }
16715
17267
  };
16716
- const readPackageManagerVersion = async (dir) => {
16717
- var _a;
16718
- try {
16719
- const pkg = JSON.parse(await (0, promises_1.readFile)((0, path_1.join)(dir, "package.json"), "utf-8"));
16720
- const match = /^yarn@(.+)$/.exec(pkg.packageManager);
16721
- return (_a = match === null || match === void 0 ? void 0 : match[1]) !== null && _a !== void 0 ? _a : null;
16722
- }
16723
- catch (_b) {
16724
- return null;
16725
- }
16726
- };
16727
- const getGitRoot = async () => {
16728
- try {
16729
- return (await (0, child_process_promise_1.exec)("git rev-parse --show-toplevel")).stdout.trim();
16730
- }
16731
- catch (_a) {
16732
- return null;
16733
- }
16734
- };
16735
- // export for mocking
16736
- exports.getYarnVersion = (0, memoizee_1.default)(async () => {
16737
- // Fast path: read from package.json packageManager field
16738
- const fromCwd = await readPackageManagerVersion(process.cwd());
16739
- if (fromCwd)
16740
- return fromCwd;
16741
- const gitRoot = await getGitRoot();
16742
- if (gitRoot && gitRoot !== process.cwd()) {
16743
- const fromGitRoot = await readPackageManagerVersion(gitRoot);
16744
- if (fromGitRoot)
16745
- return fromGitRoot;
16746
- }
16747
- // Fallback: invoke yarn CLI
16748
- return await execOrFail("yarn --version", "");
16749
- }, { promise: true });
16750
17268
  // export for mocking
16751
17269
  exports.getWorkspaces = (0, memoizee_1.default)(async (isClassic) => {
16752
17270
  var _a, _b;
@@ -17397,7 +17915,7 @@ exports.createVerifyJobs = exports.VERIFY_JOB_NAME = void 0;
17397
17915
  const createArtifactsConfig_1 = __nccwpck_require__(24494);
17398
17916
  const cache_1 = __nccwpck_require__(21100);
17399
17917
  const constants_1 = __nccwpck_require__(97627);
17400
- const yarn_1 = __nccwpck_require__(59874);
17918
+ const packageManagerInstall_1 = __nccwpck_require__(18600);
17401
17919
  const deploy_1 = __nccwpck_require__(19752);
17402
17920
  const runner_1 = __nccwpck_require__(71065);
17403
17921
  const utils_1 = __nccwpck_require__(24516);
@@ -17414,9 +17932,9 @@ const createVerifyJobs = async (context) => {
17414
17932
  return [];
17415
17933
  }
17416
17934
  const isNodeBuild = context.build.type !== "disabled" && context.build.buildType === "node";
17417
- const [yarnInstall, nodeCache] = isNodeBuild
17935
+ const [packageManagerInstall, nodeCache] = isNodeBuild
17418
17936
  ? await Promise.all([
17419
- (0, yarn_1.getYarnInstall)(context),
17937
+ (0, packageManagerInstall_1.getPackageManagerInstall)(context),
17420
17938
  (0, cache_1.getNodeCache)(context, "pull"),
17421
17939
  ])
17422
17940
  : [null, null];
@@ -17452,9 +17970,9 @@ const createVerifyJobs = async (context) => {
17452
17970
  },
17453
17971
  script: [
17454
17972
  ...setupScript,
17455
- ...(yarnInstall ? (0, yarn_1.ensureNodeVersion)(context) : []),
17973
+ ...(packageManagerInstall ? (0, packageManagerInstall_1.ensureNodeVersion)(context) : []),
17456
17974
  `cd ${context.build.dir}`,
17457
- ...(yarnInstall !== null && yarnInstall !== void 0 ? yarnInstall : []),
17975
+ ...(packageManagerInstall !== null && packageManagerInstall !== void 0 ? packageManagerInstall : []),
17458
17976
  ...(0, utils_1.ensureArray)(verifyConfig.command),
17459
17977
  ],
17460
17978
  allow_failure: verifyConfig.allowFailure,