Overriding how an artifact deploys
Change an artifact's test level, test classes and ignored components for one release run, without rebuilding or republishing it.
--artifact-override changes how one package deploys for a single sfp release run: the test level, the Apex test classes Salesforce runs, and the components left out of the deployment. The artifact itself is not changed. Nothing is written to the registry, the release candidate or the artifact's metadata, so the next release deploys the artifact as it was built.
Use it when a published artifact deploys badly and a rebuild would also pick up changes merged since. A typical case is a diff package that deploys with RunRelevantTests and makes Salesforce queue far more tests than the change needs: an override runs the named classes instead.
Syntax
sfp release \
--releasecandidate core:Release-2.0.0 \
--targetorg production \
--repository myorg/myrepo \
--artifact-override "core:testClasses=AccountTest,LeadsSelector_Test;ignoreComponents=PermissionSet:Ops_Admin" \
--artifact-override "ui:testLevel=RunLocalTests" \
--artifact-override-reason "Deploy with the tests the change needs"Each --artifact-override names one package and one or more <key>=<value> pairs separated by ;:
<package>:<key>=<value>[;<key>=<value>]Repeat the flag for each package. --artifact-override-reason is required with it, and is printed with the overrides in the run's log.
| Key | Value |
|---|---|
testLevel | RunSpecifiedTests, RunLocalTests or RunRelevantTests |
testClasses | Comma-separated Apex test classes. Replaces the classes the artifact would run |
addTestClasses | Comma-separated Apex test classes to run in addition to the artifact's classes |
removeTestClasses | Comma-separated Apex test classes to take out of the artifact's classes |
ignoreComponents | Comma-separated Type:FullName entries to leave out of the deployment |
testClasses, addTestClasses and removeTestClasses set the test level to RunSpecifiedTests, so testLevel can be omitted with them. testClasses cannot be combined with addTestClasses or removeTestClasses, and none of the three can be combined with RunLocalTests or RunRelevantTests.
Only source and diff packages can be overridden. An override cannot be combined with --checkonly or --quickdeploy.
Test classes
addTestClasses, removeTestClasses and testLevel=RunSpecifiedTests without a class list start from the classes the artifact would run:
- The artifact's bound test classes, from deployment test suites, if it has any.
- Otherwise, for a
sourcepackage, the test classes in the package. - Otherwise none. A
diffpackage with no bound classes has nothing to add to or remove from, so name the classes to run withtestClasses.
The resolved list is bound to the package for this run, so the deployment treats it like the artifact's own bound list. A test class can be in the package or already in the target org. A namespaced class is written namespace.ClassName.
Salesforce runs whole test classes in a deployment, so Class.method entries are refused. With RunRelevantTests, Salesforce still requires 75% code coverage for each Apex class in the deployment.
The override's test level applies to every org, sandboxes included: a package whose tests are normally skipped on a sandbox runs the override's tests there.
Ignored components
ignoreComponents leaves components out of the package's deployment for this run. An entry is a metadata type and a full name, for example PermissionSet:Ops_Admin. Child components can be named on their own: CustomField:Account.Region__c leaves one field out of its object, and CustomLabel:Welcome_Message leaves one label out of the labels file. Every entry must be in the package.
Validation before deployment
sfp release checks every override after it has fetched the artifacts and before it installs dependencies or deploys anything. It reports every problem at once, then stops the release. The run fails when:
- a package is not in the release, or is not a
sourceordiffpackage - a test class is in neither the package nor the target org (one read-only query on
ApexClass) - a test class is written as
Class.method - a
removeTestClassesentry is not among the classes the artifact would run RunSpecifiedTestswould run no test classes- an
ignoreComponentsentry is not in the package - the reason is missing, a key is unknown or set twice, or a name is not a valid class name or
Type:FullName
Invalid artifact overrides:
- core: test class AcountTest is neither in the package payload nor in the target org
- core: ignoreComponents PermissionSet:Ops_Admn is not in the package payloadA dry run (--dryrun) performs the same checks, so a typo fails the rehearsal as well.
What the log shows
The Command : line at the start of the run does not print the values; the flag appears as --artifact-override=<see Artifact Overrides>. Before each overridden package deploys, an Artifact Overrides group lists the reason, the package version, the test level the package would have used without the override, each test class on its own line, and the ignored components:
Reason: Deploy with the tests the change needs
core@2.0.0.12
testLevel: RunSpecifiedTests (2 test classes, was RunRelevantTests)
AccountTest
LeadsSelector_Test
ignoreComponents: PermissionSet:Ops_AdminOn a CI/CD platform that collapses log groups, the block is one group. During the deployment, each ignored component is logged as Artifact override: ignoring <Type:FullName>, and the TestLevel: line shows the test level that was used.
Packages that are already installed
An override applies only to a package that deploys. When skipIfAlreadyInstalled skips a package because its version is already in the org, the release logs Artifact override for <package> not applied: this version is already installed and deploys nothing for it. Add --forceinstall to deploy it with the override.
Overrides through sfp server
A release requested through sfp server carries its overrides in the request, so the run records them and a retry of a failed or cancelled release job keeps them. Only users with the Owner role can set, change or remove overrides on a request or a retry; members and application tokens are refused with 403. A retry that leaves the overrides unchanged is allowed for anyone who can retry the release. A rollback deploys the earlier release as it was built, without overrides.
In codev, owners set overrides from the Request Release dialog. See Artifact overrides.