@simplysf/simply-cicd-core 0.2.2 → 0.4.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/README.md +32 -3
- 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 +191 -0
- package/lib/build/createPackageVersion.js.map +1 -0
- package/lib/build/createScratchOrg.d.ts +14 -0
- package/lib/build/createScratchOrg.js +182 -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 +274 -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 +159 -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 +52 -0
- package/lib/index.js +64 -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 +167 -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/sfOrg.d.ts +13 -0
- package/lib/sfOrg.js +39 -0
- package/lib/sfOrg.js.map +1 -0
- package/lib/sfPackages.d.ts +63 -0
- package/lib/sfPackages.js +185 -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 +16 -4
|
@@ -0,0 +1,114 @@
|
|
|
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 { isSubscriberPackageVersionId } from '@simplysf/simply-core';
|
|
18
|
+
import { logger } from '../logger.js';
|
|
19
|
+
import { runDeployStage } from './runDeployStage.js';
|
|
20
|
+
import { installDeployPackageDependencies, printDeploymentSummary, runDeployApexTests, runDeploymentSteps, } from './deployCommon.js';
|
|
21
|
+
async function installPackageById(packageId, alias, upgradeType) {
|
|
22
|
+
await execa('sf', [
|
|
23
|
+
'package',
|
|
24
|
+
'install',
|
|
25
|
+
'--apex-compile',
|
|
26
|
+
'package',
|
|
27
|
+
'--package',
|
|
28
|
+
packageId,
|
|
29
|
+
'--target-org',
|
|
30
|
+
alias ?? '',
|
|
31
|
+
'--wait',
|
|
32
|
+
'120',
|
|
33
|
+
'--upgrade-type',
|
|
34
|
+
upgradeType,
|
|
35
|
+
'--no-prompt',
|
|
36
|
+
], { stdio: 'inherit' });
|
|
37
|
+
}
|
|
38
|
+
async function installProjectPackageFromSubscriberId(subscriberPackageVersionId, alias, upgradeType) {
|
|
39
|
+
logger.info(`Installing package version from --subscriber-package-version-id: ${subscriberPackageVersionId}`);
|
|
40
|
+
await installPackageById(subscriberPackageVersionId, alias, upgradeType);
|
|
41
|
+
logger.success(`Successfully installed package ${subscriberPackageVersionId}.`);
|
|
42
|
+
}
|
|
43
|
+
async function installProjectPackageFromGitTag(alias, upgradeType) {
|
|
44
|
+
logger.info('Checking for package version in git tag...');
|
|
45
|
+
try {
|
|
46
|
+
const { stdout: currentTagRaw } = await execa('git', ['tag', '--points-at', 'HEAD']);
|
|
47
|
+
const currentTag = currentTagRaw.split('\n')[0].trim();
|
|
48
|
+
if (!currentTag) {
|
|
49
|
+
logger.info('No git tag found at HEAD. Skipping main package installation.');
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
logger.info(`Found git tag ${currentTag}, checking for package ID...`);
|
|
53
|
+
const { stdout: tagAnnotation } = await execa('git', ['tag', '-l', '-n1', currentTag]);
|
|
54
|
+
const parts = tagAnnotation.trim().split(/\s+/);
|
|
55
|
+
if (parts.length <= 1) {
|
|
56
|
+
logger.info(`Git tag ${currentTag} has no annotation. Skipping main package installation.`);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const packageId = parts.slice(1).join(' ');
|
|
60
|
+
if (!isSubscriberPackageVersionId(packageId)) {
|
|
61
|
+
logger.info('No 04t package version found in git tag annotation. Skipping main package installation.');
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
logger.info(`Found package ID ${packageId} in tag. Installing...`);
|
|
65
|
+
await installPackageById(packageId, alias, upgradeType);
|
|
66
|
+
logger.success(`Successfully installed package ${packageId} from git tag.`);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
logger.warn(`Could not determine package version from git tag: ${error.message}. Skipping main package installation.`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Installs the project's own package into the target org: prioritizes `--subscriber-package-version-id`
|
|
74
|
+
* if given, else looks for a `04t...` package ID annotated on the git tag pointing at HEAD.
|
|
75
|
+
*/
|
|
76
|
+
async function installProjectPackage(config) {
|
|
77
|
+
const { alias, subscriberPackageVersionId, upgradeType = 'Mixed' } = config;
|
|
78
|
+
logger.info('Installing main package...');
|
|
79
|
+
if (subscriberPackageVersionId && isSubscriberPackageVersionId(subscriberPackageVersionId)) {
|
|
80
|
+
await installProjectPackageFromSubscriberId(subscriberPackageVersionId, alias, upgradeType);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
await installProjectPackageFromGitTag(alias, upgradeType);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Runs a single-package "project" deployment stage: `install-packaged` installs dependencies plus
|
|
88
|
+
* the project's own package, `run-apex-tests` delegates to the shared Apex test runner, and every
|
|
89
|
+
* other stage runs through the resumable deployment-steps loop against `config/deploy.json`.
|
|
90
|
+
*/
|
|
91
|
+
export async function deployProject(options) {
|
|
92
|
+
const { stage, ...config } = options;
|
|
93
|
+
await runDeployStage(stage, options, async () => {
|
|
94
|
+
if (stage === 'install-packaged') {
|
|
95
|
+
await installDeployPackageDependencies(config);
|
|
96
|
+
await installProjectPackage(config);
|
|
97
|
+
}
|
|
98
|
+
else if (stage === 'run-apex-tests') {
|
|
99
|
+
await runDeployApexTests(config);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
const { deployProgress } = await runDeploymentSteps({
|
|
103
|
+
...config,
|
|
104
|
+
isProjectDeployment: true,
|
|
105
|
+
stage,
|
|
106
|
+
deployConfigFile: config.deployConfigFile ?? 'config/deploy.json',
|
|
107
|
+
deployProgressFile: config.deployProgressFile ?? 'DEPLOY_PROGRESS.json',
|
|
108
|
+
deployRulesFile: config.deployRulesFile ?? 'config/deploy-rules.json',
|
|
109
|
+
});
|
|
110
|
+
printDeploymentSummary(deployProgress, stage);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=deployProject.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deployProject.js","sourceRoot":"","sources":["../../src/deploy/deployProject.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run one deployment stage inside the shared banner/timing/error frame.
|
|
3
|
+
*
|
|
4
|
+
* Both deployment styles bracket a stage the same way: announce it, install the deployment
|
|
5
|
+
* plugins, run it, then report how long it took — or, on failure, report the elapsed time and the
|
|
6
|
+
* failing job before rethrowing. Only the middle step differs between them.
|
|
7
|
+
*
|
|
8
|
+
* @param stage - The stage name, as it appears in the banner.
|
|
9
|
+
* @param options - The stage's full options, logged verbatim when `debug` is set.
|
|
10
|
+
* @param runStage - The stage's actual work.
|
|
11
|
+
* @throws Whatever `runStage` throws, after logging it. The error is never swallowed — the CI job
|
|
12
|
+
* still has to fail.
|
|
13
|
+
*/
|
|
14
|
+
export declare function runDeployStage(stage: string, options: {
|
|
15
|
+
debug?: boolean;
|
|
16
|
+
}, runStage: () => Promise<void>): Promise<void>;
|
|
@@ -0,0 +1,65 @@
|
|
|
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 chalk from 'chalk';
|
|
17
|
+
import { logger } from '../logger.js';
|
|
18
|
+
import { installDeploymentPlugins } from '../sfPlugins.js';
|
|
19
|
+
/** Width of the `=` rules that bracket each stage's banner in the job log. */
|
|
20
|
+
const BANNER_WIDTH = 80;
|
|
21
|
+
/** @returns Seconds elapsed since `startTime`, to two decimal places. */
|
|
22
|
+
function elapsedSeconds(startTime) {
|
|
23
|
+
return Number(((Date.now() - startTime) / 1000).toFixed(2));
|
|
24
|
+
}
|
|
25
|
+
/** Writes a rule-bracketed banner, the shape every stage boundary uses in the job log. */
|
|
26
|
+
function banner(write, message) {
|
|
27
|
+
logger.raw('\n' + '='.repeat(BANNER_WIDTH));
|
|
28
|
+
write(message);
|
|
29
|
+
logger.raw('='.repeat(BANNER_WIDTH) + '\n');
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Run one deployment stage inside the shared banner/timing/error frame.
|
|
33
|
+
*
|
|
34
|
+
* Both deployment styles bracket a stage the same way: announce it, install the deployment
|
|
35
|
+
* plugins, run it, then report how long it took — or, on failure, report the elapsed time and the
|
|
36
|
+
* failing job before rethrowing. Only the middle step differs between them.
|
|
37
|
+
*
|
|
38
|
+
* @param stage - The stage name, as it appears in the banner.
|
|
39
|
+
* @param options - The stage's full options, logged verbatim when `debug` is set.
|
|
40
|
+
* @param runStage - The stage's actual work.
|
|
41
|
+
* @throws Whatever `runStage` throws, after logging it. The error is never swallowed — the CI job
|
|
42
|
+
* still has to fail.
|
|
43
|
+
*/
|
|
44
|
+
export async function runDeployStage(stage, options, runStage) {
|
|
45
|
+
banner(logger.info, `>>> Starting Deployment Stage: ${chalk.bold(stage)} <<<`);
|
|
46
|
+
const startTime = Date.now();
|
|
47
|
+
try {
|
|
48
|
+
if (options.debug) {
|
|
49
|
+
logger.debug(`Incoming parameters: ${stage}`, options);
|
|
50
|
+
}
|
|
51
|
+
await installDeploymentPlugins(options.debug);
|
|
52
|
+
await runStage();
|
|
53
|
+
banner(logger.success, `Completed stage ${chalk.bold(stage)} in ${elapsedSeconds(startTime)}s`);
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
// Deployment-step failures carry the job they came from; anything else just has a message.
|
|
57
|
+
const job = error.job;
|
|
58
|
+
logger.raw('\n' + '='.repeat(BANNER_WIDTH));
|
|
59
|
+
logger.error(`Failed stage ${chalk.bold(stage)}${job ? ` for ${chalk.bold(job)}` : ''} after ${elapsedSeconds(startTime)}s`);
|
|
60
|
+
logger.raw(error.message);
|
|
61
|
+
logger.raw('='.repeat(BANNER_WIDTH) + '\n');
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=runDeployStage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runDeployStage.js","sourceRoot":"","sources":["../../src/deploy/runDeployStage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAE3D,8EAA8E;AAC9E,MAAM,YAAY,GAAG,EAAE,CAAC;AAExB,yEAAyE;AACzE,SAAS,cAAc,CAAC,SAAiB;IACvC,OAAO,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,0FAA0F;AAC1F,SAAS,MAAM,CAAC,KAAgC,EAAE,OAAe;IAC/D,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;IAC5C,KAAK,CAAC,OAAO,CAAC,CAAC;IACf,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,CAAC;AAC9C,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,KAAa,EACb,OAA4B,EAC5B,QAA6B;IAE7B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,kCAAkC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAE/E,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,IAAI,CAAC;QACH,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,MAAM,CAAC,KAAK,CAAC,wBAAwB,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;QACzD,CAAC;QAED,MAAM,wBAAwB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC9C,MAAM,QAAQ,EAAE,CAAC;QAEjB,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,mBAAmB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAClG,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,2FAA2F;QAC3F,MAAM,GAAG,GAAI,KAAkC,CAAC,GAAG,CAAC;QAEpD,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;QAC5C,MAAM,CAAC,KAAK,CACV,gBAAgB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,cAAc,CAAC,SAAS,CAAC,GAAG,CAC/G,CAAC;QACF,MAAM,CAAC,GAAG,CAAE,KAAe,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,CAAC;QAE5C,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { DeployHappySoupOptions } from './deployHappySoup.js';
|
|
2
|
+
import type { DeployProjectOptions } from './deployProject.js';
|
|
3
|
+
/** The parsed flag values of a "project" deployment stage command, keyed by kebab-case flag name. */
|
|
4
|
+
export type ProjectStageFlagValues = {
|
|
5
|
+
'ci-job-token': string;
|
|
6
|
+
alias: string;
|
|
7
|
+
debug: boolean;
|
|
8
|
+
'deploy-config-file': string;
|
|
9
|
+
'deploy-progress-file': string;
|
|
10
|
+
'deploy-rules-file': string;
|
|
11
|
+
'start-from'?: string;
|
|
12
|
+
'test-level'?: string;
|
|
13
|
+
'test-suite'?: string;
|
|
14
|
+
tests?: string;
|
|
15
|
+
'vcs-host'?: string;
|
|
16
|
+
'vcs-provider': DeployProjectOptions['vcsProvider'];
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* The parsed flag values of a "happy-soup" deployment stage command, keyed by kebab-case flag name.
|
|
20
|
+
*
|
|
21
|
+
* `--deploy-config-file` is optional here where the project flags make it required, because
|
|
22
|
+
* happy-soup falls back to deriving one from `--source-branch-name`.
|
|
23
|
+
*/
|
|
24
|
+
export type HappySoupStageFlagValues = Omit<ProjectStageFlagValues, 'deploy-config-file' | 'test-suite'> & {
|
|
25
|
+
'deploy-config-file'?: string;
|
|
26
|
+
'source-branch-name'?: string;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Map a project stage command's parsed flags onto {@link DeployProjectOptions}.
|
|
30
|
+
*
|
|
31
|
+
* The kebab-case flag names and camelCase option names are a straight one-to-one rename, and it
|
|
32
|
+
* was written out identically in every stage command.
|
|
33
|
+
*
|
|
34
|
+
* @param stage - The stage this command runs.
|
|
35
|
+
* @param flags - The command's parsed flags.
|
|
36
|
+
* @returns The options to hand to `deployProject()`.
|
|
37
|
+
*/
|
|
38
|
+
export declare function toProjectStageOptions(stage: string, flags: ProjectStageFlagValues): DeployProjectOptions;
|
|
39
|
+
/**
|
|
40
|
+
* Map a happy-soup stage command's parsed flags onto {@link DeployHappySoupOptions}.
|
|
41
|
+
*
|
|
42
|
+
* Same shape as {@link toProjectStageOptions}, trading `--test-suite` (which happy-soup stages
|
|
43
|
+
* don't accept) for `--source-branch-name`.
|
|
44
|
+
*
|
|
45
|
+
* @param stage - The stage this command runs.
|
|
46
|
+
* @param flags - The command's parsed flags.
|
|
47
|
+
* @returns The options to hand to `deployHappySoup()`.
|
|
48
|
+
*/
|
|
49
|
+
export declare function toHappySoupStageOptions(stage: string, flags: HappySoupStageFlagValues): DeployHappySoupOptions;
|
|
@@ -0,0 +1,70 @@
|
|
|
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
|
+
/**
|
|
17
|
+
* Map a project stage command's parsed flags onto {@link DeployProjectOptions}.
|
|
18
|
+
*
|
|
19
|
+
* The kebab-case flag names and camelCase option names are a straight one-to-one rename, and it
|
|
20
|
+
* was written out identically in every stage command.
|
|
21
|
+
*
|
|
22
|
+
* @param stage - The stage this command runs.
|
|
23
|
+
* @param flags - The command's parsed flags.
|
|
24
|
+
* @returns The options to hand to `deployProject()`.
|
|
25
|
+
*/
|
|
26
|
+
export function toProjectStageOptions(stage, flags) {
|
|
27
|
+
return {
|
|
28
|
+
stage,
|
|
29
|
+
ciJobToken: flags['ci-job-token'],
|
|
30
|
+
alias: flags.alias,
|
|
31
|
+
debug: flags.debug,
|
|
32
|
+
deployConfigFile: flags['deploy-config-file'],
|
|
33
|
+
deployProgressFile: flags['deploy-progress-file'],
|
|
34
|
+
deployRulesFile: flags['deploy-rules-file'],
|
|
35
|
+
startFrom: flags['start-from'],
|
|
36
|
+
testLevel: flags['test-level'],
|
|
37
|
+
testSuite: flags['test-suite'],
|
|
38
|
+
tests: flags.tests,
|
|
39
|
+
vcsHost: flags['vcs-host'],
|
|
40
|
+
vcsProvider: flags['vcs-provider'],
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Map a happy-soup stage command's parsed flags onto {@link DeployHappySoupOptions}.
|
|
45
|
+
*
|
|
46
|
+
* Same shape as {@link toProjectStageOptions}, trading `--test-suite` (which happy-soup stages
|
|
47
|
+
* don't accept) for `--source-branch-name`.
|
|
48
|
+
*
|
|
49
|
+
* @param stage - The stage this command runs.
|
|
50
|
+
* @param flags - The command's parsed flags.
|
|
51
|
+
* @returns The options to hand to `deployHappySoup()`.
|
|
52
|
+
*/
|
|
53
|
+
export function toHappySoupStageOptions(stage, flags) {
|
|
54
|
+
return {
|
|
55
|
+
stage,
|
|
56
|
+
ciJobToken: flags['ci-job-token'],
|
|
57
|
+
alias: flags.alias,
|
|
58
|
+
debug: flags.debug,
|
|
59
|
+
deployConfigFile: flags['deploy-config-file'],
|
|
60
|
+
deployProgressFile: flags['deploy-progress-file'],
|
|
61
|
+
deployRulesFile: flags['deploy-rules-file'],
|
|
62
|
+
sourceBranchName: flags['source-branch-name'],
|
|
63
|
+
startFrom: flags['start-from'],
|
|
64
|
+
testLevel: flags['test-level'],
|
|
65
|
+
tests: flags.tests,
|
|
66
|
+
vcsHost: flags['vcs-host'],
|
|
67
|
+
vcsProvider: flags['vcs-provider'],
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=stageOptions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stageOptions.js","sourceRoot":"","sources":["../../src/deploy/stageOptions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAgCH;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAa,EAAE,KAA6B;IAChF,OAAO;QACL,KAAK;QACL,UAAU,EAAE,KAAK,CAAC,cAAc,CAAC;QACjC,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,gBAAgB,EAAE,KAAK,CAAC,oBAAoB,CAAC;QAC7C,kBAAkB,EAAE,KAAK,CAAC,sBAAsB,CAAC;QACjD,eAAe,EAAE,KAAK,CAAC,mBAAmB,CAAC;QAC3C,SAAS,EAAE,KAAK,CAAC,YAAY,CAAC;QAC9B,SAAS,EAAE,KAAK,CAAC,YAAY,CAAC;QAC9B,SAAS,EAAE,KAAK,CAAC,YAAY,CAAC;QAC9B,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC;QAC1B,WAAW,EAAE,KAAK,CAAC,cAAc,CAAC;KACnC,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAa,EAAE,KAA+B;IACpF,OAAO;QACL,KAAK;QACL,UAAU,EAAE,KAAK,CAAC,cAAc,CAAC;QACjC,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,gBAAgB,EAAE,KAAK,CAAC,oBAAoB,CAAC;QAC7C,kBAAkB,EAAE,KAAK,CAAC,sBAAsB,CAAC;QACjD,eAAe,EAAE,KAAK,CAAC,mBAAmB,CAAC;QAC3C,gBAAgB,EAAE,KAAK,CAAC,oBAAoB,CAAC;QAC7C,SAAS,EAAE,KAAK,CAAC,YAAY,CAAC;QAC9B,SAAS,EAAE,KAAK,CAAC,YAAY,CAAC;QAC9B,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC;QAC1B,WAAW,EAAE,KAAK,CAAC,cAAc,CAAC;KACnC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type ValidateDeployFilesOptions = {
|
|
2
|
+
deployConfigFile?: string;
|
|
3
|
+
deployRulesFile?: string;
|
|
4
|
+
sourceBranchName?: string;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Validates the deployment config and deployment rules files against their JSON schemas.
|
|
8
|
+
* Each is validated independently: a missing file is skipped (warned, not fatal), but a malformed
|
|
9
|
+
* or schema-invalid file throws.
|
|
10
|
+
*/
|
|
11
|
+
export declare function validateDeployFiles(options: ValidateDeployFilesOptions): Promise<void>;
|
|
@@ -0,0 +1,54 @@
|
|
|
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 { deployConfigSchema } from '../schemas/deployConfig.js';
|
|
18
|
+
import { deployRulesSchema } from '../schemas/deployRules.js';
|
|
19
|
+
import { determineDeployConfigFile, loadValidatedJsonFile } from './deployCommon.js';
|
|
20
|
+
async function validateFile(filePath, schema) {
|
|
21
|
+
try {
|
|
22
|
+
await loadValidatedJsonFile(filePath, schema);
|
|
23
|
+
logger.success(`Validation successful for ${filePath}`);
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
if (error.code === 'ENOENT') {
|
|
27
|
+
logger.warn(`Skipping validation for ${filePath} as it was not found.`);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
logger.error(`Validation failed for ${filePath}: ${error.message}`);
|
|
31
|
+
throw error;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Validates the deployment config and deployment rules files against their JSON schemas.
|
|
36
|
+
* Each is validated independently: a missing file is skipped (warned, not fatal), but a malformed
|
|
37
|
+
* or schema-invalid file throws.
|
|
38
|
+
*/
|
|
39
|
+
export async function validateDeployFiles(options) {
|
|
40
|
+
const resolvedDeployConfigFile = determineDeployConfigFile(options.sourceBranchName, options.deployConfigFile);
|
|
41
|
+
if (resolvedDeployConfigFile) {
|
|
42
|
+
await validateFile(resolvedDeployConfigFile, deployConfigSchema);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
logger.warn('No deployment config file specified or derivable from --source-branch-name. Skipping validation.');
|
|
46
|
+
}
|
|
47
|
+
if (options.deployRulesFile) {
|
|
48
|
+
await validateFile(options.deployRulesFile, deployRulesSchema);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
logger.warn('No deployment rules file specified. Skipping validation.');
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/deploy/validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAQrF,KAAK,UAAU,YAAY,CAAI,QAAgB,EAAE,MAAoB;IACnE,IAAI,CAAC;QACH,MAAM,qBAAqB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC9C,MAAM,CAAC,OAAO,CAAC,6BAA6B,QAAQ,EAAE,CAAC,CAAC;IAC1D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACvD,MAAM,CAAC,IAAI,CAAC,2BAA2B,QAAQ,uBAAuB,CAAC,CAAC;YACxE,OAAO;QACT,CAAC;QACD,MAAM,CAAC,KAAK,CAAC,yBAAyB,QAAQ,KAAM,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/E,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAAmC;IAC3E,MAAM,wBAAwB,GAAG,yBAAyB,CAAC,OAAO,CAAC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAE/G,IAAI,wBAAwB,EAAE,CAAC;QAC7B,MAAM,YAAY,CAAC,wBAAwB,EAAE,kBAAkB,CAAC,CAAC;IACnE,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,IAAI,CAAC,kGAAkG,CAAC,CAAC;IAClH,CAAC;IAED,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;QAC5B,MAAM,YAAY,CAAC,OAAO,CAAC,eAAe,EAAE,iBAAiB,CAAC,CAAC;IACjE,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAC;IAC1E,CAAC;AACH,CAAC"}
|
package/lib/env.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type EnvLogger = {
|
|
2
|
+
info: (message: string, ...args: unknown[]) => void;
|
|
3
|
+
error: (message: string, ...args: unknown[]) => void;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Appends key-value pairs to a .env style file. If the file exists and its content doesn't end
|
|
7
|
+
* with a newline, a leading newline is added before appending. Creates the file if it doesn't exist.
|
|
8
|
+
*/
|
|
9
|
+
export declare function appendToEnvFile(filePath: string, variables: Record<string, string | undefined>, log?: EnvLogger): void;
|
package/lib/env.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
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 fs from 'node:fs';
|
|
17
|
+
/**
|
|
18
|
+
* Appends key-value pairs to a .env style file. If the file exists and its content doesn't end
|
|
19
|
+
* with a newline, a leading newline is added before appending. Creates the file if it doesn't exist.
|
|
20
|
+
*/
|
|
21
|
+
export function appendToEnvFile(filePath, variables, log) {
|
|
22
|
+
const targetLogger = log ?? console;
|
|
23
|
+
const lines = Object.entries(variables)
|
|
24
|
+
.filter((entry) => entry[1] !== undefined)
|
|
25
|
+
.map(([key, value]) => `${key}=${value}`);
|
|
26
|
+
if (lines.length === 0) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const variablesToAppend = lines.join('\n') + '\n';
|
|
30
|
+
try {
|
|
31
|
+
let contentToAppend = variablesToAppend;
|
|
32
|
+
if (fs.existsSync(filePath)) {
|
|
33
|
+
const currentContent = fs.readFileSync(filePath, 'utf8');
|
|
34
|
+
if (currentContent && !currentContent.endsWith('\n')) {
|
|
35
|
+
contentToAppend = `\n${variablesToAppend}`;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
fs.appendFileSync(filePath, contentToAppend, 'utf8');
|
|
39
|
+
targetLogger.info(`Variables successfully appended to ${filePath}!`);
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
const err = error;
|
|
43
|
+
targetLogger.error(`Error appending to ${filePath}: ${err.message}`);
|
|
44
|
+
throw err;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=env.js.map
|
package/lib/env.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AAOzB;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAgB,EAChB,SAA6C,EAC7C,GAAe;IAEf,MAAM,YAAY,GAAG,GAAG,IAAI,OAAO,CAAC;IACpC,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC;SACpC,MAAM,CAAC,CAAC,KAAK,EAA6B,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC;SACpE,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC;IAE5C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO;IACT,CAAC;IAED,MAAM,iBAAiB,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAElD,IAAI,CAAC;QACH,IAAI,eAAe,GAAG,iBAAiB,CAAC;QACxC,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,MAAM,cAAc,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YACzD,IAAI,cAAc,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrD,eAAe,GAAG,KAAK,iBAAiB,EAAE,CAAC;YAC7C,CAAC;QACH,CAAC;QAED,EAAE,CAAC,cAAc,CAAC,QAAQ,EAAE,eAAe,EAAE,MAAM,CAAC,CAAC;QACrD,YAAY,CAAC,IAAI,CAAC,sCAAsC,QAAQ,GAAG,CAAC,CAAC;IACvE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,GAAG,GAAG,KAAc,CAAC;QAC3B,YAAY,CAAC,KAAK,CAAC,sBAAsB,QAAQ,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACrE,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type ExecaChildProcess, type Options } from 'execa';
|
|
2
|
+
/**
|
|
3
|
+
* Run the Salesforce CLI.
|
|
4
|
+
*
|
|
5
|
+
* Everything this package does to an org ultimately shells out to `sf`, and each site was
|
|
6
|
+
* naming the binary itself. Options are forwarded only when a caller supplies them, so the
|
|
7
|
+
* underlying `execa()` call keeps the exact arity each site had.
|
|
8
|
+
*
|
|
9
|
+
* @param args - Arguments to pass to `sf`.
|
|
10
|
+
* @param options - Optional `execa` options, e.g. `{ stdio: 'inherit' }` to stream output
|
|
11
|
+
* straight into the job log.
|
|
12
|
+
* @returns The completed `execa` result.
|
|
13
|
+
*/
|
|
14
|
+
export declare function runSf(args: string[], options?: Options): ExecaChildProcess;
|
|
15
|
+
/**
|
|
16
|
+
* Run the Salesforce CLI and parse its `--json` output.
|
|
17
|
+
*
|
|
18
|
+
* The caller still passes `--json` in `args` — this doesn't inject it, because which commands
|
|
19
|
+
* accept it and where it belongs in the argument list varies. What it does replace is the
|
|
20
|
+
* `JSON.parse(stdout) as SomeShape` written out at each call site.
|
|
21
|
+
*
|
|
22
|
+
* @param args - Arguments to pass to `sf`, including `--json`.
|
|
23
|
+
* @param options - Optional `execa` options.
|
|
24
|
+
* @returns The parsed payload, typed as the caller asserts.
|
|
25
|
+
* @throws {SyntaxError} If the command's output isn't valid JSON.
|
|
26
|
+
*/
|
|
27
|
+
export declare function runSfJson<T>(args: string[], options?: Options): Promise<T>;
|
|
@@ -0,0 +1,50 @@
|
|
|
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
|
+
/** The `sf` executable, as resolved from `PATH` in the CI job. */
|
|
18
|
+
const SF_BINARY = 'sf';
|
|
19
|
+
/**
|
|
20
|
+
* Run the Salesforce CLI.
|
|
21
|
+
*
|
|
22
|
+
* Everything this package does to an org ultimately shells out to `sf`, and each site was
|
|
23
|
+
* naming the binary itself. Options are forwarded only when a caller supplies them, so the
|
|
24
|
+
* underlying `execa()` call keeps the exact arity each site had.
|
|
25
|
+
*
|
|
26
|
+
* @param args - Arguments to pass to `sf`.
|
|
27
|
+
* @param options - Optional `execa` options, e.g. `{ stdio: 'inherit' }` to stream output
|
|
28
|
+
* straight into the job log.
|
|
29
|
+
* @returns The completed `execa` result.
|
|
30
|
+
*/
|
|
31
|
+
export function runSf(args, options) {
|
|
32
|
+
return options ? execa(SF_BINARY, args, options) : execa(SF_BINARY, args);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Run the Salesforce CLI and parse its `--json` output.
|
|
36
|
+
*
|
|
37
|
+
* The caller still passes `--json` in `args` — this doesn't inject it, because which commands
|
|
38
|
+
* accept it and where it belongs in the argument list varies. What it does replace is the
|
|
39
|
+
* `JSON.parse(stdout) as SomeShape` written out at each call site.
|
|
40
|
+
*
|
|
41
|
+
* @param args - Arguments to pass to `sf`, including `--json`.
|
|
42
|
+
* @param options - Optional `execa` options.
|
|
43
|
+
* @returns The parsed payload, typed as the caller asserts.
|
|
44
|
+
* @throws {SyntaxError} If the command's output isn't valid JSON.
|
|
45
|
+
*/
|
|
46
|
+
export async function runSfJson(args, options) {
|
|
47
|
+
const { stdout } = await runSf(args, options);
|
|
48
|
+
return JSON.parse(stdout);
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=sfCli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sfCli.js","sourceRoot":"","sources":["../../src/exec/sfCli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,KAAK,EAAwC,MAAM,OAAO,CAAC;AAEpE,kEAAkE;AAClE,MAAM,SAAS,GAAG,IAAI,CAAC;AAEvB;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,KAAK,CAAC,IAAc,EAAE,OAAiB;IACrD,OAAO,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAC5E,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAI,IAAc,EAAE,OAAiB;IAClE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAE9C,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAM,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coerce a string or boolean to a boolean. `'true'`/`'false'` are recognised
|
|
3
|
+
* case- and whitespace-insensitively; anything else is `false`.
|
|
4
|
+
*
|
|
5
|
+
* Environment variables are always strings, unlike the boolean flags oclif parses natively, so
|
|
6
|
+
* any flag with an env-var fallback needs this on the env side.
|
|
7
|
+
*
|
|
8
|
+
* @param value - The raw flag or environment value.
|
|
9
|
+
* @returns The coerced boolean.
|
|
10
|
+
*/
|
|
11
|
+
export declare function parseBooleanString(value: string | boolean): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Resolve a string setting with CLI flag > environment variable > fallback precedence.
|
|
14
|
+
*
|
|
15
|
+
* Several settings accept more than one environment variable — a `SIMPLY_CICD_`-prefixed name of
|
|
16
|
+
* our own plus whatever the CI provider already exports — so the env side takes a list, tried in
|
|
17
|
+
* order.
|
|
18
|
+
*
|
|
19
|
+
* @param flagValue - The parsed CLI flag, if the caller passed one.
|
|
20
|
+
* @param envVars - Candidate environment values, most specific first.
|
|
21
|
+
* @param fallback - Used when neither the flag nor any environment variable is set.
|
|
22
|
+
* @returns The resolved value.
|
|
23
|
+
*/
|
|
24
|
+
export declare function resolveString(flagValue: string | undefined, envVars: Array<string | undefined>, fallback?: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* {@link resolveString} for settings with no default, where "unset" is meaningful.
|
|
27
|
+
*
|
|
28
|
+
* @param flagValue - The parsed CLI flag, if the caller passed one.
|
|
29
|
+
* @param envVars - Candidate environment values, most specific first.
|
|
30
|
+
* @returns The resolved value, or `undefined` if nothing supplied one.
|
|
31
|
+
*/
|
|
32
|
+
export declare function resolveOptionalString(flagValue: string | undefined, envVars: Array<string | undefined>): string | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* Resolve a boolean setting with CLI flag > environment variable > fallback precedence.
|
|
35
|
+
*
|
|
36
|
+
* The flag is checked for `undefined` rather than falsiness, so an explicit `--no-…` stays
|
|
37
|
+
* distinguishable from an unset flag and still beats the environment.
|
|
38
|
+
*
|
|
39
|
+
* @param flagValue - The parsed CLI flag, if the caller passed one.
|
|
40
|
+
* @param envVar - The environment value, coerced via {@link parseBooleanString}.
|
|
41
|
+
* @param fallback - Used when neither the flag nor the environment variable is set.
|
|
42
|
+
* @returns The resolved boolean.
|
|
43
|
+
*/
|
|
44
|
+
export declare function resolveBoolean(flagValue: boolean | undefined, envVar: string | undefined, fallback: boolean): boolean;
|