Smart Deploy
sfdt deploy --smart deploys only the metadata that changed between two git refs, picks the
minimal safe Apex test level, honors overwrite protection, and runs a self-contained,
non-interactive sf project deploy (no archive/commit side effects).
sfdt deploy --smart --dry-run # validate the delta (recommended in CI)
sfdt deploy --smart --delta-base main # delta vs main
sfdt deploy --smart --delta-base origin/main --delta-head HEAD --org uat
sfdt deploy --smart --prod # treat target as production
sfdt deploy --smart --ai-fix # AI analysis on failure
sfdt deploy --smart --pr-comment # decorate the PR with the resultHow it works
- Delta — computes changed metadata between
--delta-base(defaultmain, ordeployment.smart.deltaBase) and--delta-head(defaultHEAD) using the same engine assfdt manifest. Additive and destructive changes are separated automatically. - Overwrite protection — members listed in
package-no-overwrite.xml(configurable;*wildcard supported) are removed from the deploy so they’re never overwritten. - Smart test selection:
- Production (or
--prod/assumeProd) →RunLocalTests, never downgraded. - No impacting metadata changed (Apex/triggers/flows) →
NoTestRun. - Only Apex test classes changed →
RunSpecifiedTests(those tests). - Any other impacting change →
RunLocalTests. - When
RunSpecifiedTestsis chosen, the selection is widened by Spring ‘26@IsTestannotations: test classes whose@IsTest(testFor='Type:Name')targets a changed component, plus every@IsTest(critical=true)class, are included automatically (sources are comment/string-sanitized first, so commented-out annotations don’t count). - On a non-production org with
sourceApiVersion≥ 66,deployment.smart.useRelevantTests(defaultfalse) opts into Salesforce’s betaRunRelevantTestsinstead of theRunLocalTestsfallback. Production deploys are never auto-downgraded.
- Production (or
- Execute —
sf project deploy validate(with--dry-run) orsf project deploy start, including--post-destructive-changeswhen needed.
Agentforce metadata is delta-aware. The manifest engine recognises Agentforce / Einstein
agent types — Bot, BotVersion (member Bot.Version), GenAiPlanner, GenAiPlannerBundle,
GenAiPlugin, GenAiFunction, GenAiPromptTemplate, AiEvaluationDefinition, and
AiAuthoringBundle (the Agent Script authoring bundle). Previously these changes mapped to
UNKNOWN and were silently dropped from deploy --smart deltas and sfdt manifest output.
Options
| Flag | Notes |
|---|---|
--smart | Enable smart delta deploy |
--delta-base <ref> / --delta-head <ref> | Git refs to diff (defaults: config/main … HEAD) |
--overwrite-manifest <path> | Path to package-no-overwrite.xml (overrides config) |
--prod | Treat the target as production (never downgrade tests) |
--dry-run | Validate only (no changes applied) |
--ai-deps | Run AI dependency cleanup on the computed delta first |
--ai-fix | On failure, run AI deploy-error analysis (or the auto-fix loop, below) |
--max-turns <n> | Auto-fix iteration cap (overrides ai.agent.maxTurns) |
--pr-comment | Post the delta + outcome to the current PR (via gh) |
--notify | Dispatch deploy-success / deploy-failure through configured notification channels after the run (see below) |
--agent | Non-interactive mode (AI prompts never block on input) |
Configuration
{
"deployment": {
"smart": {
"enabled": false,
"deltaBase": "main",
"noOverwriteManifest": "manifest/package-no-overwrite.xml",
"impactingTypes": ["ApexClass", "ApexTrigger", "Flow"],
"downgradeTestsOnNonProd": true,
"useRelevantTests": false,
"assumeProd": false
}
}
}useRelevantTests opts non-production orgs on API ≥ 66 into Salesforce’s beta RunRelevantTests
(the org analyzes the payload and runs only the relevant tests) in place of the RunLocalTests
fallback. It’s beta — a known sf CLI issue can
cause deploy validate to run zero tests with this level, so verify with --json output.
Notifications
sfdt deploy --smart --notify dispatches deploy-success / deploy-failure through the
configured notification channels after the run (previously --notify was
ignored with a warning in smart mode — it only worked on the standard manifest deploy). The
notification includes the delta refs, additive/destructive counts, and test level; validate-only
runs say “Validation (check-only)”. When no channels are configured it warns instead of failing.
AI deploy-error resolution & auto-fix loop
--ai-fix captures the failure output and runs the editable deploy-error prompt to explain the
failure and suggest fixes (read-only).
When ai.agent.enabled and ai.agent.allowWrite are set (CLI providers only — the http
provider can’t run tools), --ai-fix instead runs a bounded coding-agent auto-fix loop: the
agent edits the repo, re-validates via a dry-run each turn, and stops on success or after
maxTurns. It never deploys, the failure text is redacted before prompting, and everything
defaults off.
{ "ai": { "agent": { "enabled": false, "maxTurns": 3, "allowWrite": false } } }Delta deployments are git-diff based and don’t automatically pull in parent metadata (e.g. a
changed field without its object). Use --ai-deps for an AI dependency pass, or maintain
package-no-overwrite.xml and review the computed delta in --dry-run first.
See Retrofit & PR Comments for promoting org changes through smart-deploy, and CI/CD Integration for the generated PR validation pipeline.