@simplysf/simply-cicd-core 0.4.0 → 0.9.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 +10 -10
- package/lib/build/cleanupScratchOrgs.js +16 -49
- package/lib/build/cleanupScratchOrgs.js.map +1 -1
- package/lib/build/createPackageVersion.js +20 -44
- package/lib/build/createPackageVersion.js.map +1 -1
- package/lib/build/createScratchOrg.d.ts +2 -1
- package/lib/build/createScratchOrg.js +33 -63
- package/lib/build/createScratchOrg.js.map +1 -1
- package/lib/build/deleteScratchOrg.js +3 -2
- package/lib/build/deleteScratchOrg.js.map +1 -1
- package/lib/build/pushScratch.js +40 -19
- package/lib/build/pushScratch.js.map +1 -1
- package/lib/deploy/deployProject.js +15 -14
- package/lib/deploy/deployProject.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/sfApex.js +39 -34
- package/lib/sfApex.js.map +1 -1
- package/lib/sfAuth.d.ts +8 -1
- package/lib/sfAuth.js +65 -46
- package/lib/sfAuth.js.map +1 -1
- package/lib/sfDeploy.d.ts +34 -0
- package/lib/sfDeploy.js +77 -0
- package/lib/sfDeploy.js.map +1 -0
- package/lib/sfOrg.d.ts +73 -0
- package/lib/sfOrg.js +160 -1
- package/lib/sfOrg.js.map +1 -1
- package/lib/sfPackages.d.ts +27 -1
- package/lib/sfPackages.js +45 -1
- package/lib/sfPackages.js.map +1 -1
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ Salesforce CI/CD pipeline stages (build, deploy, notify, sfdx-dependabot), ALM i
|
|
|
12
12
|
npm install @simplysf/simply-cicd-core
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
Requires Node.js `>=22` and either `"type": "module"` or a dynamic `import()` — this package ships ESM only. `vcs/`'s GitHub/GitLab clients use the platform `fetch`.
|
|
15
|
+
Requires Node.js `>=22` and either `"type": "module"` or a dynamic `import()` — this package ships ESM only. `vcs/`'s GitHub/GitLab clients use the platform `fetch`. Salesforce operations run in-process through `@salesforce/core`, `@salesforce/packaging`, `@salesforce/apex-node` and `@salesforce/source-deploy-retrieve` / `@salesforce/source-tracking`. `sf` is only needed on `PATH` for `installPlugin`/`installDeploymentPlugins` (which manage the CLI's own plugins) and for any deploy-stage scripts of yours that call it; `git` (via `execa`) is needed by the stages that tag, clone or diff. Stages write `[SIMPLY-CICD]`-prefixed progress output to the console.
|
|
16
16
|
|
|
17
17
|
## API
|
|
18
18
|
|
|
@@ -57,15 +57,15 @@ const mr = await gitlab.findMergeRequest({ sourceBranch: 'feature/x' });
|
|
|
57
57
|
|
|
58
58
|
The modules `@simplysf/simply-cicd`'s commands run, also exported from the package root. Each stage function takes a plain options object (the camelCase equivalent of the command's flags) and throws on failure. Full signatures are in the [API reference](https://simplysf.github.io/simply-plugins-core/api/simply-cicd-core/readme/).
|
|
59
59
|
|
|
60
|
-
| Area
|
|
61
|
-
|
|
|
62
|
-
| Build
|
|
63
|
-
| Deploy
|
|
64
|
-
| Notify
|
|
65
|
-
| sfdx-dependabot
|
|
66
|
-
| Schemas (zod)
|
|
67
|
-
| Salesforce org and package
|
|
68
|
-
| `sf`/`git`/env utilities
|
|
60
|
+
| Area | Main exports |
|
|
61
|
+
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
62
|
+
| Build | `createScratchOrg`, `deleteScratchOrg`, `cleanupScratchOrgs`, `pushToScratch`, `runScratchApexTests`, `installDependencies`, `createPackageVersion`, `createFallbackTag`, `determinePackageChanges`, `runLwcJest`, `runCheckPermissionSets`, `runFlowDelta`, `runFlexipageDelta`, `publishUtamPageObjects`, `VersionTagFormat` |
|
|
63
|
+
| Deploy | `deployProject`, `deployHappySoup`, `runDeployStage`, `validateDeployFiles`, `toProjectStageOptions`, `toHappySoupStageOptions`, plus the `deployCommon` helpers (`runDeploymentSteps`, `loadProgress`, `updateProgress`, `installDeployPackageDependencies`, `runDeployApexTests`, …) |
|
|
64
|
+
| Notify | `sendBuildNotification`, `projectNotifyBeforeScript`/`projectNotifyAfterScript`, `happySoupNotifyBeforeScript`/`happySoupNotifyAfterScript`, `getCommitStories`, `getRemoteCommitStories`, `sendNotification`, `renderNotifyTemplate`, `NOTIFY_TEMPLATES` |
|
|
65
|
+
| sfdx-dependabot | `discoverEligibleProjects`, `processProject`, `applyProjectUpdate`, `updateSfdxProject` |
|
|
66
|
+
| Schemas (zod) | `deployConfigSchema`, `deployProgressSchema`, `deployRulesSchema`, `deployStageSchema` |
|
|
67
|
+
| Salesforce org and package operations | `authenticateOrg` (JWT or SFDX auth URL), `requestPackageVersionCreate`, `getPackageVersionCreateStatus`, `deployProjectSource`, `getPackageVersionReport`, `listInstalledPackages`, `getOrgConnection`, `getOrgInstanceUrl`, `getRemainingDailyScratchOrgs`, `assignPermissionSets`, `assignPermissionSetLicenses` (`AssignmentError`), `createScratchOrgOnHub`, `deleteTargetScratchOrg` (in-process via `@salesforce/core` / `@salesforce/packaging`, no `sf` needed) |
|
|
68
|
+
| `sf`/`git`/env utilities | `runSf`, `runSfJson`, `installPackageDependencies`, `runApexTests`, `installPlugin`, `cloneRepo`, `appendToEnvFile`, `resolveString`/`resolveBoolean`, `logger` |
|
|
69
69
|
|
|
70
70
|
```ts
|
|
71
71
|
import { deployProject } from '@simplysf/simply-cicd-core';
|
|
@@ -13,65 +13,32 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
import path from 'node:path';
|
|
17
|
-
import { promises as fs } from 'node:fs';
|
|
18
|
-
import { runSf } from '../exec/sfCli.js';
|
|
19
16
|
import { logger } from '../logger.js';
|
|
17
|
+
import { getOrgConnection } from '../sfOrg.js';
|
|
20
18
|
import { resolveDevHubs } from './devHubs.js';
|
|
21
19
|
async function cleanupScratchOrgsForHub(hubUsername) {
|
|
22
20
|
logger.info(`Querying for scratch orgs in ${hubUsername}...`);
|
|
23
|
-
const csvFile = path.join(process.cwd(), `${hubUsername}_orgs.csv`);
|
|
24
21
|
try {
|
|
22
|
+
const connection = await getOrgConnection(hubUsername);
|
|
25
23
|
const threeHoursAgo = new Date(Date.now() - 3 * 60 * 60 * 1000).toISOString();
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
'data',
|
|
29
|
-
'query',
|
|
30
|
-
'--query',
|
|
31
|
-
query,
|
|
32
|
-
'--result-format',
|
|
33
|
-
'csv',
|
|
34
|
-
'--target-org',
|
|
35
|
-
hubUsername,
|
|
36
|
-
]);
|
|
37
|
-
await fs.writeFile(csvFile, stdout);
|
|
38
|
-
const fileContent = await fs.readFile(csvFile, 'utf-8');
|
|
39
|
-
// Fixed: the original split on '' (individual characters), so this line count was
|
|
40
|
-
// effectively always > 1 for any non-empty CSV and the "no old scratch orgs" branch below
|
|
41
|
-
// was unreachable. Splitting on newlines actually counts CSV rows.
|
|
42
|
-
const lines = fileContent.trim().split('\n');
|
|
43
|
-
if (lines.length > 1) {
|
|
44
|
-
logger.info(`Found ${lines.length - 1} old scratch orgs in ${hubUsername}. Deleting...`);
|
|
45
|
-
await runSf([
|
|
46
|
-
'data',
|
|
47
|
-
'bulk',
|
|
48
|
-
'delete',
|
|
49
|
-
'--sobject',
|
|
50
|
-
'ActiveScratchOrg',
|
|
51
|
-
'--file',
|
|
52
|
-
csvFile,
|
|
53
|
-
'--target-org',
|
|
54
|
-
hubUsername,
|
|
55
|
-
'--wait',
|
|
56
|
-
'30',
|
|
57
|
-
], {
|
|
58
|
-
stdio: 'inherit',
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
24
|
+
const { records } = await connection.query(`SELECT Id FROM ActiveScratchOrg WHERE CreatedDate < ${threeHoursAgo}`, { autoFetch: true, maxFetch: 50_000 });
|
|
25
|
+
if (records.length === 0) {
|
|
62
26
|
logger.info(`No old scratch orgs found in ${hubUsername}.`);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
logger.info(`Found ${records.length} old scratch orgs in ${hubUsername}. Deleting...`);
|
|
30
|
+
// Deleting an ActiveScratchOrg record deletes the scratch org. allowRecursive splits the
|
|
31
|
+
// sObject Collections call into the API's 200-record batches.
|
|
32
|
+
const results = await connection.sobject('ActiveScratchOrg').destroy(records.map((record) => record.Id), { allOrNone: false, allowRecursive: true });
|
|
33
|
+
const failures = results.filter((result) => !result.success);
|
|
34
|
+
for (const failure of failures) {
|
|
35
|
+
const reason = failure.success ? '' : failure.errors.map((e) => e.message).join('; ');
|
|
36
|
+
logger.warn(`Could not delete scratch org ${failure.id ?? 'unknown'} in ${hubUsername}: ${reason}`);
|
|
63
37
|
}
|
|
38
|
+
logger.info(`Deleted ${results.length - failures.length} of ${results.length} old scratch orgs in ${hubUsername}.`);
|
|
64
39
|
}
|
|
65
40
|
catch (error) {
|
|
66
|
-
logger.error(`Failed to cleanup scratch orgs for ${hubUsername}:`, error.
|
|
67
|
-
}
|
|
68
|
-
finally {
|
|
69
|
-
try {
|
|
70
|
-
await fs.unlink(csvFile);
|
|
71
|
-
}
|
|
72
|
-
catch {
|
|
73
|
-
/* ignore */
|
|
74
|
-
}
|
|
41
|
+
logger.error(`Failed to cleanup scratch orgs for ${hubUsername}:`, error.message);
|
|
75
42
|
}
|
|
76
43
|
}
|
|
77
44
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cleanupScratchOrgs.js","sourceRoot":"","sources":["../../src/build/cleanupScratchOrgs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"cleanupScratchOrgs.js","sourceRoot":"","sources":["../../src/build/cleanupScratchOrgs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,KAAK,UAAU,wBAAwB,CAAC,WAAmB;IACzD,MAAM,CAAC,IAAI,CAAC,gCAAgC,WAAW,KAAK,CAAC,CAAC;IAC9D,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,gBAAgB,CAAC,WAAW,CAAC,CAAC;QACvD,MAAM,aAAa,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;QAC9E,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,UAAU,CAAC,KAAK,CACxC,uDAAuD,aAAa,EAAE,EACtE,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CACtC,CAAC;QACF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,CAAC,IAAI,CAAC,gCAAgC,WAAW,GAAG,CAAC,CAAC;YAC5D,OAAO;QACT,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,MAAM,wBAAwB,WAAW,eAAe,CAAC,CAAC;QACvF,yFAAyF;QACzF,8DAA8D;QAC9D,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,OAAO,CAClE,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAClC,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,CAC3C,CAAC;QACF,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC7D,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtF,MAAM,CAAC,IAAI,CAAC,gCAAgC,OAAO,CAAC,EAAE,IAAI,SAAS,OAAO,WAAW,KAAK,MAAM,EAAE,CAAC,CAAC;QACtG,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,WAAW,OAAO,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,OAAO,OAAO,CAAC,MAAM,wBAAwB,WAAW,GAAG,CAAC,CAAC;IACtH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,sCAAsC,WAAW,GAAG,EAAG,KAAe,CAAC,OAAO,CAAC,CAAC;IAC/F,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,aAAuB;IAC9D,MAAM,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,aAAa,CAAC,CAAC;IAEpD,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,wGAAwG;QACxG,MAAM,wBAAwB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC/C,CAAC;IAED,MAAM,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAC;AAClD,CAAC"}
|
|
@@ -17,10 +17,9 @@ import { promises as fs } from 'node:fs';
|
|
|
17
17
|
import { execa } from 'execa';
|
|
18
18
|
import { getDefaultPackageDirectory, getPluginConfig, readSfdxProject } from '@simplysf/simply-core';
|
|
19
19
|
import { createVcsProvider } from '../vcs/index.js';
|
|
20
|
-
import { runSf } from '../exec/sfCli.js';
|
|
21
20
|
import { addGitRemote } from '../git.js';
|
|
22
21
|
import { logger } from '../logger.js';
|
|
23
|
-
import { getPackageVersionReport } from '../sfPackages.js';
|
|
22
|
+
import { getPackageVersionCreateStatus, getPackageVersionReport, requestPackageVersionCreate } from '../sfPackages.js';
|
|
24
23
|
import { VersionTagFormat } from './versionTagFormat.js';
|
|
25
24
|
/**
|
|
26
25
|
* Whether this build's ref is a release-branch build.
|
|
@@ -31,14 +30,14 @@ import { VersionTagFormat } from './versionTagFormat.js';
|
|
|
31
30
|
export function refIncludesPrefix(ciCommitRefName, packageReleaseBranchPrefix) {
|
|
32
31
|
return packageReleaseBranchPrefix !== undefined && ciCommitRefName.includes(packageReleaseBranchPrefix);
|
|
33
32
|
}
|
|
34
|
-
function
|
|
33
|
+
function determineBranch(branchAttribute, ciCommitRefName, packageReleaseBranchPrefix) {
|
|
35
34
|
if (branchAttribute) {
|
|
36
|
-
return
|
|
35
|
+
return branchAttribute;
|
|
37
36
|
}
|
|
38
37
|
if (!refIncludesPrefix(ciCommitRefName, packageReleaseBranchPrefix)) {
|
|
39
|
-
return
|
|
38
|
+
return ciCommitRefName;
|
|
40
39
|
}
|
|
41
|
-
return
|
|
40
|
+
return undefined;
|
|
42
41
|
}
|
|
43
42
|
/**
|
|
44
43
|
* The suffix appended to this build's version tag: the package's `branch` attribute, else the CI ref
|
|
@@ -90,23 +89,15 @@ function logPackageId(sfdxProjectJson) {
|
|
|
90
89
|
async function pollPackageVersionCreation(createRequestId, packagingDevhub) {
|
|
91
90
|
for (;;) {
|
|
92
91
|
// eslint-disable-next-line no-await-in-loop -- each poll must wait for the previous one's result before deciding to continue
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
'--target-dev-hub',
|
|
101
|
-
packagingDevhub,
|
|
102
|
-
'--json',
|
|
103
|
-
]);
|
|
104
|
-
const report = JSON.parse(reportStdout).result[0];
|
|
105
|
-
logger.info(`Polling package creation status: ${report.Status}`);
|
|
106
|
-
if (report.Status === 'Error') {
|
|
107
|
-
throw new Error(`Package creation failed: ${report.Error ?? 'unknown error'}`);
|
|
92
|
+
const report = await getPackageVersionCreateStatus(createRequestId, packagingDevhub);
|
|
93
|
+
// The library types this as an enum; its values are the plain status strings the API returns.
|
|
94
|
+
const status = report.Status;
|
|
95
|
+
logger.info(`Polling package creation status: ${status}`);
|
|
96
|
+
if (status === 'Error') {
|
|
97
|
+
const errors = report.Error ?? [];
|
|
98
|
+
throw new Error(`Package creation failed: ${errors.length ? errors.map(String).join(',') : 'unknown error'}`);
|
|
108
99
|
}
|
|
109
|
-
if (
|
|
100
|
+
if (status === 'Success') {
|
|
110
101
|
const subscriberPackageVersionId = report.SubscriberPackageVersionId ?? '';
|
|
111
102
|
logger.success(`Package version created successfully: ${subscriberPackageVersionId}`);
|
|
112
103
|
return subscriberPackageVersionId;
|
|
@@ -148,29 +139,14 @@ export async function createPackageVersion(options) {
|
|
|
148
139
|
// whose tag then can't be written.
|
|
149
140
|
const versionTagFormat = VersionTagFormat.fromProject(sfdxProjectJson);
|
|
150
141
|
logPackageId(sfdxProjectJson);
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
'version',
|
|
155
|
-
'create',
|
|
156
|
-
'--code-coverage',
|
|
157
|
-
'--package',
|
|
158
|
-
packageAlias,
|
|
159
|
-
'--definition-file',
|
|
142
|
+
const { Id: createRequestId } = await requestPackageVersionCreate({
|
|
143
|
+
devHubAliasOrUsername: options.packagingDevhub,
|
|
144
|
+
packageId: packageAlias,
|
|
160
145
|
definitionFile,
|
|
161
|
-
|
|
162
|
-
options.
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
'--target-dev-hub',
|
|
166
|
-
options.packagingDevhub,
|
|
167
|
-
...branchArgs,
|
|
168
|
-
'--installation-key-bypass',
|
|
169
|
-
'--wait',
|
|
170
|
-
'0',
|
|
171
|
-
'--json',
|
|
172
|
-
]);
|
|
173
|
-
const createRequestId = JSON.parse(createStdout).result.Id;
|
|
146
|
+
versionDescription: options.ciPipelineUrl,
|
|
147
|
+
tag: options.ciCommitSha,
|
|
148
|
+
branch: determineBranch(branchAttribute, options.ciCommitRefName, options.packageReleaseBranchPrefix),
|
|
149
|
+
});
|
|
174
150
|
logger.info(`Package version creation requested. Request ID: ${createRequestId}`);
|
|
175
151
|
const subscriberPackageVersionId = await pollPackageVersionCreation(createRequestId, options.packagingDevhub);
|
|
176
152
|
await fs.writeFile('subscriberPackageVersionId.env', `SUBSCRIBER_PACKAGE_VERSION_ID=${subscriberPackageVersionId}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createPackageVersion.js","sourceRoot":"","sources":["../../src/build/createPackageVersion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAE,0BAA0B,EAAE,eAAe,EAAE,eAAe,EAAoB,MAAM,uBAAuB,CAAC;AACvH,OAAO,EAAE,iBAAiB,EAAwB,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"createPackageVersion.js","sourceRoot":"","sources":["../../src/build/createPackageVersion.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import { type CreatedScratchOrg } from '../sfOrg.js';
|
|
2
|
+
export type ScratchOrgCreateResult = CreatedScratchOrg;
|
|
2
3
|
export type CreateScratchOrgOptions = {
|
|
3
4
|
debug?: boolean;
|
|
4
5
|
scratchDefinitionFile?: string;
|
|
@@ -15,21 +15,16 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { promises as fs } from 'node:fs';
|
|
17
17
|
import { getDefaultPackageDirectory, readSfdxProject } from '@simplysf/simply-core';
|
|
18
|
-
import { runSf, runSfJson } from '../exec/sfCli.js';
|
|
19
18
|
import { logger } from '../logger.js';
|
|
20
|
-
import { getRemainingDailyScratchOrgs } from '../sfOrg.js';
|
|
19
|
+
import { assignPermissionSetLicenses as assignLicensesToOrgUser, assignPermissionSets as assignPermissionSetsToOrgUser, createScratchOrgOnHub, getOrgConnection, getRemainingDailyScratchOrgs, } from '../sfOrg.js';
|
|
21
20
|
import { resolveDevHubs } from './devHubs.js';
|
|
22
21
|
async function assignPermissionSets(permissionSets) {
|
|
23
22
|
if (permissionSets.length === 0) {
|
|
24
23
|
return;
|
|
25
24
|
}
|
|
26
25
|
logger.info('Assigning permission sets...');
|
|
27
|
-
const args = ['org', 'assign', 'permset', '--json', ...permissionSets.flatMap((ps) => ['--name', ps])];
|
|
28
26
|
try {
|
|
29
|
-
|
|
30
|
-
if (result.status !== 0) {
|
|
31
|
-
throw new Error(`Permission set assignment failed: ${JSON.stringify(result.failures)}`);
|
|
32
|
-
}
|
|
27
|
+
await assignPermissionSetsToOrgUser(permissionSets);
|
|
33
28
|
logger.success('Permission sets assigned successfully.');
|
|
34
29
|
}
|
|
35
30
|
catch (e) {
|
|
@@ -42,12 +37,8 @@ async function assignPermissionSetLicenses(licenses) {
|
|
|
42
37
|
return;
|
|
43
38
|
}
|
|
44
39
|
logger.info('Assigning permission set licenses...');
|
|
45
|
-
const args = ['org', 'assign', 'permset-license', '--json', ...licenses.flatMap((psl) => ['--name', psl])];
|
|
46
40
|
try {
|
|
47
|
-
|
|
48
|
-
if (result.status !== 0) {
|
|
49
|
-
throw new Error(`Permission set license assignment failed: ${JSON.stringify(result.failures)}`);
|
|
50
|
-
}
|
|
41
|
+
await assignLicensesToOrgUser(licenses);
|
|
51
42
|
logger.success('Permission set licenses assigned successfully.');
|
|
52
43
|
}
|
|
53
44
|
catch (e) {
|
|
@@ -66,74 +57,48 @@ async function assignPermissions(sfdxProjectJson) {
|
|
|
66
57
|
}
|
|
67
58
|
async function trySetDefaultCountry() {
|
|
68
59
|
try {
|
|
69
|
-
|
|
60
|
+
// Runs against the just-created scratch org (the default target org). CountryCode only exists
|
|
61
|
+
// with State and Country/Territory picklists enabled, so this query is the feature probe.
|
|
62
|
+
const connection = await getOrgConnection();
|
|
63
|
+
await connection.query('SELECT CountryCode FROM User LIMIT 1');
|
|
70
64
|
logger.info('State/Country picklists detected. Setting default country for user...');
|
|
71
|
-
await
|
|
72
|
-
|
|
73
|
-
'update',
|
|
74
|
-
'record',
|
|
75
|
-
'--sobject',
|
|
76
|
-
'User',
|
|
77
|
-
'--where',
|
|
78
|
-
"Name='User User'",
|
|
79
|
-
'--values',
|
|
80
|
-
"CountryCode='US'",
|
|
81
|
-
]);
|
|
65
|
+
const { Id } = await connection.singleRecordQuery("SELECT Id FROM User WHERE Name = 'User User'");
|
|
66
|
+
await connection.sobject('User').update({ Id, CountryCode: 'US' });
|
|
82
67
|
logger.success('Default country set.');
|
|
83
68
|
}
|
|
84
69
|
catch {
|
|
85
70
|
logger.info('State/Country picklists not detected. Skipping default country update.');
|
|
86
71
|
}
|
|
87
72
|
}
|
|
88
|
-
async function attemptScratchOrgCreation(hub, definitionFile,
|
|
73
|
+
async function attemptScratchOrgCreation(hub, definitionFile, durationDays) {
|
|
89
74
|
const remaining = await getRemainingDailyScratchOrgs(hub.username);
|
|
90
75
|
if (remaining === undefined || remaining <= 0) {
|
|
91
76
|
logger.warn(`Dev Hub ${hub.alias} has no remaining scratch orgs. Skipping.`);
|
|
92
77
|
return undefined;
|
|
93
78
|
}
|
|
94
79
|
logger.info(`Attempting to create scratch org with Dev Hub ${hub.alias} (${remaining} remaining).`);
|
|
95
|
-
const
|
|
96
|
-
'org',
|
|
97
|
-
'create',
|
|
98
|
-
'scratch',
|
|
99
|
-
'--target-dev-hub',
|
|
100
|
-
hub.username,
|
|
101
|
-
'--duration-days',
|
|
102
|
-
duration,
|
|
103
|
-
'--definition-file',
|
|
80
|
+
const createResult = await createScratchOrgOnHub(hub.username, {
|
|
104
81
|
definitionFile,
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
]);
|
|
110
|
-
const createResult = JSON.parse(stdout).result;
|
|
82
|
+
durationDays,
|
|
83
|
+
waitMinutes: 20,
|
|
84
|
+
setDefault: true,
|
|
85
|
+
});
|
|
111
86
|
await fs.writeFile('SCRATCH_ORG_INFO.json', JSON.stringify(createResult, null, 2));
|
|
112
87
|
logger.success(`Scratch org created successfully using Dev Hub ${hub.alias}.`);
|
|
113
88
|
return createResult;
|
|
114
89
|
}
|
|
115
|
-
|
|
116
|
-
|
|
90
|
+
/**
|
|
91
|
+
* The Dev Hub refusing the signup because its daily allocation is used up. That's the API's own
|
|
92
|
+
* `LIMIT_EXCEEDED` error on the ScratchOrgInfo insert, passed through by @salesforce/core.
|
|
93
|
+
*/
|
|
94
|
+
function isScratchOrgLimitError(error, message) {
|
|
95
|
+
return (error.errorCode === 'LIMIT_EXCEEDED' ||
|
|
96
|
+
message.includes('The signup request failed because this organization has reached its daily scratch org signup limit') ||
|
|
97
|
+
message.includes('LIMIT_EXCEEDED'));
|
|
117
98
|
}
|
|
118
99
|
function extractScratchOrgErrorMessage(error) {
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
if (err.stdout) {
|
|
122
|
-
try {
|
|
123
|
-
const errorResult = JSON.parse(err.stdout);
|
|
124
|
-
errorMessage = errorResult.message ?? errorMessage;
|
|
125
|
-
logger.error(errorMessage);
|
|
126
|
-
if (errorResult.stack) {
|
|
127
|
-
logger.error(errorResult.stack);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
catch {
|
|
131
|
-
logger.error(err.stdout);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
else {
|
|
135
|
-
logger.error(err.message);
|
|
136
|
-
}
|
|
100
|
+
const errorMessage = error.message;
|
|
101
|
+
logger.error(errorMessage);
|
|
137
102
|
return errorMessage;
|
|
138
103
|
}
|
|
139
104
|
/**
|
|
@@ -151,11 +116,16 @@ export async function createScratchOrg(options, devHubAliases) {
|
|
|
151
116
|
if (!definitionFile) {
|
|
152
117
|
throw new Error('You must specify a definitionFile in the default package directory in sfdx-project.json');
|
|
153
118
|
}
|
|
154
|
-
const
|
|
119
|
+
const rawDurationDays = options.scratchDurationDays ?? '1';
|
|
120
|
+
const durationDays = Number(rawDurationDays);
|
|
121
|
+
// `sf org create scratch --duration-days` accepted 1–30 and rejected anything else up front.
|
|
122
|
+
if (!Number.isInteger(durationDays) || durationDays < 1 || durationDays > 30) {
|
|
123
|
+
throw new Error(`Scratch org duration must be a whole number of days from 1 to 30, got "${rawDurationDays}".`);
|
|
124
|
+
}
|
|
155
125
|
for (const hub of devHubs) {
|
|
156
126
|
try {
|
|
157
127
|
// eslint-disable-next-line no-await-in-loop -- each Dev Hub is only attempted after the previous one is exhausted
|
|
158
|
-
const createResult = await attemptScratchOrgCreation(hub, definitionFile,
|
|
128
|
+
const createResult = await attemptScratchOrgCreation(hub, definitionFile, durationDays);
|
|
159
129
|
if (!createResult) {
|
|
160
130
|
continue;
|
|
161
131
|
}
|
|
@@ -168,7 +138,7 @@ export async function createScratchOrg(options, devHubAliases) {
|
|
|
168
138
|
catch (error) {
|
|
169
139
|
logger.error(`Scratch org creation failed with Dev Hub ${hub.alias}:`);
|
|
170
140
|
const errorMessage = extractScratchOrgErrorMessage(error);
|
|
171
|
-
if (isScratchOrgLimitError(errorMessage)) {
|
|
141
|
+
if (isScratchOrgLimitError(error, errorMessage)) {
|
|
172
142
|
logger.warn(`Dev Hub ${hub.alias} reached its daily limit. Trying next Dev Hub...`);
|
|
173
143
|
continue;
|
|
174
144
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createScratchOrg.js","sourceRoot":"","sources":["../../src/build/createScratchOrg.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,0BAA0B,EAAE,eAAe,EAAoB,MAAM,uBAAuB,CAAC;AACtG,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"createScratchOrg.js","sourceRoot":"","sources":["../../src/build/createScratchOrg.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
import { runSf } from '../exec/sfCli.js';
|
|
17
16
|
import { logger } from '../logger.js';
|
|
18
17
|
import { authenticateOrg } from '../sfAuth.js';
|
|
18
|
+
import { deleteTargetScratchOrg } from '../sfOrg.js';
|
|
19
19
|
import { resolveDevHubs } from './devHubs.js';
|
|
20
20
|
import { ensureScratchOrgSession } from './scratchOrgAuth.js';
|
|
21
21
|
import { readScratchOrgInfo } from './scratchOrgInfo.js';
|
|
@@ -52,7 +52,8 @@ export async function deleteScratchOrg(options, devHubAlias) {
|
|
|
52
52
|
setDefault: true,
|
|
53
53
|
debug: options.debug,
|
|
54
54
|
});
|
|
55
|
-
|
|
55
|
+
// ensureScratchOrgSession just made the scratch org the default target org.
|
|
56
|
+
await deleteTargetScratchOrg();
|
|
56
57
|
logger.success('Scratch org deleted.');
|
|
57
58
|
}
|
|
58
59
|
catch (e) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deleteScratchOrg.js","sourceRoot":"","sources":["../../src/build/deleteScratchOrg.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"deleteScratchOrg.js","sourceRoot":"","sources":["../../src/build/deleteScratchOrg.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAQzD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,OAAgC,EAAE,WAAmB;IAC1F,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IACvC,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,MAAM,kBAAkB,EAAE,CAAC;QAClD,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,cAAc,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;QAClD,IAAI,GAAG,CAAC,QAAQ,KAAK,cAAc,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC;YAC9D,MAAM,IAAI,KAAK,CACb,aAAa,WAAW,KAAK,GAAG,CAAC,QAAQ,+DAA+D,cAAc,CAAC,UAAU,CAAC,cAAc,IAAI,SAAS,IAAI,CAClK,CAAC;QACJ,CAAC;QAED,IAAI,GAAG,CAAC,cAAc,EAAE,CAAC;YACvB,uFAAuF;YACvF,0FAA0F;YAC1F,+CAA+C;YAC/C,MAAM,eAAe,CAAC;gBACpB,QAAQ,EAAE,GAAG,CAAC,QAAQ;gBACtB,QAAQ,EAAE,GAAG,CAAC,QAAQ;gBACtB,WAAW,EAAE,GAAG,CAAC,WAAW;gBAC5B,UAAU,EAAE,GAAG,CAAC,cAAc;gBAC9B,gBAAgB,EAAE,IAAI;gBACtB,KAAK,EAAE,OAAO,CAAC,KAAK;aACrB,CAAC,CAAC;QACL,CAAC;QAED,MAAM,uBAAuB,CAAC,cAAc,CAAC,UAAU,EAAE;YACvD,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,UAAU,EAAE,IAAI;YAChB,KAAK,EAAE,OAAO,CAAC,KAAK;SACrB,CAAC,CAAC;QAEH,4EAA4E;QAC5E,MAAM,sBAAsB,EAAE,CAAC;QAC/B,MAAM,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACzC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,CAAC,KAAK,CAAC,mEAAmE,EAAG,CAAW,CAAC,OAAO,CAAC,CAAC;IAC1G,CAAC;AACH,CAAC"}
|
package/lib/build/pushScratch.js
CHANGED
|
@@ -13,25 +13,43 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
import {
|
|
16
|
+
import { promises as fs } from 'node:fs';
|
|
17
|
+
import path from 'node:path';
|
|
18
|
+
import { Duration } from '@salesforce/kit';
|
|
17
19
|
import { getDefaultPackageDirectory, readSfdxProject } from '@simplysf/simply-core';
|
|
18
|
-
import { runSf } from '../exec/sfCli.js';
|
|
19
20
|
import { logger } from '../logger.js';
|
|
21
|
+
import { deployProjectSource } from '../sfDeploy.js';
|
|
20
22
|
import { ensureScratchOrgSession } from './scratchOrgAuth.js';
|
|
21
23
|
import { readScratchOrgInfo } from './scratchOrgInfo.js';
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
'
|
|
25
|
-
'
|
|
26
|
-
'
|
|
27
|
-
'
|
|
24
|
+
/** File name suffixes of External Client App metadata, which scratch orgs reject. */
|
|
25
|
+
const INCOMPATIBLE_METADATA_SUFFIXES = [
|
|
26
|
+
'.eca-meta.xml',
|
|
27
|
+
'.ecaGlblOauth-meta.xml',
|
|
28
|
+
'.ecaOauth-meta.xml',
|
|
29
|
+
'.ecaOauthPlcy-meta.xml',
|
|
30
|
+
'.ecaPlcy-meta.xml',
|
|
28
31
|
];
|
|
32
|
+
/** Never searched: neither holds project metadata, and node_modules can be huge. */
|
|
33
|
+
const SKIPPED_DIRECTORIES = new Set(['.git', 'node_modules']);
|
|
34
|
+
async function findFiles(dir, matches) {
|
|
35
|
+
const found = [];
|
|
36
|
+
for (const entry of await fs.readdir(dir, { withFileTypes: true })) {
|
|
37
|
+
const entryPath = path.join(dir, entry.name);
|
|
38
|
+
if (entry.isDirectory() && !SKIPPED_DIRECTORIES.has(entry.name)) {
|
|
39
|
+
// eslint-disable-next-line no-await-in-loop -- a depth-first walk; the tree is small once node_modules is skipped
|
|
40
|
+
found.push(...(await findFiles(entryPath, matches)));
|
|
41
|
+
}
|
|
42
|
+
else if (entry.isFile() && matches(entry.name)) {
|
|
43
|
+
found.push(entryPath);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return found;
|
|
47
|
+
}
|
|
48
|
+
/** What `find . -type f -name '*.eca*-meta.xml' -delete` did, without depending on find. */
|
|
29
49
|
async function removeIncompatibleMetadata() {
|
|
30
50
|
logger.info('Removing incompatible metadata before push...');
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
await execa('find', [process.cwd(), '-type', 'f', '-name', pattern, '-delete']);
|
|
34
|
-
}
|
|
51
|
+
const files = await findFiles(process.cwd(), (name) => INCOMPATIBLE_METADATA_SUFFIXES.some((suffix) => name.endsWith(suffix)));
|
|
52
|
+
await Promise.all(files.map((file) => fs.rm(file)));
|
|
35
53
|
}
|
|
36
54
|
/** Authenticates to the scratch org, strips ECA-related metadata, and pushes source to it. */
|
|
37
55
|
export async function pushToScratch(options) {
|
|
@@ -43,18 +61,21 @@ export async function pushToScratch(options) {
|
|
|
43
61
|
debug: options.debug,
|
|
44
62
|
});
|
|
45
63
|
await removeIncompatibleMetadata();
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
64
|
+
// What `sf project deploy start --ignore-conflicts --wait 120 [--ignore-warnings] [--source-dir …]`
|
|
65
|
+
// did, against the scratch org ensureScratchOrgSession just made the default target org.
|
|
66
|
+
const sourceDirs = [];
|
|
50
67
|
if (options.scratchOrgSourceDir) {
|
|
51
|
-
|
|
68
|
+
sourceDirs.push(options.scratchOrgSourceDir);
|
|
52
69
|
const seedMetadataDir = getDefaultPackageDirectory(await readSfdxProject())?.seedMetadata?.path;
|
|
53
70
|
if (seedMetadataDir) {
|
|
54
|
-
|
|
71
|
+
sourceDirs.push(seedMetadataDir);
|
|
55
72
|
}
|
|
56
73
|
}
|
|
57
|
-
await
|
|
74
|
+
await deployProjectSource({
|
|
75
|
+
sourceDirs,
|
|
76
|
+
ignoreWarnings: options.ignoreWarnings ?? false,
|
|
77
|
+
wait: Duration.minutes(120),
|
|
78
|
+
});
|
|
58
79
|
logger.success('Source pushed to scratch org.');
|
|
59
80
|
}
|
|
60
81
|
//# sourceMappingURL=pushScratch.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pushScratch.js","sourceRoot":"","sources":["../../src/build/pushScratch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"pushScratch.js","sourceRoot":"","sources":["../../src/build/pushScratch.ts"],"names":[],"mappings":"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"}
|