home / skills / jaganpro / sf-skills / sf-deploy

sf-deploy skill

/sf-deploy

This skill automates Salesforce DevOps deployments using sf CLI v2, guiding object-first deployments, flow activation, and scratch org management for reliable

npx playbooks add skill jaganpro/sf-skills --skill sf-deploy

Review the files below or copy the command above to add this skill to your agents.

Files (13)
SKILL.md
18.8 KB
---
name: sf-deploy
description: >
  Comprehensive Salesforce DevOps automation using sf CLI v2. Use when deploying
  metadata, managing scratch orgs, setting up CI/CD pipelines, or troubleshooting
  deployment errors.
license: MIT
metadata:
  version: "2.1.0"
  author: "Jag Valaiyapathy"
hooks:
  PreToolUse:
    - matcher: Bash
      hooks:
        - type: command
          command: "python3 ${SHARED_HOOKS}/scripts/guardrails.py"
          timeout: 5000
  PostToolUse:
    - matcher: "Write|Edit"
      hooks:
        - type: command
          command: "python3 ${SHARED_HOOKS}/suggest-related-skills.py sf-deploy"
          timeout: 5000
  SubagentStop:
    - type: command
      command: "python3 ${SHARED_HOOKS}/scripts/chain-validator.py sf-deploy"
      timeout: 5000
---

# sf-deploy: Comprehensive Salesforce DevOps Automation

Expert Salesforce DevOps engineer specializing in deployment automation, CI/CD pipelines, and metadata management using Salesforce CLI (sf v2).

## Core Responsibilities

1. **Deployment Management**: Execute, validate, and monitor deployments (metadata, Apex, LWC)
2. **DevOps Automation**: CI/CD pipelines, automated testing, deployment workflows
3. **Org Management**: Authentication, scratch orgs, environment management
4. **Quality Assurance**: Tests, code coverage, pre-production validation
5. **Troubleshooting**: Debug failures, analyze logs, provide solutions

---

## ⚠️ CRITICAL: Orchestration Order

```
┌─────────────────────────────────────────────────────────────────────────────┐
│  sf-metadata → sf-flow → sf-deploy → sf-data                               │
│                              ▲                                              │
│                         YOU ARE HERE                                        │
└─────────────────────────────────────────────────────────────────────────────┘
```

**Deploy order WITHIN sf-deploy**: Objects/Fields → Permission Sets → Apex → Flows (Draft) → Activate Flows

| Phase | Metadata Type | Why This Order |
|-------|---------------|----------------|
| 1 | Custom Objects/Fields | Everything references these |
| 2 | Permission Sets | FLS requires fields to exist |
| 3 | Apex Classes | @InvocableMethod needed before Flows |
| 4 | Flows (as Draft) | Flows reference fields and Apex |
| 5 | Activate Flows | Safe to activate after validation |

See `docs/orchestration.md` for detailed deployment workflows and agent deployment patterns.

---

## 🔑 Key Insights for Deployment

### Always Use --dry-run First

```bash
# CORRECT: Validate before deploying
sf project deploy start --dry-run --source-dir force-app --target-org alias
sf project deploy start --source-dir force-app --target-org alias

# WRONG: Deploying without validation
sf project deploy start --source-dir force-app --target-org alias  # Risky!
```

### Deploy Permission Sets After Objects

**Common Error:**
```
Error: In field: field - no CustomObject named ObjectName__c found
```

**Solution:** Deploy objects first, THEN permission sets referencing them.

### Flow Activation (4-Step Process)

**Flows deploy as Draft by default.** Activation steps:
1. Deploy with `<status>Draft</status>`
2. Verify: `sf project deploy report --job-id [id]`
3. Edit XML: `Draft` → `Active`
4. Redeploy

**Why?** Draft lets you verify before activating; if activation fails, flow still exists.

**Common Errors**: "Flow is invalid" (deploy objects first) | "Insufficient permissions" (check Manage Flow) | "Version conflict" (deactivate old version)

### FLS Warning After Deployment

**⚠️ Deployed fields may be INVISIBLE without FLS!**

After deploying custom objects/fields:
1. Deploy Permission Set granting field access
2. Assign Permission Set to user: `sf org assign permset --name PermSetName --target-org alias`
3. Verify field visibility

---

## CLI Version (CRITICAL)

**This skill uses `sf` CLI (v2.x), NOT legacy `sfdx` (v1.x)**

| Legacy sfdx (v1) | Modern sf (v2) |
|-----------------|----------------|
| `--checkonly` / `--check-only` | `--dry-run` |
| `sfdx force:source:deploy` | `sf project deploy start` |

## Prerequisites

Before deployment, verify:
```bash
sf --version              # Requires v2.x
sf org list               # Check authenticated orgs
test -f sfdx-project.json # Valid SFDX project
```

## Deployment Workflow (5-Phase)

### Phase 1: Pre-Deployment Analysis

**Gather via AskUserQuestion**: Target org, deployment scope, validation requirements, rollback strategy.

**Analyze**:
- Read `sfdx-project.json` for package directories
- Glob for metadata: `**/force-app/**/*.{cls,trigger,xml,js,html,css}`
- Grep for dependencies

**TodoWrite tasks**: Validate auth, Pre-tests, Deploy, Monitor, Post-tests, Verify

### Phase 2: Pre-Deployment Validation

```bash
sf org display --target-org <alias> --json             # Check connection
sf apex test run --test-level RunLocalTests --target-org <alias> --wait 10 --json  # Local tests
sf project deploy start --dry-run --test-level RunLocalTests --target-org <alias> --wait 30 --json  # Validate
```

### Phase 3: Deployment Execution

**Commands by scope**:
```bash
# Full metadata
sf project deploy start --target-org <alias> --wait 30 --json

# Specific components
sf project deploy start --source-dir force-app/main/default/classes --target-org <alias> --json

# Manifest-based
sf project deploy start --manifest manifest/package.xml --target-org <alias> --test-level RunLocalTests --wait 30 --json

# Quick deploy (after validation)
sf project deploy quick --job-id <validation-job-id> --target-org <alias> --json
```

Handle failures: Parse errors, identify failed components, suggest fixes.

### Phase 4: Post-Deployment Verification

```bash
sf project deploy report --job-id <job-id> --target-org <alias> --json
```

Verify components, run smoke tests, check coverage.

### Phase 5: Documentation

Provide summary with: deployed components, test results, coverage metrics, next steps.

See [examples/deployment-report-template.md](examples/deployment-report-template.md) for output format.

**Deployment Variants**: Production (full + RunAllTests), Hotfix (targeted + RunLocalTests), CI/CD (scripted + gates), Scratch (push source).

> **[Beta]** `--test-level RunRelevantTests` — Runs only tests relevant to changed components (Spring '26 / API v66.0 only). Not GA; use `RunLocalTests` for production deploys.

## CLI Reference

**Deploy**: `sf project deploy start [--dry-run] [--source-dir <path>] [--manifest <xml>] [--test-level <level>] --json`
**Quick**: `sf project deploy quick --job-id <id> --json` | **Status**: `sf project deploy report --json`
**Test**: `sf apex test run --test-level RunLocalTests` | **Coverage**: `sf apex get test --code-coverage`
**Org**: `sf org list` | `sf org display` | `sf org create scratch [--snapshot <name>]` | `sf org open`
**Metadata**: `sf project retrieve start` | `sf org list metadata --metadata-type <type>`
**Debug**: `sf project deploy start --dev-debug` — Show which files are ignored during deploy/retrieve (v2.117.7+)

## Error Handling

| Error | Cause | Solution |
|-------|-------|----------|
| FIELD_CUSTOM_VALIDATION_EXCEPTION | Validation rule blocking | Deactivate rules or use valid test data |
| INVALID_CROSS_REFERENCE_KEY | Missing dependency | Include dependencies in deploy |
| CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY | Trigger/validation error | Review trigger logic, check recursion |
| TEST_FAILURE | Test class failure | Fix test or code under test |
| INSUFFICIENT_ACCESS | Permission issue | Verify user permissions, FLS |

### Flow-Specific Errors

| Error | Cause | Solution |
|-------|-------|----------|
| "Element X is duplicated" | Elements not alphabetically ordered | Reorder Flow XML elements |
| "Element bulkSupport invalid" | Deprecated element (API 60.0+) | Remove `<bulkSupport>` |
| "Error parsing file" | Malformed XML | Validate XML syntax |

### Failure Response

1. Parse error output, identify failed components
2. Explain error in plain language
3. Suggest specific fixes with code examples
4. Provide rollback options if needed

## Best Practices

- **Always validate first**: Use `--dry-run` for production
- **Appropriate test levels**: RunLocalTests (deploy), RunAllTests (packages)
- **Code coverage**: >75% for production, >90% recommended
- **Use manifests**: `package.xml` for controlled deployments
- **Version control**: Commit before deploying, tag releases
- **Incremental deploys**: Small, frequent changes over large batches
- **Sandbox first**: Always test before production
- **Backup metadata**: Retrieve before major deployments
- **Quick deploy**: Use for validated changesets

---

## Trigger Deployment Safety

> 💡 *See `docs/trigger-deployment-safety.md` for comprehensive guide.*

### Pre-Deployment Guardrails

Before deploying triggers, verify:

| Check | Command/Action |
|-------|---------------|
| Trigger chain analysis | Map all triggers firing together |
| Cascade failure review | Identify atomic vs independent processes |
| Async decoupling | Use Queueable/Events for external calls |
| Savepoint usage | Verify explicit atomicity where needed |
| Test coverage | Include cascade success/failure tests |

### Common Trigger Cascade Risks

| Risk | Symptom | Solution |
|------|---------|----------|
| External callout in trigger | Cascade failure from HTTP timeout | Move to Queueable |
| Shared exception handling | One failure rolls back all | Isolate with try-catch or async |
| Recursive triggers | Stack overflow or DML errors | Use static flag recursion guard |
| Order-dependent triggers | Inconsistent behavior | Document and test trigger order |

### Pre-Deployment Checklist

```
TRIGGER SAFETY CHECKLIST:
□ Identify all triggers in deployment
□ Map trigger chains (which triggers fire together)
□ Verify cascade behavior is intentional
□ Check for external callouts → should be async
□ Confirm savepoint usage for atomic operations
□ Test both success and failure cascade scenarios
□ Validate with --dry-run before production deploy
```

### Recommended Async Patterns

```apex
// BAD: Synchronous external call in trigger
trigger AccountTrigger on Account (after insert) {
    ExternalService.sync(Trigger.new);  // Failure cascades
}

// GOOD: Async decoupling
trigger AccountTrigger on Account (after insert) {
    if (canEnqueueJob()) {
        System.enqueueJob(new AccountSyncQueueable(Trigger.newMap.keySet()));
    }
}
```

## CI/CD Integration

Standard pipeline workflow:
1. Authenticate (JWT/auth URL)
2. Validate metadata
3. Static analysis (PMD, ESLint)
4. Dry-run deployment
5. Run tests + coverage check
6. Deploy if validation passes
7. Notify

See [examples/deployment-workflows.md](examples/deployment-workflows.md) for scripts.

## Edge Cases

- **Large deployments**: Split into batches (limit: 10,000 files / 39 MB)
- **Test timeout**: Increase wait time or run tests separately
- **Namespace conflicts**: Handle managed package issues
- **API version**: Ensure source/target compatibility

## Cross-Skill Dependency Checklist

**Before deploying, verify these prerequisites from other skills:**

| Dependency | Check Command | Required For |
|------------|---------------|--------------|
| **TAF Package** | `sf package installed list --target-org alias` | TAF trigger pattern (sf-apex) |
| **Custom Objects/Fields** | `sf sobject describe --sobject ObjectName --target-org alias` | Apex/Flow field references |
| **Trigger_Action__mdt** | Check Setup → Custom Metadata Types | TAF trigger execution |
| **Queues** | `sf data query --query "SELECT Id,Name FROM Group WHERE Type='Queue'"` | Flow queue assignments |
| **Permission Sets** | `sf org list metadata --metadata-type PermissionSet` | FLS for custom fields |

**Common Cross-Skill Issues:**

| Error Message | Missing Dependency | Solution |
|--------------|-------------------|----------|
| `Invalid type: MetadataTriggerHandler` | TAF Package | Install apex-trigger-actions package |
| `Field does not exist: Field__c` | Custom Field or FLS | Deploy field or create Permission Set |
| `No such column 'Field__c'` | Field-Level Security | Assign Permission Set to running user |
| `SObject type 'Object__c' not supported` | Custom Object | Deploy object via sf-metadata first |
| `Queue 'QueueName' not found` | Queue Metadata | Deploy queue via sf-metadata first |

### sf-ai-agentscript Integration (Agent DevOps)

**Complete DevOps guide**: See `docs/agent-deployment-guide.md` for comprehensive agent deployment documentation.

#### Agent Metadata Types

| Metadata Type | Description |
|---------------|-------------|
| `Bot` | Top-level chatbot definition |
| `BotVersion` | Version configuration |
| `GenAiPlannerBundle` | Reasoning engine (LLM config) |
| `GenAiPlugin` | Topic definition |
| `GenAiFunction` | Action definition |

#### Agent Pseudo Metadata Type

The `Agent` pseudo type syncs all agent components at once:

```bash
# Retrieve agent + all dependencies from org
sf project retrieve start --metadata Agent:[AgentName] --target-org [alias] --json

# Deploy agent metadata to org
sf project deploy start --metadata Agent:[AgentName] --target-org [alias] --json
```

#### Agent Lifecycle Commands

```bash
# Activate agent (makes available to users)
sf agent activate --api-name [AgentName] --target-org [alias] --json

# Deactivate agent (REQUIRED before making changes)
sf agent deactivate --api-name [AgentName] --target-org [alias] --json

# Preview agent (simulated mode - safe testing) — interactive, no --json
sf agent preview --api-name [AgentName] --target-org [alias]

# Preview agent (live mode - real Apex/Flows) — interactive, no --json
sf agent preview --api-name [AgentName] --use-live-actions --target-org [alias]

# Validate Agent Script syntax
sf agent validate authoring-bundle --api-name [AgentName] --target-org [alias] --json
```

#### Full Agent Deployment Workflow

```bash
# 1. Deploy Apex classes (if any)
sf project deploy start --metadata ApexClass --target-org [alias] --json

# 2. Deploy Flows
sf project deploy start --metadata Flow --target-org [alias] --json

# 3. Validate Agent Script
sf agent validate authoring-bundle --api-name [AgentName] --target-org [alias] --json

# 4. Publish agent
sf agent publish authoring-bundle --api-name [AgentName] --target-org [alias] --json

# 5. Preview (simulated mode) — interactive, no --json
sf agent preview --api-name [AgentName] --target-org [alias]

# 6. Activate
sf agent activate --api-name [AgentName] --target-org [alias] --json
```

#### Modifying Existing Agents

**⚠️ Deactivation Required**: You MUST deactivate an agent before modifying topics, actions, or system instructions.

```bash
# 1. Deactivate
sf agent deactivate --api-name [AgentName] --target-org [alias] --json

# 2. Make changes to Agent Script

# 3. Re-publish
sf agent publish authoring-bundle --api-name [AgentName] --target-org [alias] --json

# 4. Re-activate
sf agent activate --api-name [AgentName] --target-org [alias] --json
```

#### Sync Agent Between Orgs

```bash
# 1. Retrieve from source org
sf project retrieve start --metadata Agent:[AgentName] --target-org source-org --json

# 2. Deploy dependencies to target org first
sf project deploy start --metadata ApexClass,Flow --target-org target-org --json

# 3. Deploy agent metadata
sf project deploy start --metadata Agent:[AgentName] --target-org target-org --json

# 4. Publish agent in target org
sf agent publish authoring-bundle --api-name [AgentName] --target-org target-org --json

# 5. Activate in target org
sf agent activate --api-name [AgentName] --target-org target-org --json
```

#### Agent-Specific CLI Reference

| Command | Description |
|---------|-------------|
| `sf agent publish authoring-bundle --api-name X --json` | Publish authoring bundle |
| `sf agent publish authoring-bundle --api-name X --skip-retrieve --json` | Publish without retrieving metadata (CI/CD) |
| `sf agent activate --api-name X --json` | Activate published agent |
| `sf agent deactivate --api-name X --json` | Deactivate agent for changes |
| `sf agent preview --api-name X` | Preview agent behavior (interactive — no `--json`) |
| `sf agent validate authoring-bundle --api-name X --json` | Validate Agent Script syntax |
| `sf org open agent --api-name X` | Open in Agentforce Builder |
| `sf org open authoring-bundle` | Open Agentforce Studio list view (v2.121.7+) |
| `sf agent generate authoring-bundle --api-name X` | Generate authoring bundle scaffolding |
| `sf agent generate authoring-bundle --api-name X --target-org <alias> --json` | Generate authoring bundle scaffolding |
| `sf project retrieve start --metadata Agent:X` | Retrieve agent + components |
| `sf project deploy start --metadata Agent:X` | Deploy agent metadata |

---

#### Package Management (2GP)

| Command | Description |
|---------|-------------|
| `sf package convert --package <1GP-id>` | Convert 1GP to 2GP package (GA, v2.92.7+) |
| `sf package push-upgrade schedule` | Schedule push upgrade |
| `sf package push-upgrade abort --package-push-request-id <id>` | Abort scheduled push |
| `sf package push-upgrade list` | List push upgrade requests |
| `sf package push-upgrade report --package-push-request-id <id>` | Get push upgrade status |
| `sf package version retrieve --package <package-id> --output-dir <dir>` | Retrieve 2GP package metadata (GA, v2.111.7+) |

## Deployment Script Template

Reusable multi-step deployment script: **[examples/deploy.sh](examples/deploy.sh)**

Deploys in order: Objects → Permission Sets → Apex (with tests) → Flows (Draft)

---

## Generate Package Manifest

**Auto-generate package.xml from source directory:**

```bash
# Generate from source
sf project generate manifest --source-dir force-app --name manifest/package.xml

# Generate for specific metadata types
sf project generate manifest \
    --metadata CustomObject:Account \
    --metadata ApexClass \
    --metadata Flow \
    --name manifest/package.xml

# Deploy using manifest
sf project deploy start --manifest manifest/package.xml --target-org alias
```

**When to use manifest vs source-dir:**

| Scenario | Use | Command |
|----------|-----|---------|
| Deploy everything | `--source-dir` | `sf project deploy start --source-dir force-app` |
| Deploy specific components | `--manifest` | `sf project deploy start --manifest package.xml` |
| CI/CD pipelines | `--manifest` | Controlled, reproducible deployments |
| Development iteration | `--source-dir` | Quick local changes |

---

## Notes

- **CLI**: Uses only `sf` (v2) with modern flag syntax
- **Auth**: Supports OAuth, JWT, Auth URL, web login
- **API**: Uses Metadata API (not Tooling API)
- **Async**: Use `--wait` to monitor; most deploys are async
- **Limits**: Be aware of Salesforce governor limits

---

## License

MIT License. See [LICENSE](LICENSE) file.
Copyright (c) 2024-2025 Jag Valaiyapathy

Overview

This skill automates Salesforce DevOps using the modern sf CLI (v2.x) to manage metadata deployments, scratch orgs, CI/CD pipelines, and deployment troubleshooting. It enforces safe orchestration order for objects, permission sets, Apex, and flows, and produces actionable reports and remediation steps. Use it to validate, execute, and monitor deployments with built-in guardrails for production safety.

How this skill works

The skill inspects project metadata (sfdx-project.json, package.xml, source dirs) and orchestrates deploys using sf project deploy commands with --dry-run validation before execution. It parses deployment reports and error output, suggests fixes for common failures (FLS, missing dependencies, tests), and handles flow activation as a separate verification step. It also integrates with CI/CD flows, scratch org management, and post-deploy verification commands to produce a compact deployment summary.

When to use it

  • Deploy metadata to sandboxes or production with sf CLI v2.x
  • Run CI/CD pipelines that require validation gates and test coverage checks
  • Create or manage scratch orgs and environment snapshots for feature work
  • Troubleshoot deployment failures and get remediation guidance
  • Deploy agent/AI metadata or orchestrate multi-component releases involving Apex and Flows

Best practices

  • Always run sf project deploy start --dry-run before actual deployment
  • Deploy custom objects/fields first, then permission sets, then Apex, then flows (deploy flows as Draft, then activate)
  • Use manifest-based or targeted incremental deploys instead of large monolithic batches
  • Run RunLocalTests or RunAllTests depending on environment; prefer RunAllTests for production packages
  • Commit and tag releases; back up metadata before major changes and validate in sandbox first
  • Use quick deploy after a successful validation to speed production rollouts

Example use cases

  • Full release to production: validate with --dry-run, run RunAllTests, then quick deploy validated job
  • Hotfix: targeted deploy of specific classes + RunLocalTests and immediate quick deploy
  • CI pipeline: authenticate via JWT, static analysis, dry-run gate, tests, deploy and notify
  • Agent deployment: deploy Apex then Flows, validate agent authoring bundle, publish and activate agent with required deactivation step

FAQ

Which CLI must I use?

Use sf CLI v2.x. The legacy sfdx (v1) commands and flags differ; for example, use --dry-run instead of --checkonly.

Why do flows deploy as Draft?

Flows deploy as Draft to allow validation before activation. After a successful draft deploy, edit XML to Active and redeploy to activate safely.

What common error means a dependency is missing?

INVALID_CROSS_REFERENCE_KEY or 'no CustomObject named' indicate missing objects/fields; deploy those dependencies first.