Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: async validation for package version create #687

Merged
merged 11 commits into from
Jun 18, 2024
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ Create a package version in the Dev Hub org.
```
USAGE
$ sf package version create -v <value> [--json] [--flags-dir <value>] [--api-version <value>] [-b <value>] [-c |
--skip-validation] [-f <value>] [-k <value>] [-x] [-p <value>] [-d <value>] [--post-install-script <value>]
--skip-validation | --async-validation] [-f <value>] [-k <value>] [-x] [-p <value>] [-d <value>] [--post-install-script <value>]
[--post-install-url <value>] [--releasenotes-url <value>] [--skip-ancestor-check] [-t <value>] [--uninstall-script
<value>] [-e <value>] [-a <value>] [-n <value>] [-w <value>] [--language <value>] [--verbose]

Expand Down Expand Up @@ -554,6 +554,7 @@ FLAGS
that isn’t the highest released package version.
--skip-validation Skip validation during package version creation; you can’t promote unvalidated
package versions.
--async-validation Return a new package version before completing package validations.
--uninstall-script=<value> Uninstall script name; applies to managed packages only.
--verbose Display verbose command output.

Expand Down Expand Up @@ -602,6 +603,9 @@ EXAMPLES

$ sf package version create --path common --installation-key password123 --skip-validation

Create a package version and perform package validations asynchronously:
$ sf package version create --path common --installation-key password123 --async-validation

FLAG DESCRIPTIONS
-c, --code-coverage

Expand Down Expand Up @@ -652,6 +656,12 @@ FLAG DESCRIPTIONS
versions. Skipping validation can suppress important errors that can surface at a later stage. You can specify skip
validation or code coverage, but not both. Code coverage is calculated during validation.

--async-validation Return a new package version before completing package validations.

Specifying async validation returns the package version earlier in the process, allowing you to install and test
the new version right away. If your development team is using continuous integration (CI) scripts, async validation
can reduce your overall CI run time.

--uninstall-script=<value> Uninstall script name; applies to managed packages only.

The uninstall script is an Apex class within this package that is run in the installing org after uninstallations of
Expand Down
2 changes: 2 additions & 0 deletions command-snapshot.json
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@
"releasenotesurl",
"skipancestorcheck",
"skipvalidation",
"asyncvalidation",
"target-hub-org",
"targetdevhubusername",
"uninstallscript",
Expand Down Expand Up @@ -258,6 +259,7 @@
"releasenotes-url",
"skip-ancestor-check",
"skip-validation",
"async-validation",
"tag",
"target-dev-hub",
"uninstall-script",
Expand Down
18 changes: 18 additions & 0 deletions messages/package_version_create.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ We don’t calculate code coverage for org-dependent unlocked packages, or for p

<%= config.bin %> <%= command.id %> --path common --installation-key password123 --skip-validation

- Create a package version and perform package validations asynchronously:

<%= config.bin %> <%= command.id %> --path common --installation-key password123 --async-validation

# flags.package.summary

ID (starts with 0Ho) or alias of the package to create a version of.
Expand Down Expand Up @@ -129,6 +133,14 @@ Skips validation of dependencies, package ancestors, and metadata during package

Skipping validation suppresses errors that usually surface during package version creation. Instead, these errors surface at a later stage, such as installation or post-installation. If you encounter errors that are difficult to debug, retry package version creation without the --skip-validation parameter.

# flags.async-validation.summary

Return a new package version before completing package validations.

# flags.async-validation.description

Specifying async validation returns the package version earlier in the process, allowing you to install and test the new version right away. If your development team is using continuous integration (CI) scripts, async validation can reduce your overall CI run time.

# flags.skip-ancestor-check.summary

Overrides ancestry requirements, which allows you to specify a package ancestor that isn’t the highest released package version.
Expand Down Expand Up @@ -199,6 +211,12 @@ Version create.

%d minutes remaining until timeout. Create version status: %s

# packageVersionCreatePerformingValidations

The validations for this package version are in progress, but you can now begin testing this package version.
To determine whether all package validations completed successfully, run sf package version create report and review the Async Validation Status.
Async validated package versions can be promoted only if all validations completed successfully.

# packageVersionCreateFinalStatus

Create version status: %s
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
"bugs": "https://github.com/forcedotcom/cli/issues",
"dependencies": {
"@oclif/core": "^4",
"@salesforce/core": "^7.3.8",
"@salesforce/kit": "^3.1.0",
"@salesforce/packaging": "^3.5.16",
"@salesforce/sf-plugins-core": "^10.0.0",
"@salesforce/core": "^7.4.1",
"@salesforce/kit": "^3.1.6",
"@salesforce/packaging": "^3.7.1",
"@salesforce/sf-plugins-core": "^11.1.0",
"chalk": "^5.3.0"
},
"devDependencies": {
Expand Down
3 changes: 2 additions & 1 deletion schemas/package-convert.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@
"VerifyingFeaturesAndSettings",
"VerifyingDependencies",
"VerifyingMetadata",
"FinalizingPackageVersion"
"FinalizingPackageVersion",
"PerformingValidations"
]
}
}
Expand Down
3 changes: 2 additions & 1 deletion schemas/package-version-create-list.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@
"VerifyingFeaturesAndSettings",
"VerifyingDependencies",
"VerifyingMetadata",
"FinalizingPackageVersion"
"FinalizingPackageVersion",
"PerformingValidations"
]
}
}
Expand Down
3 changes: 2 additions & 1 deletion schemas/package-version-create-report.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@
"VerifyingFeaturesAndSettings",
"VerifyingDependencies",
"VerifyingMetadata",
"FinalizingPackageVersion"
"FinalizingPackageVersion",
"PerformingValidations"
]
}
}
Expand Down
3 changes: 2 additions & 1 deletion schemas/package-version-create.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@
"VerifyingFeaturesAndSettings",
"VerifyingDependencies",
"VerifyingMetadata",
"FinalizingPackageVersion"
"FinalizingPackageVersion",
"PerformingValidations"
]
}
}
Expand Down
3 changes: 3 additions & 0 deletions schemas/package-version-report.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@
"ValidationSkipped": {
"type": "boolean"
},
"ValidatedAsync": {
"type": "boolean"
},
"Name": {
"type": "string"
},
Expand Down
23 changes: 21 additions & 2 deletions src/commands/package/version/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,13 @@ export class PackageVersionCreateCommand extends SfCommand<PackageVersionCommand
summary: messages.getMessage('flags.skip-validation.summary'),
description: messages.getMessage('flags.skip-validation.description'),
default: false,
exclusive: ['code-coverage'],
exclusive: ['code-coverage', 'async-validation'],
}),
'async-validation': Flags.boolean({
summary: messages.getMessage('flags.async-validation.summary'),
description: messages.getMessage('flags.async-validation.description'),
default: false,
exclusive: ['skip-validation'],
}),
tag: Flags.string({
char: 't',
Expand Down Expand Up @@ -193,7 +199,8 @@ export class PackageVersionCreateCommand extends SfCommand<PackageVersionCommand
// no async methods
// eslint-disable-next-line @typescript-eslint/require-await
async (data: PackageVersionCreateReportProgress) => {
if (data.Status !== Package2VersionStatus.success && data.Status !== Package2VersionStatus.error) {
if (data.Status !== Package2VersionStatus.success && data.Status !== Package2VersionStatus.error && data.Status !== Package2VersionStatus.performingValidations
) {
const status = messages.getMessage('packageVersionCreateWaitingStatus', [
data.remainingWaitTime.minutes,
data.Status,
Expand Down Expand Up @@ -251,6 +258,18 @@ export class PackageVersionCreateCommand extends SfCommand<PackageVersionCommand
throw messages.createError('multipleErrors', [
result.Error?.map((e: string, i) => `${os.EOL}(${i + 1}) ${e}`).join(''),
]);
case Package2VersionStatus.performingValidations:
this.log(messages.getMessage('packageVersionCreatePerformingValidations'));
this.log(
mradulsf marked this conversation as resolved.
Show resolved Hide resolved
messages.getMessage(Package2VersionStatus.success, [
result.Id,
result.SubscriberPackageVersionId,
INSTALL_URL_BASE.toString(),
result.SubscriberPackageVersionId,
this.config.bin,
])
);
break;
case Package2VersionStatus.success:
this.log(
messages.getMessage(result.Status, [
Expand Down
15 changes: 15 additions & 0 deletions test/commands/package/packageVersion.nut.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,19 @@ describe('package:version:*', () => {
expect(result).to.match(/Run "sfd?x? package:version:create:report -i 08c.{15}" to query for status\./);
});

it('should create a new package version with async-validation', () => {
const result = execCmd(
`package:version:create --package ${pkgName} -x --async-validation --version-description "Initial version"`,
{ ensureExitCode: 0 }
).shellOutput.stdout;
// eslint-disable-next-line no-console
console.log(result);
expect(result).to.include("Package version creating request status is '");
expect(result).to.match(
/The validations for this package version are in progress, but you can now begin testing this package version./
);
});

// package:version:create --wait --json is tested in versionPromoteUpdate.nut.ts
it('should create a new package version and wait (human)', () => {
const result = execCmd(
Expand Down Expand Up @@ -311,6 +324,7 @@ describe('package:version:*', () => {
'InstallUrl',
'CodeCoverage',
'ValidationSkipped',
'ValidatedAsync',
'AncestorId',
'AncestorVersion',
'Alias',
Expand Down Expand Up @@ -353,6 +367,7 @@ describe('package:version:*', () => {
'CodeCoverage',
'HasPassedCodeCoverageCheck',
'ValidationSkipped',
'ValidatedAsync',
'AncestorId',
'AncestorVersion',
'Alias',
Expand Down
Loading
Loading