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.

KeyValue
testLevelRunSpecifiedTests, RunLocalTests or RunRelevantTests
testClassesComma-separated Apex test classes. Replaces the classes the artifact would run
addTestClassesComma-separated Apex test classes to run in addition to the artifact's classes
removeTestClassesComma-separated Apex test classes to take out of the artifact's classes
ignoreComponentsComma-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:

  1. The artifact's bound test classes, from deployment test suites, if it has any.
  2. Otherwise, for a source package, the test classes in the package.
  3. Otherwise none. A diff package with no bound classes has nothing to add to or remove from, so name the classes to run with testClasses.

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 source or diff package
  • 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 removeTestClasses entry is not among the classes the artifact would run
  • RunSpecifiedTests would run no test classes
  • an ignoreComponents entry 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 payload

A 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_Admin

On 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.

On this page