@catladder/cli 5.5.0 → 5.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundles/catenv/index.js +364 -45
- package/dist/bundles/catenv/xdg-open +0 -0
- package/dist/bundles/cli/clipboard_i686.exe +0 -0
- package/dist/bundles/cli/clipboard_x86_64.exe +0 -0
- package/dist/bundles/cli/index.js +364 -45
- package/dist/bundles/cli/xdg-open +0 -0
- package/dist/bundles/cli/xsel +0 -0
- package/dist/bundles/runner-images/changesets/scripts/changesetsRelease +0 -0
- package/dist/bundles/runner-images/kubernetes/scripts/kubernetesCreateSecret +0 -0
- package/dist/bundles/runner-images/kubernetes/scripts/kubernetesDelete +0 -0
- package/dist/bundles/runner-images/kubernetes/scripts/kubernetesDeploy +0 -0
- package/dist/bundles/runner-images/kubernetes/scripts/kubernetesRollback +0 -0
- package/dist/bundles/skills/catladder-builds/SKILL.md +50 -2
- package/dist/bundles/skills/catladder-builds/references/build-types.md +10 -2
- package/dist/bundles/skills/catladder-pipelines/SKILL.md +18 -2
- package/dist/packages/pipeline/src/backends/github/artifactArchive.d.ts +22 -0
- package/dist/packages/pipeline/src/backends/github/artifactArchive.js +84 -0
- package/dist/packages/pipeline/src/backends/github/artifactArchive.js.map +1 -0
- package/dist/packages/pipeline/src/backends/github/createGithubJobs.js +12 -29
- package/dist/packages/pipeline/src/backends/github/createGithubJobs.js.map +1 -1
- package/dist/packages/pipeline/src/backends/gitlab/GitlabBackend.js +3 -1
- package/dist/packages/pipeline/src/backends/gitlab/GitlabBackend.js.map +1 -1
- package/dist/packages/pipeline/src/backends/gitlab/getPipelineStages.d.ts +4 -1
- package/dist/packages/pipeline/src/backends/gitlab/getPipelineStages.js +11 -2
- package/dist/packages/pipeline/src/backends/gitlab/getPipelineStages.js.map +1 -1
- package/dist/packages/pipeline/src/build/types.d.ts +4 -3
- package/dist/packages/pipeline/src/build/types.js.map +1 -1
- package/dist/packages/pipeline/src/deploy/base/deploy.js +15 -9
- package/dist/packages/pipeline/src/deploy/base/deploy.js.map +1 -1
- package/dist/packages/pipeline/src/index.d.ts +1 -0
- package/dist/packages/pipeline/src/index.js +1 -0
- package/dist/packages/pipeline/src/index.js.map +1 -1
- package/dist/packages/pipeline/src/pipeline/createJobsForComponent.js +12 -2
- package/dist/packages/pipeline/src/pipeline/createJobsForComponent.js.map +1 -1
- package/dist/packages/pipeline/src/pipeline/createJobsForWorkspace.js +7 -2
- package/dist/packages/pipeline/src/pipeline/createJobsForWorkspace.js.map +1 -1
- package/dist/packages/pipeline/src/pipeline/resolveRequirements.js +1 -0
- package/dist/packages/pipeline/src/pipeline/resolveRequirements.js.map +1 -1
- package/dist/packages/pipeline/src/postBuildTest/createPostBuildTestJobs.d.ts +16 -0
- package/dist/packages/pipeline/src/postBuildTest/createPostBuildTestJobs.js +167 -0
- package/dist/packages/pipeline/src/postBuildTest/createPostBuildTestJobs.js.map +1 -0
- package/dist/packages/pipeline/src/postBuildTest/index.d.ts +2 -0
- package/dist/packages/pipeline/src/postBuildTest/index.js +19 -0
- package/dist/packages/pipeline/src/postBuildTest/index.js.map +1 -0
- package/dist/packages/pipeline/src/postBuildTest/types.d.ts +61 -0
- package/dist/packages/pipeline/src/postBuildTest/types.js +3 -0
- package/dist/packages/pipeline/src/postBuildTest/types.js.map +1 -0
- package/dist/packages/pipeline/src/types/jobs.d.ts +2 -2
- package/dist/packages/pipeline/src/types/jobs.js +1 -0
- package/dist/packages/pipeline/src/types/jobs.js.map +1 -1
- package/dist/runner-images/changesets/scripts/changesetsRelease +0 -0
- package/dist/runner-images/kubernetes/scripts/kubernetesCreateSecret +0 -0
- package/dist/runner-images/kubernetes/scripts/kubernetesDelete +0 -0
- package/dist/runner-images/kubernetes/scripts/kubernetesDeploy +0 -0
- package/dist/runner-images/kubernetes/scripts/kubernetesRollback +0 -0
- package/dist/skills/catladder-builds/SKILL.md +50 -2
- package/dist/skills/catladder-builds/references/build-types.md +10 -2
- package/dist/skills/catladder-pipelines/SKILL.md +18 -2
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -9679,6 +9679,97 @@ exports.makeAggregateCheckJob = makeAggregateCheckJob;
|
|
|
9679
9679
|
|
|
9680
9680
|
/***/ }),
|
|
9681
9681
|
|
|
9682
|
+
/***/ 75125:
|
|
9683
|
+
/***/ ((__unused_webpack_module, exports) => {
|
|
9684
|
+
|
|
9685
|
+
"use strict";
|
|
9686
|
+
|
|
9687
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
9688
|
+
exports.createArtifactDownloadSteps = exports.createArtifactUploadSteps = exports.artifactArchiveFile = void 0;
|
|
9689
|
+
/**
|
|
9690
|
+
* Artifacts are handed between github jobs as ONE tar archive instead
|
|
9691
|
+
* of letting upload-artifact walk the paths itself.
|
|
9692
|
+
*
|
|
9693
|
+
* upload-artifact does not preserve symlinks (it uploads the target's
|
|
9694
|
+
* content) nor file modes, and it strips the paths' common ancestor.
|
|
9695
|
+
* Gitlab artifacts keep all of that, and builds rely on it: next.js
|
|
9696
|
+
* with turbopack writes `.next/node_modules/<pkg>-<hash>` as relative
|
|
9697
|
+
* symlinks into the pnpm virtual store. Copied as plain directories,
|
|
9698
|
+
* node resolves the package's own dependencies from the wrong place
|
|
9699
|
+
* and the app crashes with ERR_MODULE_NOT_FOUND at runtime. tar keeps
|
|
9700
|
+
* symlinks, modes and the paths relative to the repo root (github's
|
|
9701
|
+
* own docs recommend it for exactly this).
|
|
9702
|
+
*
|
|
9703
|
+
* The archive is not hidden (upload-artifact skips hidden files) and
|
|
9704
|
+
* lives in the workspace, the one path run steps and actions agree on
|
|
9705
|
+
* inside job containers too.
|
|
9706
|
+
*/
|
|
9707
|
+
const artifactArchiveFile = (jobId) => `catladder-artifacts-${jobId}.tar`;
|
|
9708
|
+
exports.artifactArchiveFile = artifactArchiveFile;
|
|
9709
|
+
const createArtifactUploadSteps = (jobId, paths, condition) => {
|
|
9710
|
+
const archive = (0, exports.artifactArchiveFile)(jobId);
|
|
9711
|
+
const ifCondition = condition ? { if: condition } : {};
|
|
9712
|
+
return [
|
|
9713
|
+
{
|
|
9714
|
+
name: "Archive artifacts",
|
|
9715
|
+
...ifCondition,
|
|
9716
|
+
run: [
|
|
9717
|
+
"shopt -s nullglob globstar",
|
|
9718
|
+
"paths=()",
|
|
9719
|
+
// unquoted on purpose: artifact paths may be globs. Non-matching
|
|
9720
|
+
// globs vanish (nullglob), missing literal paths are skipped —
|
|
9721
|
+
// gitlab only warns about both, so do we
|
|
9722
|
+
`for path in ${paths.join(" ")}; do`,
|
|
9723
|
+
' if [ -e "$path" ] || [ -L "$path" ]; then paths+=("$path"); else echo "::warning::artifact path not found: $path"; fi',
|
|
9724
|
+
"done",
|
|
9725
|
+
"if [ ${#paths[@]} -eq 0 ]; then",
|
|
9726
|
+
// an empty archive keeps downstream downloads from failing.
|
|
9727
|
+
// Written by hand: busybox tar (alpine job images) refuses to
|
|
9728
|
+
// create one, and zero blocks are what an empty tar is
|
|
9729
|
+
` head -c 10240 /dev/zero > ${archive}`,
|
|
9730
|
+
"else",
|
|
9731
|
+
` tar -cf ${archive} -- "\${paths[@]}"`,
|
|
9732
|
+
"fi",
|
|
9733
|
+
].join("\n"),
|
|
9734
|
+
shell: "bash",
|
|
9735
|
+
},
|
|
9736
|
+
{
|
|
9737
|
+
name: "Upload artifacts",
|
|
9738
|
+
...ifCondition,
|
|
9739
|
+
uses: "actions/upload-artifact@v4",
|
|
9740
|
+
with: {
|
|
9741
|
+
name: jobId,
|
|
9742
|
+
path: archive,
|
|
9743
|
+
"if-no-files-found": "error",
|
|
9744
|
+
},
|
|
9745
|
+
},
|
|
9746
|
+
];
|
|
9747
|
+
};
|
|
9748
|
+
exports.createArtifactUploadSteps = createArtifactUploadSteps;
|
|
9749
|
+
const createArtifactDownloadSteps = (providerIds) => providerIds.length === 0
|
|
9750
|
+
? []
|
|
9751
|
+
: [
|
|
9752
|
+
...providerIds.map((id) => ({
|
|
9753
|
+
name: `Download artifacts from ${id}`,
|
|
9754
|
+
uses: "actions/download-artifact@v4",
|
|
9755
|
+
with: { name: id },
|
|
9756
|
+
})),
|
|
9757
|
+
{
|
|
9758
|
+
name: "Extract artifacts",
|
|
9759
|
+
run: providerIds
|
|
9760
|
+
.flatMap((id) => [
|
|
9761
|
+
`tar -xf ${(0, exports.artifactArchiveFile)(id)}`,
|
|
9762
|
+
`rm ${(0, exports.artifactArchiveFile)(id)}`,
|
|
9763
|
+
])
|
|
9764
|
+
.join("\n"),
|
|
9765
|
+
shell: "bash",
|
|
9766
|
+
},
|
|
9767
|
+
];
|
|
9768
|
+
exports.createArtifactDownloadSteps = createArtifactDownloadSteps;
|
|
9769
|
+
//# sourceMappingURL=artifactArchive.js.map
|
|
9770
|
+
|
|
9771
|
+
/***/ }),
|
|
9772
|
+
|
|
9682
9773
|
/***/ 17300:
|
|
9683
9774
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
|
9684
9775
|
|
|
@@ -9748,6 +9839,7 @@ const utils_1 = __nccwpck_require__(49401);
|
|
|
9748
9839
|
const gitlab_1 = __nccwpck_require__(86962);
|
|
9749
9840
|
const scriptFunctions_1 = __nccwpck_require__(85873);
|
|
9750
9841
|
const ciVariables_1 = __nccwpck_require__(17300);
|
|
9842
|
+
const artifactArchive_1 = __nccwpck_require__(75125);
|
|
9751
9843
|
/**
|
|
9752
9844
|
* runner variables that only make sense on gitlab runners and must not
|
|
9753
9845
|
* leak into github jobs (docker-in-docker daemon config, kubernetes
|
|
@@ -9958,7 +10050,7 @@ const getReferencedSecretsEnv = (script, kinds) => Object.fromEntries([...script
|
|
|
9958
10050
|
.filter((name) => !ciVariables_1.GITHUB_INJECTED_WORKFLOW_ENV_NAMES.has(name))
|
|
9959
10051
|
.map((name) => [name, vaultValueExpression(name, kinds)]));
|
|
9960
10052
|
const makeGithubJob = (context, job, allJobs, uploadProviderIds, images, scripts, secretKinds = new Map()) => {
|
|
9961
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
10053
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
9962
10054
|
const id = (0, exports.githubJobId)(context, job.name);
|
|
9963
10055
|
const isComponent = context.type === "component";
|
|
9964
10056
|
const createsJobEnv = !!job.environment &&
|
|
@@ -10103,13 +10195,7 @@ const makeGithubJob = (context, job, allJobs, uploadProviderIds, images, scripts
|
|
|
10103
10195
|
? []
|
|
10104
10196
|
: [{ name: "Checkout", uses: "actions/checkout@v4" }]),
|
|
10105
10197
|
...createCacheSteps(context, job),
|
|
10106
|
-
...needs
|
|
10107
|
-
.filter((n) => n.artifacts)
|
|
10108
|
-
.map((n) => ({
|
|
10109
|
-
name: `Download artifacts from ${n.id}`,
|
|
10110
|
-
uses: "actions/download-artifact@v4",
|
|
10111
|
-
with: { name: n.id },
|
|
10112
|
-
})),
|
|
10198
|
+
...(0, artifactArchive_1.createArtifactDownloadSteps)(needs.filter((n) => n.artifacts).map((n) => n.id)),
|
|
10113
10199
|
{
|
|
10114
10200
|
name: job.name,
|
|
10115
10201
|
id: "main",
|
|
@@ -10130,27 +10216,15 @@ const makeGithubJob = (context, job, allJobs, uploadProviderIds, images, scripts
|
|
|
10130
10216
|
},
|
|
10131
10217
|
]
|
|
10132
10218
|
: []),
|
|
10133
|
-
...(pagesPublishDir
|
|
10134
|
-
?
|
|
10135
|
-
|
|
10136
|
-
|
|
10137
|
-
|
|
10138
|
-
|
|
10139
|
-
|
|
10140
|
-
|
|
10141
|
-
|
|
10142
|
-
name: id,
|
|
10143
|
-
path: artifactPaths.join("\n"),
|
|
10144
|
-
"if-no-files-found": "warn",
|
|
10145
|
-
// gitlab artifacts include everything; upload-artifact
|
|
10146
|
-
// silently drops hidden files by default — which is
|
|
10147
|
-
// exactly where next.js builds live (.next)
|
|
10148
|
-
"include-hidden-files": true,
|
|
10149
|
-
},
|
|
10150
|
-
},
|
|
10151
|
-
]
|
|
10152
|
-
: []
|
|
10153
|
-
: []),
|
|
10219
|
+
...(!pagesPublishDir && artifactPaths.length > 0
|
|
10220
|
+
? (0, artifactArchive_1.createArtifactUploadSteps)(id, artifactPaths,
|
|
10221
|
+
// gitlab's `artifacts.when`: steps only run on success by default
|
|
10222
|
+
((_k = job.artifacts) === null || _k === void 0 ? void 0 : _k.when) === "always"
|
|
10223
|
+
? "always()"
|
|
10224
|
+
: ((_l = job.artifacts) === null || _l === void 0 ? void 0 : _l.when) === "on_failure"
|
|
10225
|
+
? "failure()"
|
|
10226
|
+
: undefined)
|
|
10227
|
+
: []),
|
|
10154
10228
|
],
|
|
10155
10229
|
};
|
|
10156
10230
|
return [id, githubJob];
|
|
@@ -10843,7 +10917,6 @@ class GitlabBackend {
|
|
|
10843
10917
|
return [mainInclude, ...componentIncludes];
|
|
10844
10918
|
}
|
|
10845
10919
|
async createPipeline(config, images) {
|
|
10846
|
-
const stages = (0, getPipelineStages_1.getPipelineStages)(config);
|
|
10847
10920
|
// register the release image first: the per-trigger job creation
|
|
10848
10921
|
// below emits the build jobs of all images registered so far. The
|
|
10849
10922
|
// release jobs themselves are created afterwards — they need the
|
|
@@ -10862,6 +10935,9 @@ class GitlabBackend {
|
|
|
10862
10935
|
jobs: await (0, createGitlabJobs_1.createGitlabJobs)(await (0, createAllJobs_1.createAllJobs)({ config, trigger, pipelineType: this.type }), images, getGitlabRulesForTrigger(trigger)),
|
|
10863
10936
|
})));
|
|
10864
10937
|
const allJobsPerTrigger = jobsPerTrigger.flatMap(({ jobs }) => jobs);
|
|
10938
|
+
const stages = (0, getPipelineStages_1.getPipelineStages)(config, new Set(allJobsPerTrigger
|
|
10939
|
+
.map(({ gitlabJob }) => gitlabJob.stage)
|
|
10940
|
+
.filter((stage) => typeof stage === "string")));
|
|
10865
10941
|
// the jobs the queued-release executor waits for: everything that
|
|
10866
10942
|
// runs automatically in a main-branch pipeline. Manual jobs (stop,
|
|
10867
10943
|
// rollback, gates) are excluded — gitlab skips a job whose needs
|
|
@@ -11516,14 +11592,23 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
|
11516
11592
|
exports.getPipelineStages = void 0;
|
|
11517
11593
|
const config_1 = __nccwpck_require__(11646);
|
|
11518
11594
|
const jobs_1 = __nccwpck_require__(98521);
|
|
11595
|
+
/**
|
|
11596
|
+
* stages that only appear in the pipeline when a job uses them, so that
|
|
11597
|
+
* projects not using the feature keep their generated files unchanged
|
|
11598
|
+
*/
|
|
11599
|
+
const OPTIONAL_STAGES = ["post-build"];
|
|
11519
11600
|
/**
|
|
11520
11601
|
* while technically not required, we group different envs in its own stage
|
|
11521
11602
|
* each job from `createJobs` that is defined as `envMode: "stagePerEnv"` will have `deploy dev`, etc. instead of just `deploy`
|
|
11522
11603
|
* this is just so that it looks nicer in gitlab and makes running mutliple manual tasks more easy to use
|
|
11604
|
+
*
|
|
11605
|
+
* `usedStages` are the stages of all generated jobs; optional stages are
|
|
11606
|
+
* dropped when none of them is used.
|
|
11523
11607
|
*/
|
|
11524
|
-
function getPipelineStages(config) {
|
|
11608
|
+
function getPipelineStages(config, usedStages = new Set()) {
|
|
11525
11609
|
const allEnvs = (0, config_1.getAllEnvsInAllComponents)(config).filter((e) => e !== "local");
|
|
11526
|
-
const
|
|
11610
|
+
const isUsed = (baseStage) => [...usedStages].some((stage) => stage === baseStage || stage.startsWith(`${baseStage} `));
|
|
11611
|
+
const stages = jobs_1.BASE_STAGES.filter((baseStage) => !OPTIONAL_STAGES.includes(baseStage) || isUsed(baseStage)).reduce((acc, baseStage) => [
|
|
11527
11612
|
...acc,
|
|
11528
11613
|
baseStage,
|
|
11529
11614
|
...allEnvs.map((e) => `${baseStage} ${e}`),
|
|
@@ -15607,14 +15692,20 @@ class DeployJob extends jobs_1.CatladderJob {
|
|
|
15607
15692
|
: []),
|
|
15608
15693
|
];
|
|
15609
15694
|
// we don't want to deploy when there is a broken test
|
|
15610
|
-
const
|
|
15611
|
-
|
|
15612
|
-
artifacts: false,
|
|
15613
|
-
//
|
|
15614
|
-
|
|
15615
|
-
?
|
|
15616
|
-
|
|
15617
|
-
|
|
15695
|
+
const qualityGateRequirements = [
|
|
15696
|
+
// the component's own gates (e.g. post-build tests, custom test jobs)
|
|
15697
|
+
{ capability: "qualityGate", artifacts: false },
|
|
15698
|
+
// ...and the gates of the workspace build it is built in
|
|
15699
|
+
...((0, context_1.componentContextHasWorkspaceBuild)(context)
|
|
15700
|
+
? [
|
|
15701
|
+
{
|
|
15702
|
+
capability: "qualityGate",
|
|
15703
|
+
artifacts: false,
|
|
15704
|
+
from: { workspace: context.build.workspaceName },
|
|
15705
|
+
},
|
|
15706
|
+
]
|
|
15707
|
+
: []),
|
|
15708
|
+
];
|
|
15618
15709
|
super({
|
|
15619
15710
|
name: exports.DEPLOY_JOB_NAME,
|
|
15620
15711
|
script: jobDefinition.script,
|
|
@@ -15631,7 +15722,7 @@ class DeployJob extends jobs_1.CatladderJob {
|
|
|
15631
15722
|
...waitForRequirements,
|
|
15632
15723
|
// if the build is disabled, we don't need to wait for it
|
|
15633
15724
|
...(context.build.type !== "disabled"
|
|
15634
|
-
? [...buildRequirements,
|
|
15725
|
+
? [...buildRequirements, ...qualityGateRequirements]
|
|
15635
15726
|
: []),
|
|
15636
15727
|
],
|
|
15637
15728
|
gate: whenDeploy,
|
|
@@ -18407,6 +18498,7 @@ __exportStar(__nccwpck_require__(15707), exports);
|
|
|
18407
18498
|
__exportStar(__nccwpck_require__(45492), exports);
|
|
18408
18499
|
__exportStar(__nccwpck_require__(3659), exports);
|
|
18409
18500
|
__exportStar(__nccwpck_require__(50713), exports);
|
|
18501
|
+
__exportStar(__nccwpck_require__(28458), exports);
|
|
18410
18502
|
__exportStar(__nccwpck_require__(26041), exports);
|
|
18411
18503
|
__exportStar(__nccwpck_require__(47663), exports);
|
|
18412
18504
|
__exportStar(__nccwpck_require__(91804), exports);
|
|
@@ -19004,6 +19096,7 @@ exports.createJobsForComponentContext = void 0;
|
|
|
19004
19096
|
const build_1 = __nccwpck_require__(45492);
|
|
19005
19097
|
const deploy_1 = __nccwpck_require__(3659);
|
|
19006
19098
|
const jobs_1 = __nccwpck_require__(98521);
|
|
19099
|
+
const createPostBuildTestJobs_1 = __nccwpck_require__(61844);
|
|
19007
19100
|
const createVerifyJobs_1 = __nccwpck_require__(66900);
|
|
19008
19101
|
const injectDefaultVarsInCustomJobs = (context, jobs) => jobs.map(({ variables, ...job }) => {
|
|
19009
19102
|
var _a;
|
|
@@ -19023,17 +19116,26 @@ const getCustomJobs = (context) => {
|
|
|
19023
19116
|
return injectDefaultVarsInCustomJobs(context, rawJobs);
|
|
19024
19117
|
};
|
|
19025
19118
|
const createJobsForComponentContext = async (context) => {
|
|
19026
|
-
const [buildJobs, deployJobs, verifyJobs] = await Promise.all([
|
|
19119
|
+
const [buildJobs, postBuildTestJobs, deployJobs, verifyJobs] = await Promise.all([
|
|
19027
19120
|
context.build.type !== "disabled"
|
|
19028
19121
|
? build_1.BUILD_TYPES[context.build.buildType].jobs(context)
|
|
19029
19122
|
: [],
|
|
19123
|
+
(0, createPostBuildTestJobs_1.createPostBuildTestJobs)(context),
|
|
19030
19124
|
context.componentConfig.deploy !== false
|
|
19031
19125
|
? deploy_1.DEPLOY_TYPES[context.componentConfig.deploy.type].jobs(context)
|
|
19032
19126
|
: [],
|
|
19033
19127
|
(0, createVerifyJobs_1.createVerifyJobs)(context),
|
|
19034
19128
|
]);
|
|
19035
19129
|
const customJobs = getCustomJobs(context);
|
|
19036
|
-
|
|
19130
|
+
const otherJobs = [...buildJobs, ...deployJobs, ...verifyJobs, ...customJobs];
|
|
19131
|
+
(0, createPostBuildTestJobs_1.assertUniquePostBuildTestNames)(context, postBuildTestJobs, otherJobs);
|
|
19132
|
+
return [
|
|
19133
|
+
...buildJobs,
|
|
19134
|
+
...postBuildTestJobs,
|
|
19135
|
+
...deployJobs,
|
|
19136
|
+
...verifyJobs,
|
|
19137
|
+
...customJobs,
|
|
19138
|
+
];
|
|
19037
19139
|
};
|
|
19038
19140
|
exports.createJobsForComponentContext = createJobsForComponentContext;
|
|
19039
19141
|
//# sourceMappingURL=createJobsForComponent.js.map
|
|
@@ -19048,9 +19150,14 @@ exports.createJobsForComponentContext = createJobsForComponentContext;
|
|
|
19048
19150
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
19049
19151
|
exports.createJobsForWorkspace = void 0;
|
|
19050
19152
|
const build_1 = __nccwpck_require__(45492);
|
|
19153
|
+
const createPostBuildTestJobs_1 = __nccwpck_require__(61844);
|
|
19051
19154
|
const createJobsForWorkspace = async (context) => {
|
|
19052
|
-
const buildJobs = await
|
|
19053
|
-
|
|
19155
|
+
const [buildJobs, postBuildTestJobs] = await Promise.all([
|
|
19156
|
+
build_1.WORKSPACE_BUILD_TYPES[context.build.buildType].jobs(context),
|
|
19157
|
+
(0, createPostBuildTestJobs_1.createPostBuildTestJobs)(context),
|
|
19158
|
+
]);
|
|
19159
|
+
(0, createPostBuildTestJobs_1.assertUniquePostBuildTestNames)(context, postBuildTestJobs, buildJobs);
|
|
19160
|
+
return [...buildJobs, ...postBuildTestJobs];
|
|
19054
19161
|
};
|
|
19055
19162
|
exports.createJobsForWorkspace = createJobsForWorkspace;
|
|
19056
19163
|
//# sourceMappingURL=createJobsForWorkspace.js.map
|
|
@@ -19519,6 +19626,7 @@ exports.resolveRequirements = void 0;
|
|
|
19519
19626
|
const DEFAULT_STAGE_CAPABILITIES = {
|
|
19520
19627
|
build: "build",
|
|
19521
19628
|
test: "qualityGate",
|
|
19629
|
+
"post-build": "qualityGate",
|
|
19522
19630
|
deploy: "deployment",
|
|
19523
19631
|
};
|
|
19524
19632
|
/**
|
|
@@ -19660,6 +19768,216 @@ exports.getWorkspaceDependencies = getWorkspaceDependencies;
|
|
|
19660
19768
|
|
|
19661
19769
|
/***/ }),
|
|
19662
19770
|
|
|
19771
|
+
/***/ 61844:
|
|
19772
|
+
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
|
19773
|
+
|
|
19774
|
+
"use strict";
|
|
19775
|
+
|
|
19776
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
19777
|
+
exports.assertUniquePostBuildTestNames = exports.createPostBuildTestJobs = exports.postBuildTestJobName = exports.POST_BUILD_TEST_STAGE = void 0;
|
|
19778
|
+
const createArtifactsConfig_1 = __nccwpck_require__(14149);
|
|
19779
|
+
const cache_1 = __nccwpck_require__(74559);
|
|
19780
|
+
const constants_1 = __nccwpck_require__(5576);
|
|
19781
|
+
const packageManagerInstall_1 = __nccwpck_require__(28419);
|
|
19782
|
+
const types_1 = __nccwpck_require__(35249);
|
|
19783
|
+
const runner_1 = __nccwpck_require__(92146);
|
|
19784
|
+
const jobs_1 = __nccwpck_require__(98521);
|
|
19785
|
+
const utils_1 = __nccwpck_require__(49401);
|
|
19786
|
+
exports.POST_BUILD_TEST_STAGE = "post-build";
|
|
19787
|
+
const postBuildTestJobName = (name) => `🔬 ${name}`;
|
|
19788
|
+
exports.postBuildTestJobName = postBuildTestJobName;
|
|
19789
|
+
const getPostBuildTestsConfig = (context) => {
|
|
19790
|
+
if (context.type === "workspace") {
|
|
19791
|
+
return context.build.config.postBuildTests;
|
|
19792
|
+
}
|
|
19793
|
+
if (context.build.type === "disabled") {
|
|
19794
|
+
return undefined;
|
|
19795
|
+
}
|
|
19796
|
+
return context.build.config.postBuildTests;
|
|
19797
|
+
};
|
|
19798
|
+
/**
|
|
19799
|
+
* whether the build output is a node project, so the job has to install
|
|
19800
|
+
* the dependencies before running the tests
|
|
19801
|
+
*/
|
|
19802
|
+
const isNodeBuild = (context) => {
|
|
19803
|
+
if (context.type === "workspace") {
|
|
19804
|
+
return true; // workspace builds are node builds
|
|
19805
|
+
}
|
|
19806
|
+
if (context.build.type === "fromWorkspace") {
|
|
19807
|
+
return true;
|
|
19808
|
+
}
|
|
19809
|
+
if (context.build.type === "standalone") {
|
|
19810
|
+
return (0, types_1.isOfBuildType)(context.build.config, "node", "node-static", "storybook", "meteor");
|
|
19811
|
+
}
|
|
19812
|
+
return false;
|
|
19813
|
+
};
|
|
19814
|
+
const hasBuildCommand = (buildCommand) => buildCommand !== null && buildCommand !== false;
|
|
19815
|
+
/**
|
|
19816
|
+
* whether the build creates an app build job with artifacts. Rails builds
|
|
19817
|
+
* and builds with `buildCommand: false` only build the docker image.
|
|
19818
|
+
*/
|
|
19819
|
+
const hasBuildArtifacts = (context) => {
|
|
19820
|
+
if (context.type === "workspace") {
|
|
19821
|
+
return hasBuildCommand(context.build.config.buildCommand);
|
|
19822
|
+
}
|
|
19823
|
+
if (context.build.type === "fromWorkspace") {
|
|
19824
|
+
return hasBuildCommand(context.build.workspaceBuildConfig.buildCommand);
|
|
19825
|
+
}
|
|
19826
|
+
if (context.build.type === "standalone") {
|
|
19827
|
+
return (!(0, types_1.isOfBuildType)(context.build.config, "rails") &&
|
|
19828
|
+
hasBuildCommand(context.build.config.buildCommand));
|
|
19829
|
+
}
|
|
19830
|
+
return false;
|
|
19831
|
+
};
|
|
19832
|
+
const getDefaultImage = (context) => {
|
|
19833
|
+
if (context.type === "component" &&
|
|
19834
|
+
context.build.type === "standalone" &&
|
|
19835
|
+
(0, types_1.isOfBuildType)(context.build.config, "custom")) {
|
|
19836
|
+
// custom builds bring their own toolchain image
|
|
19837
|
+
return context.build.config.jobImage;
|
|
19838
|
+
}
|
|
19839
|
+
return (0, runner_1.getRunnerImage)("jobs-default");
|
|
19840
|
+
};
|
|
19841
|
+
/**
|
|
19842
|
+
* jobs for `postBuildTests`: they run after the build in the `post-build`
|
|
19843
|
+
* stage, against the build artifacts, and act as quality gates, so a
|
|
19844
|
+
* failing post-build test blocks the deploy.
|
|
19845
|
+
*/
|
|
19846
|
+
const createPostBuildTestJobs = async (context) => {
|
|
19847
|
+
var _a;
|
|
19848
|
+
// like lint and test: tagged releases deploy what was already tested
|
|
19849
|
+
if (context.trigger === "taggedRelease") {
|
|
19850
|
+
return [];
|
|
19851
|
+
}
|
|
19852
|
+
const tests = Object.entries((_a = getPostBuildTestsConfig(context)) !== null && _a !== void 0 ? _a : {}).filter((entry) => entry[1] !== false);
|
|
19853
|
+
if (tests.length === 0) {
|
|
19854
|
+
return [];
|
|
19855
|
+
}
|
|
19856
|
+
const nodeBuild = isNodeBuild(context);
|
|
19857
|
+
const [packageManagerInstall, nodeCache] = nodeBuild
|
|
19858
|
+
? await Promise.all([
|
|
19859
|
+
(0, packageManagerInstall_1.getPackageManagerInstall)(context),
|
|
19860
|
+
// pull-only: the build job is the designated cache writer
|
|
19861
|
+
(0, cache_1.getNodeCache)(context, "pull"),
|
|
19862
|
+
])
|
|
19863
|
+
: [null, null];
|
|
19864
|
+
// components built in a workspace test the workspace build output
|
|
19865
|
+
const from = context.type === "component" && context.build.type === "fromWorkspace"
|
|
19866
|
+
? { workspace: context.build.workspaceName }
|
|
19867
|
+
: undefined;
|
|
19868
|
+
const buildRequirement = hasBuildArtifacts(context)
|
|
19869
|
+
? { capability: "buildArtifacts", artifacts: true, strict: true, from }
|
|
19870
|
+
: // no build artifacts (e.g. rails): run after the build (docker image)
|
|
19871
|
+
{ capability: "build", artifacts: false, from };
|
|
19872
|
+
return tests.map(([name, test]) => {
|
|
19873
|
+
var _a, _b, _c;
|
|
19874
|
+
const artifactsConfig = (0, createArtifactsConfig_1.createArtifactsConfig)(context.build.dir, test.artifactsReports, test.artifacts);
|
|
19875
|
+
return new jobs_1.CatladderJob({
|
|
19876
|
+
name: (0, exports.postBuildTestJobName)(name),
|
|
19877
|
+
stage: exports.POST_BUILD_TEST_STAGE,
|
|
19878
|
+
envMode: "stagePerEnv",
|
|
19879
|
+
provides: ["qualityGate"],
|
|
19880
|
+
needs: [],
|
|
19881
|
+
requires: [buildRequirement],
|
|
19882
|
+
image: (_a = test.jobImage) !== null && _a !== void 0 ? _a : getDefaultImage(context),
|
|
19883
|
+
services: test.services,
|
|
19884
|
+
// neutral cache declarations, lowered by each backend
|
|
19885
|
+
caches: nodeCache !== null && nodeCache !== void 0 ? nodeCache : undefined,
|
|
19886
|
+
variables: {
|
|
19887
|
+
APP_PATH: context.build.dir,
|
|
19888
|
+
...(context.type === "component"
|
|
19889
|
+
? context.environment.jobOnlyVars.build.envVars
|
|
19890
|
+
: {}),
|
|
19891
|
+
...((_b = test.vars) !== null && _b !== void 0 ? _b : {}),
|
|
19892
|
+
},
|
|
19893
|
+
runnerVariables: {
|
|
19894
|
+
...(nodeBuild ? constants_1.NODE_RUNNER_BUILD_VARIABLES : {}),
|
|
19895
|
+
...((_c = test.runnerVariables) !== null && _c !== void 0 ? _c : {}),
|
|
19896
|
+
},
|
|
19897
|
+
script: [
|
|
19898
|
+
...(nodeBuild ? (0, packageManagerInstall_1.ensureNodeVersion)(context) : []),
|
|
19899
|
+
`cd ${context.build.dir}`,
|
|
19900
|
+
...(packageManagerInstall !== null && packageManagerInstall !== void 0 ? packageManagerInstall : []),
|
|
19901
|
+
...(0, utils_1.ensureArray)(test.command),
|
|
19902
|
+
],
|
|
19903
|
+
allow_failure: test.allowFailure,
|
|
19904
|
+
// reports and screenshots are most needed when the tests fail
|
|
19905
|
+
...(artifactsConfig
|
|
19906
|
+
? {
|
|
19907
|
+
artifacts: {
|
|
19908
|
+
when: "always",
|
|
19909
|
+
...artifactsConfig.artifacts,
|
|
19910
|
+
},
|
|
19911
|
+
}
|
|
19912
|
+
: {}),
|
|
19913
|
+
});
|
|
19914
|
+
});
|
|
19915
|
+
};
|
|
19916
|
+
exports.createPostBuildTestJobs = createPostBuildTestJobs;
|
|
19917
|
+
const jobIdOf = (jobName) => jobName
|
|
19918
|
+
.toLowerCase()
|
|
19919
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
19920
|
+
.replace(/^-+|-+$/g, "");
|
|
19921
|
+
/**
|
|
19922
|
+
* post-build test names are chosen by the user. Github job ids drop the
|
|
19923
|
+
* emoji of the job name, so e.g. a post-build test named `test` would
|
|
19924
|
+
* clash with the `🧪 test` job.
|
|
19925
|
+
*/
|
|
19926
|
+
const assertUniquePostBuildTestNames = (context, postBuildTestJobs, otherJobs) => {
|
|
19927
|
+
const seenIds = new Set(otherJobs.map((job) => jobIdOf(job.name)));
|
|
19928
|
+
// also catches two post-build tests that only differ in case or
|
|
19929
|
+
// punctuation (e.g. `e2e` and `E2E`)
|
|
19930
|
+
const clash = postBuildTestJobs.find((job) => {
|
|
19931
|
+
const id = jobIdOf(job.name);
|
|
19932
|
+
const isClash = seenIds.has(id);
|
|
19933
|
+
seenIds.add(id);
|
|
19934
|
+
return isClash;
|
|
19935
|
+
});
|
|
19936
|
+
if (clash) {
|
|
19937
|
+
throw new Error(`${context.name}: post-build test '${clash.name}' clashes with another job of the same name, please rename it in postBuildTests`);
|
|
19938
|
+
}
|
|
19939
|
+
};
|
|
19940
|
+
exports.assertUniquePostBuildTestNames = assertUniquePostBuildTestNames;
|
|
19941
|
+
//# sourceMappingURL=createPostBuildTestJobs.js.map
|
|
19942
|
+
|
|
19943
|
+
/***/ }),
|
|
19944
|
+
|
|
19945
|
+
/***/ 28458:
|
|
19946
|
+
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
|
19947
|
+
|
|
19948
|
+
"use strict";
|
|
19949
|
+
|
|
19950
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
19951
|
+
if (k2 === undefined) k2 = k;
|
|
19952
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
19953
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
19954
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
19955
|
+
}
|
|
19956
|
+
Object.defineProperty(o, k2, desc);
|
|
19957
|
+
}) : (function(o, m, k, k2) {
|
|
19958
|
+
if (k2 === undefined) k2 = k;
|
|
19959
|
+
o[k2] = m[k];
|
|
19960
|
+
}));
|
|
19961
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
19962
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
19963
|
+
};
|
|
19964
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
19965
|
+
__exportStar(__nccwpck_require__(92967), exports);
|
|
19966
|
+
__exportStar(__nccwpck_require__(61844), exports);
|
|
19967
|
+
//# sourceMappingURL=index.js.map
|
|
19968
|
+
|
|
19969
|
+
/***/ }),
|
|
19970
|
+
|
|
19971
|
+
/***/ 92967:
|
|
19972
|
+
/***/ ((__unused_webpack_module, exports) => {
|
|
19973
|
+
|
|
19974
|
+
"use strict";
|
|
19975
|
+
|
|
19976
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
19977
|
+
//# sourceMappingURL=types.js.map
|
|
19978
|
+
|
|
19979
|
+
/***/ }),
|
|
19980
|
+
|
|
19663
19981
|
/***/ 26041:
|
|
19664
19982
|
/***/ ((__unused_webpack_module, exports) => {
|
|
19665
19983
|
|
|
@@ -19993,6 +20311,7 @@ exports.BASE_STAGES = [
|
|
|
19993
20311
|
"setup",
|
|
19994
20312
|
"test",
|
|
19995
20313
|
"build",
|
|
20314
|
+
"post-build",
|
|
19996
20315
|
"deploy",
|
|
19997
20316
|
"verify",
|
|
19998
20317
|
"agents",
|
|
File without changes
|
package/dist/bundles/cli/xsel
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: catladder-builds
|
|
3
|
-
description: Configuring how a component is built in a catladder project — the `build` config in catladder.ts (build types node / rails / meteor / custom, build & start commands, artifacts, caching, lint/test/audit jobs, the Docker image, project-declared job images, and shared workspace builds). Use when adding or changing a component's build, choosing a build type, wiring a Dockerfile/nginx image, declaring a custom CI job image (`images` config), tuning the build/test/lint jobs, or setting up a monorepo workspace build. Triggers on "build config", "buildCommand", "build type", "Dockerfile", "docker image", "job image", "jobImage", "custom image", "project image", "rails build", "monorepo build", "artifacts".
|
|
3
|
+
description: Configuring how a component is built in a catladder project — the `build` config in catladder.ts (build types node / rails / meteor / custom, build & start commands, artifacts, caching, lint/test/audit jobs, the Docker image, project-declared job images, and shared workspace builds). Use when adding or changing a component's build, choosing a build type, wiring a Dockerfile/nginx image, declaring a custom CI job image (`images` config), tuning the build/test/lint jobs, adding e2e tests against the build (`postBuildTests`), or setting up a monorepo workspace build. Triggers on "build config", "postBuildTests", "post-build test", "e2e", "playwright", "buildCommand", "build type", "Dockerfile", "docker image", "job image", "jobImage", "custom image", "project image", "rails build", "monorepo build", "artifacts".
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Component builds with catladder
|
|
@@ -66,6 +66,10 @@ type: `build: { from: "web" }` (see workspace builds below).
|
|
|
66
66
|
won't run).
|
|
67
67
|
- `lint` / `test` / `audit` — customize (`{ command, jobImage, … }`) or
|
|
68
68
|
set to `false` to disable that job.
|
|
69
|
+
- `postBuildTests` — named tests against the **build output** (e.g. an
|
|
70
|
+
e2e suite against the production build with a Postgres service). Each
|
|
71
|
+
entry becomes a job in the `post-build` stage between build and deploy
|
|
72
|
+
and blocks the deploy when it fails (see below).
|
|
69
73
|
- `artifactsPaths` / `artifactsExcludePaths` — extra build artifacts
|
|
70
74
|
(`dist` and `.next` are always included).
|
|
71
75
|
- `cache` — build caching (see the `catladder-pipelines` skill for the
|
|
@@ -82,11 +86,55 @@ type: `build: { from: "web" }` (see workspace builds below).
|
|
|
82
86
|
(`{ type: "nginx" | "node" | "meteor" }`) or
|
|
83
87
|
`{ type: "custom" }` (expects a `Dockerfile`).
|
|
84
88
|
|
|
89
|
+
## Post-build tests (e2e against the build)
|
|
90
|
+
|
|
91
|
+
`lint`/`test` run against the sources, in parallel with the build. Tests
|
|
92
|
+
that need the built app go into `postBuildTests`:
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
build: {
|
|
96
|
+
type: "node",
|
|
97
|
+
postBuildTests: {
|
|
98
|
+
e2e: {
|
|
99
|
+
command: "pnpm test:e2e", // runs in the build dir
|
|
100
|
+
jobImage: "mcr.microsoft.com/playwright:v1.56.0-noble",
|
|
101
|
+
services: [{ name: "postgres:17", alias: "postgres",
|
|
102
|
+
variables: { POSTGRES_PASSWORD: "postgres" } }],
|
|
103
|
+
vars: { DATABASE_URL: "postgres://postgres:postgres@postgres:5432/postgres" },
|
|
104
|
+
artifacts: { paths: ["apps/web/playwright-report"] }, // repo-root relative
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
- The job (`🔬 e2e`, stage `post-build <env>`) downloads the build
|
|
111
|
+
artifacts (`.next`, `dist`, `artifactsPaths`), installs dependencies
|
|
112
|
+
for node builds, then runs `command`. The command starts the app
|
|
113
|
+
itself, e.g. playwright `webServer: { command: "pnpm start" }`.
|
|
114
|
+
Builds without artifacts (`rails`, `buildCommand: false`) just run
|
|
115
|
+
it after the build.
|
|
116
|
+
- It is a quality gate: the env's deploy waits for it; on github it is
|
|
117
|
+
part of the `catladder ✅` required check. `allowFailure: true` makes
|
|
118
|
+
it report-only.
|
|
119
|
+
- It gets the build vars plus `vars`, **not** the deployed env's
|
|
120
|
+
runtime vars/secrets — use services instead of the real database.
|
|
121
|
+
- Artifacts are uploaded also when the job fails.
|
|
122
|
+
- Not run in tagged releases. Disable one per env:
|
|
123
|
+
`env: { dev: { build: { postBuildTests: { e2e: false } } } }`.
|
|
124
|
+
- Names must not clash with other jobs of the component (e.g. `test`,
|
|
125
|
+
`lint`) — generation fails with a clear error.
|
|
126
|
+
- Workspace builds: on `builds.<ws>` they block the deploys of all
|
|
127
|
+
components in the workspace; on `build: { from: "<ws>", postBuildTests }`
|
|
128
|
+
only that component's deploy.
|
|
129
|
+
- To test the **deployed** env instead (smoke tests on dev / review
|
|
130
|
+
apps), use the component's `verify` (post-deploy, does not block the
|
|
131
|
+
deploy). The same suite can serve both, with `BASE_URL` as the switch.
|
|
132
|
+
|
|
85
133
|
## Project images (custom CI job images)
|
|
86
134
|
|
|
87
135
|
When a job needs a toolchain catladder doesn't ship (Java, Playwright,
|
|
88
136
|
…), declare a Docker image at the top level under `images` and reference
|
|
89
|
-
it in any `jobImage` field (build, `test.jobImage`, custom/pages deploy,
|
|
137
|
+
it in any `jobImage` field (build, `test.jobImage`, `postBuildTests`, custom/pages deploy,
|
|
90
138
|
verify):
|
|
91
139
|
|
|
92
140
|
```ts
|
|
@@ -12,6 +12,7 @@ generated pipeline files.
|
|
|
12
12
|
| `startCommand` | `string` | runtime start command |
|
|
13
13
|
| `postInstall` | `string \| string[]` | runs after the package-manager install (node family) |
|
|
14
14
|
| `lint` / `test` / `audit` | `false \| TestJobCustom` | customize or disable the job |
|
|
15
|
+
| `postBuildTests` | `Record<string, PostBuildTestConfig \| false>` | named tests against the build output in the `post-build` stage; block the deploy |
|
|
15
16
|
| `artifactsPaths` | `string[]` | extra artifacts (`dist`, `.next` always included) |
|
|
16
17
|
| `artifactsExcludePaths` | `string[]` | artifact excludes |
|
|
17
18
|
| `artifactsReports` | `{ junit?: string[] }` | CI test report paths |
|
|
@@ -27,6 +28,13 @@ generated pipeline files.
|
|
|
27
28
|
`artifactsReports`, `artifacts`, `runnerVariables`, `allowFailure`
|
|
28
29
|
(`allowFailure` defaults to `true` for `audit`).
|
|
29
30
|
|
|
31
|
+
`PostBuildTestConfig` (for `postBuildTests` entries): `TestJobCustom` with
|
|
32
|
+
a required `command`, plus `services?: Services` (gitlab shape, reachable
|
|
33
|
+
by alias) and `vars?: Record<string,string>`. The job gets the build
|
|
34
|
+
artifacts, the build vars and `vars` (not the deployed env's runtime
|
|
35
|
+
vars), installs dependencies for node builds, and uploads `artifacts`
|
|
36
|
+
also on failure.
|
|
37
|
+
|
|
30
38
|
`audit` additionally takes `level`: `"info" | "low" | "moderate" | "high" |
|
|
31
39
|
"critical"` (default `"critical"`) — the lowest severity that fails the job,
|
|
32
40
|
translated to the package manager's own flag (`pnpm audit --audit-level`,
|
|
@@ -81,5 +89,5 @@ defaulted `buildCommand: "yarn build-storybook --quiet -o ./dist"`.
|
|
|
81
89
|
Top-level `builds: Record<string, WorkspaceBuildConfig>`. Only
|
|
82
90
|
`type: "node"` is supported.
|
|
83
91
|
|
|
84
|
-
- Node workspace build: `dir?`, `buildCommand?` (default `<pm> build`), `dockerDefaults?: { yarnRebuildEnabled }`, plus shared `lint?` (default `{ command: "<pm> lint" }`), `test?` (default `{ command: "<pm> test" }`), `audit?`, `runnerVariables?`, `artifactsReports?`, `jobImage?`, `jobTags?`, `cache?` (`<pm>` = `yarn`/`pnpm` per detection).
|
|
85
|
-
- A component references it via `build: { from: "<name>", docker?, startCommand?, artifactsPaths?, artifactsExcludePaths?, cache? }` — the per-component overrides layer on top of the shared build.
|
|
92
|
+
- Node workspace build: `dir?`, `buildCommand?` (default `<pm> build`), `dockerDefaults?: { yarnRebuildEnabled }`, plus shared `lint?` (default `{ command: "<pm> lint" }`), `test?` (default `{ command: "<pm> test" }`), `audit?`, `postBuildTests?` (block the deploys of all its components), `runnerVariables?`, `artifactsReports?`, `jobImage?`, `jobTags?`, `cache?` (`<pm>` = `yarn`/`pnpm` per detection).
|
|
93
|
+
- A component references it via `build: { from: "<name>", docker?, startCommand?, artifactsPaths?, artifactsExcludePaths?, cache?, postBuildTests? }` — the per-component overrides layer on top of the shared build.
|