@simplysf/simply-cicd-core 0.2.1 → 0.3.1
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/README.md +35 -7
- package/lib/build/checkPermissionSets.d.ts +22 -0
- package/lib/build/checkPermissionSets.js +102 -0
- package/lib/build/checkPermissionSets.js.map +1 -0
- package/lib/build/cleanupScratchOrgs.d.ts +6 -0
- package/lib/build/cleanupScratchOrgs.js +91 -0
- package/lib/build/cleanupScratchOrgs.js.map +1 -0
- package/lib/build/createFallbackTag.d.ts +24 -0
- package/lib/build/createFallbackTag.js +147 -0
- package/lib/build/createFallbackTag.js.map +1 -0
- package/lib/build/createPackageVersion.d.ts +42 -0
- package/lib/build/createPackageVersion.js +198 -0
- package/lib/build/createPackageVersion.js.map +1 -0
- package/lib/build/createScratchOrg.d.ts +14 -0
- package/lib/build/createScratchOrg.js +192 -0
- package/lib/build/createScratchOrg.js.map +1 -0
- package/lib/build/deleteScratchOrg.d.ts +13 -0
- package/lib/build/deleteScratchOrg.js +62 -0
- package/lib/build/deleteScratchOrg.js.map +1 -0
- package/lib/build/deltaRunner.d.ts +73 -0
- package/lib/build/deltaRunner.js +109 -0
- package/lib/build/deltaRunner.js.map +1 -0
- package/lib/build/determinePackageChanges.d.ts +11 -0
- package/lib/build/determinePackageChanges.js +90 -0
- package/lib/build/determinePackageChanges.js.map +1 -0
- package/lib/build/devHubs.d.ts +12 -0
- package/lib/build/devHubs.js +42 -0
- package/lib/build/devHubs.js.map +1 -0
- package/lib/build/flexipageDelta.d.ts +18 -0
- package/lib/build/flexipageDelta.js +35 -0
- package/lib/build/flexipageDelta.js.map +1 -0
- package/lib/build/flowDelta.d.ts +17 -0
- package/lib/build/flowDelta.js +34 -0
- package/lib/build/flowDelta.js.map +1 -0
- package/lib/build/installDependencies.d.ts +10 -0
- package/lib/build/installDependencies.js +39 -0
- package/lib/build/installDependencies.js.map +1 -0
- package/lib/build/lwcJest.d.ts +25 -0
- package/lib/build/lwcJest.js +126 -0
- package/lib/build/lwcJest.js.map +1 -0
- package/lib/build/publishUtamPageObjects.d.ts +50 -0
- package/lib/build/publishUtamPageObjects.js +283 -0
- package/lib/build/publishUtamPageObjects.js.map +1 -0
- package/lib/build/pushScratch.d.ts +9 -0
- package/lib/build/pushScratch.js +60 -0
- package/lib/build/pushScratch.js.map +1 -0
- package/lib/build/scratchOrgAuth.d.ts +18 -0
- package/lib/build/scratchOrgAuth.js +52 -0
- package/lib/build/scratchOrgAuth.js.map +1 -0
- package/lib/build/scratchOrgInfo.d.ts +14 -0
- package/lib/build/scratchOrgInfo.js +21 -0
- package/lib/build/scratchOrgInfo.js.map +1 -0
- package/lib/build/skipGuard.d.ts +8 -0
- package/lib/build/skipGuard.js +42 -0
- package/lib/build/skipGuard.js.map +1 -0
- package/lib/build/testScratch.d.ts +15 -0
- package/lib/build/testScratch.js +42 -0
- package/lib/build/testScratch.js.map +1 -0
- package/lib/build/utamPageObjects.d.ts +143 -0
- package/lib/build/utamPageObjects.js +258 -0
- package/lib/build/utamPageObjects.js.map +1 -0
- package/lib/build/versionTagFormat.d.ts +57 -0
- package/lib/build/versionTagFormat.js +194 -0
- package/lib/build/versionTagFormat.js.map +1 -0
- package/lib/config/defaultDeploymentPlugins.d.ts +2 -0
- package/lib/config/defaultDeploymentPlugins.js +18 -0
- package/lib/config/defaultDeploymentPlugins.js.map +1 -0
- package/lib/config/trustedPlugins.d.ts +2 -0
- package/lib/config/trustedPlugins.js +18 -0
- package/lib/config/trustedPlugins.js.map +1 -0
- package/lib/deploy/deployCommon.d.ts +105 -0
- package/lib/deploy/deployCommon.js +358 -0
- package/lib/deploy/deployCommon.js.map +1 -0
- package/lib/deploy/deployHappySoup.d.ts +56 -0
- package/lib/deploy/deployHappySoup.js +160 -0
- package/lib/deploy/deployHappySoup.js.map +1 -0
- package/lib/deploy/deployProject.d.ts +27 -0
- package/lib/deploy/deployProject.js +114 -0
- package/lib/deploy/deployProject.js.map +1 -0
- package/lib/deploy/runDeployStage.d.ts +16 -0
- package/lib/deploy/runDeployStage.js +65 -0
- package/lib/deploy/runDeployStage.js.map +1 -0
- package/lib/deploy/stageOptions.d.ts +49 -0
- package/lib/deploy/stageOptions.js +70 -0
- package/lib/deploy/stageOptions.js.map +1 -0
- package/lib/deploy/validate.d.ts +11 -0
- package/lib/deploy/validate.js +54 -0
- package/lib/deploy/validate.js.map +1 -0
- package/lib/env.d.ts +9 -0
- package/lib/env.js +47 -0
- package/lib/env.js.map +1 -0
- package/lib/exec/sfCli.d.ts +27 -0
- package/lib/exec/sfCli.js +50 -0
- package/lib/exec/sfCli.js.map +1 -0
- package/lib/flags/env.d.ts +44 -0
- package/lib/flags/env.js +81 -0
- package/lib/flags/env.js.map +1 -0
- package/lib/git.d.ts +32 -0
- package/lib/git.js +106 -0
- package/lib/git.js.map +1 -0
- package/lib/happySoup/resolveOriginProject.d.ts +22 -0
- package/lib/happySoup/resolveOriginProject.js +61 -0
- package/lib/happySoup/resolveOriginProject.js.map +1 -0
- package/lib/index.d.ts +51 -0
- package/lib/index.js +63 -2
- package/lib/index.js.map +1 -1
- package/lib/logger.d.ts +10 -0
- package/lib/logger.js +33 -0
- package/lib/logger.js.map +1 -0
- package/lib/notify/buildNotification.d.ts +53 -0
- package/lib/notify/buildNotification.js +176 -0
- package/lib/notify/buildNotification.js.map +1 -0
- package/lib/notify/getCommitStories.d.ts +30 -0
- package/lib/notify/getCommitStories.js +70 -0
- package/lib/notify/getCommitStories.js.map +1 -0
- package/lib/notify/getRemoteCommitStories.d.ts +10 -0
- package/lib/notify/getRemoteCommitStories.js +45 -0
- package/lib/notify/getRemoteCommitStories.js.map +1 -0
- package/lib/notify/happySoupNotification.d.ts +26 -0
- package/lib/notify/happySoupNotification.js +140 -0
- package/lib/notify/happySoupNotification.js.map +1 -0
- package/lib/notify/projectNotification.d.ts +46 -0
- package/lib/notify/projectNotification.js +177 -0
- package/lib/notify/projectNotification.js.map +1 -0
- package/lib/notify/renderTemplate.d.ts +3 -0
- package/lib/notify/renderTemplate.js +24 -0
- package/lib/notify/renderTemplate.js.map +1 -0
- package/lib/notify/sendNotification.d.ts +2 -0
- package/lib/notify/sendNotification.js +50 -0
- package/lib/notify/sendNotification.js.map +1 -0
- package/lib/notify/templates.d.ts +13 -0
- package/lib/notify/templates.js +118 -0
- package/lib/notify/templates.js.map +1 -0
- package/lib/schemas/deployConfig.d.ts +25 -0
- package/lib/schemas/deployConfig.js +55 -0
- package/lib/schemas/deployConfig.js.map +1 -0
- package/lib/schemas/deployProgress.d.ts +33 -0
- package/lib/schemas/deployProgress.js +46 -0
- package/lib/schemas/deployProgress.js.map +1 -0
- package/lib/schemas/deployRules.d.ts +34 -0
- package/lib/schemas/deployRules.js +40 -0
- package/lib/schemas/deployRules.js.map +1 -0
- package/lib/sfApex.d.ts +22 -0
- package/lib/sfApex.js +169 -0
- package/lib/sfApex.js.map +1 -0
- package/lib/sfAuth.d.ts +19 -0
- package/lib/sfAuth.js +78 -0
- package/lib/sfAuth.js.map +1 -0
- package/lib/sfConfig.d.ts +23 -0
- package/lib/sfConfig.js +82 -0
- package/lib/sfConfig.js.map +1 -0
- package/lib/sfPackages.d.ts +31 -0
- package/lib/sfPackages.js +143 -0
- package/lib/sfPackages.js.map +1 -0
- package/lib/sfPlugins.d.ts +11 -0
- package/lib/sfPlugins.js +134 -0
- package/lib/sfPlugins.js.map +1 -0
- package/lib/sfdxDependabot/dependabotRun.d.ts +95 -0
- package/lib/sfdxDependabot/dependabotRun.js +287 -0
- package/lib/sfdxDependabot/dependabotRun.js.map +1 -0
- package/lib/sfdxDependabot/updater.d.ts +14 -0
- package/lib/sfdxDependabot/updater.js +94 -0
- package/lib/sfdxDependabot/updater.js.map +1 -0
- package/package.json +18 -7
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2026, SimplySF.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { execa } from 'execa';
|
|
17
|
+
import { createVcsProvider } from '../vcs/index.js';
|
|
18
|
+
import { logger } from '../logger.js';
|
|
19
|
+
import { installFlowDeltaPlugin } from '../sfPlugins.js';
|
|
20
|
+
export const FLOW_DELTA = {
|
|
21
|
+
binary: 'flow-delta',
|
|
22
|
+
path: '**/*.flow-meta.xml',
|
|
23
|
+
defaultOut: 'flow-delta-out',
|
|
24
|
+
label: 'Flow',
|
|
25
|
+
};
|
|
26
|
+
export const FLEXIPAGE_DELTA = {
|
|
27
|
+
binary: 'flexipage-delta',
|
|
28
|
+
path: '**/*.flexipage-meta.xml',
|
|
29
|
+
defaultOut: 'flexipage-delta-out',
|
|
30
|
+
label: 'Flexipage',
|
|
31
|
+
};
|
|
32
|
+
/** Appends `--flag value` only when a value is present, so the reporter's env fallbacks still apply. */
|
|
33
|
+
function pushIfPresent(args, flag, value) {
|
|
34
|
+
if (value) {
|
|
35
|
+
args.push(flag, value);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Builds the reporter argv for the selected platform. The two reporters take different context
|
|
40
|
+
* flags — GitLab addresses a merge request by project ID and IID, GitHub a pull request by
|
|
41
|
+
* `owner/repo` and number — which is the whole reason this is routed through the VCS choice.
|
|
42
|
+
*/
|
|
43
|
+
export function buildReporterArgs(kind, out, context) {
|
|
44
|
+
const args = ['--in', out];
|
|
45
|
+
pushIfPresent(args, '--token', context.projectAccessToken);
|
|
46
|
+
pushIfPresent(args, '--commit-sha', context.commitSha);
|
|
47
|
+
// Ask the provider where its API lives rather than rebuilding the URL here.
|
|
48
|
+
if (context.projectAccessToken) {
|
|
49
|
+
const { apiUrl } = createVcsProvider(kind, { host: context.vcsHost, token: context.projectAccessToken });
|
|
50
|
+
args.push('--api-url', apiUrl);
|
|
51
|
+
}
|
|
52
|
+
if (kind === 'github') {
|
|
53
|
+
pushIfPresent(args, '--repo', context.ciRepository);
|
|
54
|
+
pushIfPresent(args, '--pr', context.ciPullRequestNumber);
|
|
55
|
+
pushIfPresent(args, '--run-id', context.ciRunId);
|
|
56
|
+
pushIfPresent(args, '--server-url', context.ciServerUrl);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
pushIfPresent(args, '--project-id', context.ciProjectId);
|
|
60
|
+
pushIfPresent(args, '--mr-iid', context.ciMergeRequestIid);
|
|
61
|
+
}
|
|
62
|
+
return args;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Runs a delta tool: the diff binary over the `from..to` range, then the reporter binary for the
|
|
66
|
+
* selected platform to post the result back to the change request. Does not catch its own errors;
|
|
67
|
+
* callers decide how to handle them.
|
|
68
|
+
*/
|
|
69
|
+
export async function runDelta(tool, options) {
|
|
70
|
+
const { from, to, out = tool.defaultOut, debug = false, vcsProvider = 'gitlab' } = options;
|
|
71
|
+
if (!from || !to) {
|
|
72
|
+
throw new Error('Missing "from" or "to" commit SHA. Provide --from/--to arguments.');
|
|
73
|
+
}
|
|
74
|
+
await installFlowDeltaPlugin(debug);
|
|
75
|
+
await execa(tool.binary, ['--repo', '.', '--from', from, '--to', to, '--path', tool.path, '--changed-only', '--out', out, '--json'], { stdio: 'inherit' });
|
|
76
|
+
await execa(`${tool.binary}-${vcsProvider}`, buildReporterArgs(vcsProvider, out, options), { stdio: 'inherit' });
|
|
77
|
+
}
|
|
78
|
+
function extractErrorMessage(error, tool) {
|
|
79
|
+
if (error instanceof Error && error.message) {
|
|
80
|
+
return error.message;
|
|
81
|
+
}
|
|
82
|
+
if (typeof error === 'string') {
|
|
83
|
+
return error;
|
|
84
|
+
}
|
|
85
|
+
return `Unknown error running ${tool.binary}`;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Action-handler wrapper around `runDelta`: checks the job-level skip flag, then runs the delta and
|
|
89
|
+
* logs (rather than throws) on failure, since a diff-posting step shouldn't fail the build.
|
|
90
|
+
*/
|
|
91
|
+
export async function generateDiff(tool, options) {
|
|
92
|
+
const lowerLabel = tool.label.toLowerCase();
|
|
93
|
+
if (options.disabled) {
|
|
94
|
+
logger.info(`${tool.label} diff generation is disabled. Skipping.`);
|
|
95
|
+
return { skipped: true, success: false };
|
|
96
|
+
}
|
|
97
|
+
logger.info(`Generating ${lowerLabel} diff using ${tool.binary}...`);
|
|
98
|
+
try {
|
|
99
|
+
await runDelta(tool, options);
|
|
100
|
+
logger.success(`${tool.label} diff generation completed.`);
|
|
101
|
+
return { skipped: false, success: true };
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
logger.error(`${tool.label} diff generation failed.`);
|
|
105
|
+
logger.error(extractErrorMessage(error, tool));
|
|
106
|
+
return { skipped: false, success: false };
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=deltaRunner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deltaRunner.js","sourceRoot":"","sources":["../../src/build/deltaRunner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAE,iBAAiB,EAAwB,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAiBzD,MAAM,CAAC,MAAM,UAAU,GAAc;IACnC,MAAM,EAAE,YAAY;IACpB,IAAI,EAAE,oBAAoB;IAC1B,UAAU,EAAE,gBAAgB;IAC5B,KAAK,EAAE,MAAM;CACd,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAc;IACxC,MAAM,EAAE,iBAAiB;IACzB,IAAI,EAAE,yBAAyB;IAC/B,UAAU,EAAE,qBAAqB;IACjC,KAAK,EAAE,WAAW;CACnB,CAAC;AAoCF,wGAAwG;AACxG,SAAS,aAAa,CAAC,IAAc,EAAE,IAAY,EAAE,KAAyB;IAC5E,IAAI,KAAK,EAAE,CAAC;QACV,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACzB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAqB,EAAE,GAAW,EAAE,OAA6B;IACjG,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,aAAa,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC3D,aAAa,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAEvD,4EAA4E;IAC5E,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC;QAC/B,MAAM,EAAE,MAAM,EAAE,GAAG,iBAAiB,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;QACzG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACjC,CAAC;IAED,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,aAAa,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;QACpD,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;QACzD,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QACjD,aAAa,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAC3D,CAAC;SAAM,CAAC;QACN,aAAa,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;QACzD,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAe,EAAE,OAAwB;IACtE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,GAAG,IAAI,CAAC,UAAU,EAAE,KAAK,GAAG,KAAK,EAAE,WAAW,GAAG,QAAQ,EAAE,GAAG,OAAO,CAAC;IAC3F,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAC;IACvF,CAAC;IAED,MAAM,sBAAsB,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,KAAK,CACT,IAAI,CAAC,MAAM,EACX,CAAC,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,CAAC,EAC1G,EAAE,KAAK,EAAE,SAAS,EAAE,CACrB,CAAC;IAEF,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,WAAW,EAAE,EAAE,iBAAiB,CAAC,WAAW,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;AACnH,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAc,EAAE,IAAe;IAC1D,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAC5C,OAAO,KAAK,CAAC,OAAO,CAAC;IACvB,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,yBAAyB,IAAI,CAAC,MAAM,EAAE,CAAC;AAChD,CAAC;AAKD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAe,EAAE,OAA4B;IAC9E,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;IAE5C,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,yCAAyC,CAAC,CAAC;QACpE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC3C,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,cAAc,UAAU,eAAe,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC;IACrE,IAAI,CAAC;QACH,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC9B,MAAM,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,6BAA6B,CAAC,CAAC;QAC3D,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,0BAA0B,CAAC,CAAC;QACtD,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;QAC/C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC5C,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type DeterminePackageChangesOptions = {
|
|
2
|
+
out?: string;
|
|
3
|
+
debug?: boolean;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Detects whether any files under the default package directory (or `sfdx-project.json` itself)
|
|
7
|
+
* have changed since the last release tag, and writes the result as a dotenv file. Any failure
|
|
8
|
+
* during detection (missing/invalid sfdx-project.json, git errors) defaults to `PACKAGE_CHANGED=TRUE`
|
|
9
|
+
* so a build never silently skips work it should have done.
|
|
10
|
+
*/
|
|
11
|
+
export declare function determinePackageChanges(options: DeterminePackageChangesOptions): Promise<void>;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2026, SimplySF.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { promises as fs } from 'node:fs';
|
|
17
|
+
import { execa } from 'execa';
|
|
18
|
+
import { getDefaultPackageDirectory, readSfdxProject } from '@simplysf/simply-core';
|
|
19
|
+
import { logger } from '../logger.js';
|
|
20
|
+
import { VersionTagFormat } from './versionTagFormat.js';
|
|
21
|
+
async function resolveLastTag(tagMatchPattern) {
|
|
22
|
+
try {
|
|
23
|
+
const { stdout } = await execa('git', ['describe', '--tags', '--abbrev=0', '--match', tagMatchPattern]);
|
|
24
|
+
return stdout.trim();
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
logger.info(`No previous release tag (${tagMatchPattern}) found. A full package build is required.`);
|
|
28
|
+
return '';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async function detectChangesSincePackagePath(packagePath, lastTag) {
|
|
32
|
+
logger.info(`Running git diff on path: "${packagePath}" and "sfdx-project.json"`);
|
|
33
|
+
const { stdout: diffOutput } = await execa('git', [
|
|
34
|
+
'diff',
|
|
35
|
+
'--name-only',
|
|
36
|
+
lastTag,
|
|
37
|
+
'HEAD',
|
|
38
|
+
'--',
|
|
39
|
+
packagePath,
|
|
40
|
+
'sfdx-project.json',
|
|
41
|
+
]);
|
|
42
|
+
if (diffOutput.trim().length > 0) {
|
|
43
|
+
logger.info(`Changes detected in package directory or project config:\n${diffOutput}`);
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
logger.success('No changes detected in package directory or project config.');
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
async function detectPackageChanges() {
|
|
50
|
+
const projectJson = await readSfdxProject();
|
|
51
|
+
const defaultDir = getDefaultPackageDirectory(projectJson);
|
|
52
|
+
if (!defaultDir?.path) {
|
|
53
|
+
logger.warn('No default package directory found in sfdx-project.json. Defaulting to PACKAGE_CHANGED=FALSE.');
|
|
54
|
+
return { packageChanged: false, lastTag: '' };
|
|
55
|
+
}
|
|
56
|
+
logger.info('Fetching remote tags...');
|
|
57
|
+
await execa('git', ['fetch', '--tags']);
|
|
58
|
+
const tagMatchPattern = VersionTagFormat.fromProject(projectJson).matchPattern(defaultDir.versionNumber);
|
|
59
|
+
const lastTag = await resolveLastTag(tagMatchPattern);
|
|
60
|
+
if (!lastTag) {
|
|
61
|
+
return { packageChanged: true, lastTag: '' };
|
|
62
|
+
}
|
|
63
|
+
logger.info(`Last package tag found: ${lastTag}`);
|
|
64
|
+
const packageChanged = await detectChangesSincePackagePath(defaultDir.path, lastTag);
|
|
65
|
+
return { packageChanged, lastTag };
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Detects whether any files under the default package directory (or `sfdx-project.json` itself)
|
|
69
|
+
* have changed since the last release tag, and writes the result as a dotenv file. Any failure
|
|
70
|
+
* during detection (missing/invalid sfdx-project.json, git errors) defaults to `PACKAGE_CHANGED=TRUE`
|
|
71
|
+
* so a build never silently skips work it should have done.
|
|
72
|
+
*/
|
|
73
|
+
export async function determinePackageChanges(options) {
|
|
74
|
+
logger.info('Determining package changes...');
|
|
75
|
+
const outFile = options.out ?? 'changes.env';
|
|
76
|
+
let packageChanged;
|
|
77
|
+
let lastTag;
|
|
78
|
+
try {
|
|
79
|
+
({ packageChanged, lastTag } = await detectPackageChanges());
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
logger.error(`Error during change detection: ${err.message}. Defaulting to full build.`);
|
|
83
|
+
packageChanged = true;
|
|
84
|
+
lastTag = '';
|
|
85
|
+
}
|
|
86
|
+
const envContent = `PACKAGE_CHANGED=${packageChanged ? 'TRUE' : 'FALSE'}\nLAST_TAG=${lastTag}\n`;
|
|
87
|
+
await fs.writeFile(outFile, envContent, 'utf-8');
|
|
88
|
+
logger.success(`Wrote change detection results to ${outFile}`);
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=determinePackageChanges.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"determinePackageChanges.js","sourceRoot":"","sources":["../../src/build/determinePackageChanges.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type ResolvedDevHub = {
|
|
2
|
+
/** The alias (or username) the caller passed in. */
|
|
3
|
+
alias: string;
|
|
4
|
+
/** The Dev Hub's canonical username, resolved from the alias. */
|
|
5
|
+
username: string;
|
|
6
|
+
instanceUrl: string;
|
|
7
|
+
clientId?: string;
|
|
8
|
+
/** Only present when the Dev Hub was JWT-authenticated. */
|
|
9
|
+
privateKeyFile?: string;
|
|
10
|
+
};
|
|
11
|
+
/** Resolves multiple Dev Hub aliases in parallel. Each must already be authenticated. */
|
|
12
|
+
export declare function resolveDevHubs(aliases: string[]): Promise<ResolvedDevHub[]>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2026, SimplySF.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { AuthInfo } from '@salesforce/core';
|
|
17
|
+
/**
|
|
18
|
+
* Resolves a Dev Hub alias to its already-authenticated config. `simply-cicd` never authenticates
|
|
19
|
+
* Dev Hubs itself — the alias must already be authenticated (by the calling pipeline, however it
|
|
20
|
+
* chooses to do that: JWT, web, SFDX auth-url, or Client Credentials) before this runs.
|
|
21
|
+
*
|
|
22
|
+
* `clientId`/`instanceUrl`/`privateKey` are all stored in plaintext in a Dev Hub's `AuthInfo` (only
|
|
23
|
+
* token/password/secret-named fields are encrypted at rest), so no decryption is needed to read them.
|
|
24
|
+
*
|
|
25
|
+
* @throws {SfError} `NamedOrgNotFoundError` if the alias hasn't already been authenticated.
|
|
26
|
+
*/
|
|
27
|
+
async function resolveDevHub(alias) {
|
|
28
|
+
const authInfo = await AuthInfo.create({ username: alias });
|
|
29
|
+
const fields = authInfo.getFields();
|
|
30
|
+
return {
|
|
31
|
+
alias,
|
|
32
|
+
username: authInfo.getUsername(),
|
|
33
|
+
instanceUrl: fields.instanceUrl ?? '',
|
|
34
|
+
clientId: fields.clientId,
|
|
35
|
+
privateKeyFile: fields.privateKey,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/** Resolves multiple Dev Hub aliases in parallel. Each must already be authenticated. */
|
|
39
|
+
export async function resolveDevHubs(aliases) {
|
|
40
|
+
return Promise.all(aliases.map(resolveDevHub));
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=devHubs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"devHubs.js","sourceRoot":"","sources":["../../src/build/devHubs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAa5C;;;;;;;;;GASG;AACH,KAAK,UAAU,aAAa,CAAC,KAAa;IACxC,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,EAAE,CAAC;IAEpC,OAAO;QACL,KAAK;QACL,QAAQ,EAAE,QAAQ,CAAC,WAAW,EAAE;QAChC,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,EAAE;QACrC,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,cAAc,EAAE,MAAM,CAAC,UAAU;KAClC,CAAC;AACJ,CAAC;AAED,yFAAyF;AACzF,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAiB;IACpD,OAAO,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC;AACjD,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type GenerateDiffOptions, type GenerateDiffResult, type RunDeltaOptions } from './deltaRunner.js';
|
|
2
|
+
export type RunFlexipageDeltaOptions = RunDeltaOptions;
|
|
3
|
+
export type GenerateFlexipageDiffOptions = GenerateDiffOptions;
|
|
4
|
+
export type GenerateFlexipageDiffResult = GenerateDiffResult;
|
|
5
|
+
/**
|
|
6
|
+
* Runs the upstream `flexipage-delta` binary over the commit range, then the reporter binary for
|
|
7
|
+
* the selected VCS platform. Does not catch its own errors; callers decide how to handle them.
|
|
8
|
+
*/
|
|
9
|
+
export declare function runFlexipageDelta(options: RunFlexipageDeltaOptions): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Action-handler wrapper around `runFlexipageDelta`: checks the job-level skip flag, then runs the
|
|
12
|
+
* flexipage delta and logs (rather than throws) on failure, since a diff-posting step shouldn't
|
|
13
|
+
* fail the build.
|
|
14
|
+
*
|
|
15
|
+
* Fixes a bug from the original: the CLI wired its skip flag as `--disabled`, but this function
|
|
16
|
+
* checked `options.disableFlexipageDiff` — a property nothing ever set — so `--disabled` was a no-op.
|
|
17
|
+
*/
|
|
18
|
+
export declare function generateFlexipageDiff(options: GenerateFlexipageDiffOptions): Promise<GenerateFlexipageDiffResult>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2026, SimplySF.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { FLEXIPAGE_DELTA, generateDiff, runDelta, } from './deltaRunner.js';
|
|
17
|
+
/**
|
|
18
|
+
* Runs the upstream `flexipage-delta` binary over the commit range, then the reporter binary for
|
|
19
|
+
* the selected VCS platform. Does not catch its own errors; callers decide how to handle them.
|
|
20
|
+
*/
|
|
21
|
+
export async function runFlexipageDelta(options) {
|
|
22
|
+
return runDelta(FLEXIPAGE_DELTA, options);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Action-handler wrapper around `runFlexipageDelta`: checks the job-level skip flag, then runs the
|
|
26
|
+
* flexipage delta and logs (rather than throws) on failure, since a diff-posting step shouldn't
|
|
27
|
+
* fail the build.
|
|
28
|
+
*
|
|
29
|
+
* Fixes a bug from the original: the CLI wired its skip flag as `--disabled`, but this function
|
|
30
|
+
* checked `options.disableFlexipageDiff` — a property nothing ever set — so `--disabled` was a no-op.
|
|
31
|
+
*/
|
|
32
|
+
export async function generateFlexipageDiff(options) {
|
|
33
|
+
return generateDiff(FLEXIPAGE_DELTA, options);
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=flexipageDelta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flexipageDelta.js","sourceRoot":"","sources":["../../src/build/flexipageDelta.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EACL,eAAe,EACf,YAAY,EACZ,QAAQ,GAIT,MAAM,kBAAkB,CAAC;AAM1B;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,OAAiC;IACvE,OAAO,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,OAAqC;IAErC,OAAO,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type GenerateDiffOptions, type GenerateDiffResult, type RunDeltaOptions } from './deltaRunner.js';
|
|
2
|
+
export type RunFlowDeltaOptions = RunDeltaOptions;
|
|
3
|
+
export type GenerateFlowDiffOptions = GenerateDiffOptions;
|
|
4
|
+
export type GenerateFlowDiffResult = GenerateDiffResult;
|
|
5
|
+
/**
|
|
6
|
+
* Runs the upstream `flow-delta` binary over the commit range, then the reporter binary for the
|
|
7
|
+
* selected VCS platform. Does not catch its own errors; callers decide how to handle them.
|
|
8
|
+
*/
|
|
9
|
+
export declare function runFlowDelta(options: RunFlowDeltaOptions): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Action-handler wrapper around `runFlowDelta`: checks the job-level skip flag, then runs the flow
|
|
12
|
+
* delta and logs (rather than throws) on failure, since a diff-posting step shouldn't fail the build.
|
|
13
|
+
*
|
|
14
|
+
* Fixes a bug from the original: the CLI wired its skip flag as `--disabled`, but this function
|
|
15
|
+
* checked `options.disableFlowDiff` — a property nothing ever set — so `--disabled` was a no-op.
|
|
16
|
+
*/
|
|
17
|
+
export declare function generateFlowDiff(options: GenerateFlowDiffOptions): Promise<GenerateFlowDiffResult>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2026, SimplySF.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { FLOW_DELTA, generateDiff, runDelta, } from './deltaRunner.js';
|
|
17
|
+
/**
|
|
18
|
+
* Runs the upstream `flow-delta` binary over the commit range, then the reporter binary for the
|
|
19
|
+
* selected VCS platform. Does not catch its own errors; callers decide how to handle them.
|
|
20
|
+
*/
|
|
21
|
+
export async function runFlowDelta(options) {
|
|
22
|
+
return runDelta(FLOW_DELTA, options);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Action-handler wrapper around `runFlowDelta`: checks the job-level skip flag, then runs the flow
|
|
26
|
+
* delta and logs (rather than throws) on failure, since a diff-posting step shouldn't fail the build.
|
|
27
|
+
*
|
|
28
|
+
* Fixes a bug from the original: the CLI wired its skip flag as `--disabled`, but this function
|
|
29
|
+
* checked `options.disableFlowDiff` — a property nothing ever set — so `--disabled` was a no-op.
|
|
30
|
+
*/
|
|
31
|
+
export async function generateFlowDiff(options) {
|
|
32
|
+
return generateDiff(FLOW_DELTA, options);
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=flowDelta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flowDelta.js","sourceRoot":"","sources":["../../src/build/flowDelta.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EACL,UAAU,EACV,YAAY,EACZ,QAAQ,GAIT,MAAM,kBAAkB,CAAC;AAM1B;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAA4B;IAC7D,OAAO,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;AACvC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,OAAgC;IACrE,OAAO,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type PackageInstallUpgradeType } from '../sfPackages.js';
|
|
2
|
+
export type InstallDependenciesOptions = {
|
|
3
|
+
/** Required only when the scratch org's Dev Hub was JWT-authenticated (no refresh token available). */
|
|
4
|
+
jwtKeyFile?: string;
|
|
5
|
+
debug?: boolean;
|
|
6
|
+
installType?: 'All' | 'Delta' | 'Upgrade';
|
|
7
|
+
upgradeType?: PackageInstallUpgradeType;
|
|
8
|
+
};
|
|
9
|
+
/** Authenticates to the scratch org (recorded in `SCRATCH_ORG_INFO.json`) and installs its packaged dependencies. */
|
|
10
|
+
export declare function installDependencies(options: InstallDependenciesOptions): Promise<void>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2026, SimplySF.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { logger } from '../logger.js';
|
|
17
|
+
import { installPackageDependencies as installPackageDependenciesCommon, } from '../sfPackages.js';
|
|
18
|
+
import { ensureScratchOrgSession } from './scratchOrgAuth.js';
|
|
19
|
+
import { readScratchOrgInfo } from './scratchOrgInfo.js';
|
|
20
|
+
/** Authenticates to the scratch org (recorded in `SCRATCH_ORG_INFO.json`) and installs its packaged dependencies. */
|
|
21
|
+
export async function installDependencies(options) {
|
|
22
|
+
logger.info('Installing package dependencies into scratch org...');
|
|
23
|
+
const scratchOrgInfo = await readScratchOrgInfo();
|
|
24
|
+
await ensureScratchOrgSession(scratchOrgInfo.authFields, {
|
|
25
|
+
jwtKeyFile: options.jwtKeyFile,
|
|
26
|
+
setDefault: true,
|
|
27
|
+
debug: options.debug,
|
|
28
|
+
});
|
|
29
|
+
// The install runs in-process (not via a child `sf` invocation that would read the default org
|
|
30
|
+
// just written to config), so target the scratch org explicitly by its username.
|
|
31
|
+
await installPackageDependenciesCommon({
|
|
32
|
+
alias: scratchOrgInfo.authFields.username,
|
|
33
|
+
wait: '240',
|
|
34
|
+
installType: options.installType,
|
|
35
|
+
upgradeType: options.upgradeType,
|
|
36
|
+
});
|
|
37
|
+
logger.success('Package dependencies installed.');
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=installDependencies.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installDependencies.js","sourceRoot":"","sources":["../../src/build/installDependencies.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EACL,0BAA0B,IAAI,gCAAgC,GAE/D,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAUzD,qHAAqH;AACrH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAAmC;IAC3E,MAAM,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAC;IACnE,MAAM,cAAc,GAAG,MAAM,kBAAkB,EAAE,CAAC;IAClD,MAAM,uBAAuB,CAAC,cAAc,CAAC,UAAU,EAAE;QACvD,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,UAAU,EAAE,IAAI;QAChB,KAAK,EAAE,OAAO,CAAC,KAAK;KACrB,CAAC,CAAC;IACH,+FAA+F;IAC/F,iFAAiF;IACjF,MAAM,gCAAgC,CAAC;QACrC,KAAK,EAAE,cAAc,CAAC,UAAU,CAAC,QAAQ;QACzC,IAAI,EAAE,KAAK;QACX,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,WAAW,EAAE,OAAO,CAAC,WAAW;KACjC,CAAC,CAAC;IACH,MAAM,CAAC,OAAO,CAAC,iCAAiC,CAAC,CAAC;AACpD,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** Where `runLwcJest` writes the JUnit report, mirroring `runApexTests`'s `./test-results/apex`. */
|
|
2
|
+
export declare const LWC_JEST_RESULTS_DIR = "./test-results/lwc";
|
|
3
|
+
export declare const LWC_JEST_RESULTS_FILE = "test-result.xml";
|
|
4
|
+
export type RunLwcJestOptions = {
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
failOnTestFailure?: boolean;
|
|
7
|
+
projectDir?: string;
|
|
8
|
+
};
|
|
9
|
+
export type RunLwcJestResult = {
|
|
10
|
+
skipped: boolean;
|
|
11
|
+
success: boolean;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Builds an ES module Jest config that loads the project's own config and adds `jest-junit` to its
|
|
15
|
+
* reporters, rather than replacing them the way a CLI `--reporters` would. `rootDir` is pinned to the
|
|
16
|
+
* project, since Jest would otherwise default it to the wrapper's own (temporary) directory.
|
|
17
|
+
*/
|
|
18
|
+
export declare function buildJunitJestConfig(projectConfigFile: string, projectDir: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* Installs the LWC Jest test libraries and runs the project's LWC Jest tests with coverage, writing
|
|
21
|
+
* a JUnit report to `./test-results/lwc/test-result.xml` alongside any reporters the project's own
|
|
22
|
+
* Jest config sets. A failure is logged and returned, unless `failOnTestFailure` is set, in which
|
|
23
|
+
* case it also throws.
|
|
24
|
+
*/
|
|
25
|
+
export declare function runLwcJest(options: RunLwcJestOptions): Promise<RunLwcJestResult>;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2026, SimplySF.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { promises as fs } from 'node:fs';
|
|
17
|
+
import os from 'node:os';
|
|
18
|
+
import path from 'node:path';
|
|
19
|
+
import { pathToFileURL } from 'node:url';
|
|
20
|
+
import { execa } from 'execa';
|
|
21
|
+
import { logger } from '../logger.js';
|
|
22
|
+
/** Where `runLwcJest` writes the JUnit report, mirroring `runApexTests`'s `./test-results/apex`. */
|
|
23
|
+
export const LWC_JEST_RESULTS_DIR = './test-results/lwc';
|
|
24
|
+
export const LWC_JEST_RESULTS_FILE = 'test-result.xml';
|
|
25
|
+
/** The project config files `sfdx-lwc-jest` recognizes; with none present it passes its own default `--config`. */
|
|
26
|
+
const PROJECT_JEST_CONFIG_FILES = ['jest.config.js', 'jest.config.mjs', 'jest.config.cjs'];
|
|
27
|
+
async function findProjectJestConfig(projectDir) {
|
|
28
|
+
for (const file of PROJECT_JEST_CONFIG_FILES) {
|
|
29
|
+
const configPath = path.join(projectDir, file);
|
|
30
|
+
try {
|
|
31
|
+
// eslint-disable-next-line no-await-in-loop -- first match wins, in sfdx-lwc-jest's order
|
|
32
|
+
await fs.access(configPath);
|
|
33
|
+
return configPath;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// not present; try the next name
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Builds an ES module Jest config that loads the project's own config and adds `jest-junit` to its
|
|
43
|
+
* reporters, rather than replacing them the way a CLI `--reporters` would. `rootDir` is pinned to the
|
|
44
|
+
* project, since Jest would otherwise default it to the wrapper's own (temporary) directory.
|
|
45
|
+
*/
|
|
46
|
+
export function buildJunitJestConfig(projectConfigFile, projectDir) {
|
|
47
|
+
// A config function rather than top-level await: Jest loads config files with require() first, and
|
|
48
|
+
// require() can't load an ES module that uses top-level await.
|
|
49
|
+
return `import path from 'node:path';
|
|
50
|
+
|
|
51
|
+
export default async () => {
|
|
52
|
+
const mod = await import(${JSON.stringify(pathToFileURL(projectConfigFile).href)});
|
|
53
|
+
let config = mod.default ?? mod;
|
|
54
|
+
if (typeof config === 'function') {
|
|
55
|
+
config = await config();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const reporters = config.reporters ?? ['default'];
|
|
59
|
+
const hasJunit = reporters.some((reporter) => (Array.isArray(reporter) ? reporter[0] : reporter) === 'jest-junit');
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
...config,
|
|
63
|
+
rootDir: path.resolve(${JSON.stringify(projectDir)}, config.rootDir ?? '.'),
|
|
64
|
+
reporters: hasJunit ? reporters : [...reporters, 'jest-junit'],
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
`;
|
|
68
|
+
}
|
|
69
|
+
function failRun(options, message, error) {
|
|
70
|
+
logger.error(message);
|
|
71
|
+
if (options.failOnTestFailure) {
|
|
72
|
+
throw new Error(message, { cause: error });
|
|
73
|
+
}
|
|
74
|
+
return { skipped: false, success: false };
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Installs the LWC Jest test libraries and runs the project's LWC Jest tests with coverage, writing
|
|
78
|
+
* a JUnit report to `./test-results/lwc/test-result.xml` alongside any reporters the project's own
|
|
79
|
+
* Jest config sets. A failure is logged and returned, unless `failOnTestFailure` is set, in which
|
|
80
|
+
* case it also throws.
|
|
81
|
+
*/
|
|
82
|
+
export async function runLwcJest(options) {
|
|
83
|
+
if (options.disabled) {
|
|
84
|
+
logger.warn('lwc-jest is disabled. Skipping.');
|
|
85
|
+
return { skipped: true, success: false };
|
|
86
|
+
}
|
|
87
|
+
const projectDir = options.projectDir ?? process.cwd();
|
|
88
|
+
logger.info('Running LWC Jest tests...');
|
|
89
|
+
// Created up front so a pipeline's `when: always` artifact path exists even if Jest never starts.
|
|
90
|
+
await fs.mkdir(path.join(projectDir, LWC_JEST_RESULTS_DIR), { recursive: true });
|
|
91
|
+
try {
|
|
92
|
+
await execa('npm', ['install', '@salesforce/sfdx-lwc-jest', '@sa11y/jest', 'jest-junit'], {
|
|
93
|
+
cwd: projectDir,
|
|
94
|
+
stdio: 'pipe',
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
return failRun(options, 'Failed to install the LWC Jest test libraries.', error);
|
|
99
|
+
}
|
|
100
|
+
const projectConfig = await findProjectJestConfig(projectDir);
|
|
101
|
+
const wrapperDir = projectConfig ? await fs.mkdtemp(path.join(os.tmpdir(), 'lwc-jest-')) : undefined;
|
|
102
|
+
try {
|
|
103
|
+
let reporterArgs = ['--reporters=default', '--reporters=jest-junit'];
|
|
104
|
+
if (projectConfig && wrapperDir) {
|
|
105
|
+
const wrapperConfig = path.join(wrapperDir, 'jest.config.mjs');
|
|
106
|
+
await fs.writeFile(wrapperConfig, buildJunitJestConfig(projectConfig, projectDir));
|
|
107
|
+
reporterArgs = [`--config=${wrapperConfig}`];
|
|
108
|
+
}
|
|
109
|
+
await execa('npx', ['sfdx-lwc-jest', '--coverage', '--', '--passWithNoTests', ...reporterArgs], {
|
|
110
|
+
cwd: projectDir,
|
|
111
|
+
stdio: 'inherit',
|
|
112
|
+
env: { JEST_JUNIT_OUTPUT_DIR: LWC_JEST_RESULTS_DIR, JEST_JUNIT_OUTPUT_NAME: LWC_JEST_RESULTS_FILE },
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
return failRun(options, 'LWC Jest tests failed.', error);
|
|
117
|
+
}
|
|
118
|
+
finally {
|
|
119
|
+
if (wrapperDir) {
|
|
120
|
+
await fs.rm(wrapperDir, { recursive: true, force: true });
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
logger.success('LWC Jest tests completed.');
|
|
124
|
+
return { skipped: false, success: true };
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=lwcJest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lwcJest.js","sourceRoot":"","sources":["../../src/build/lwcJest.ts"],"names":[],"mappings":"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"}
|