Set up and run Salesforce delivery for Spring '26 — SFDX project layout and `sfdx-project.json`, scratch orgs vs sandboxes and source tracking, the `sf` CLI (`project deploy validate` then `deploy quick`, `retrieve start`, `org create scratch`), branching and release flow, DevOps Center vs Gearset/Copado vs a GitHub Actions pipeline you own, unlocked and 2GP package promotion, quality gates with Code Analyzer v5 and `code-analyzer.yml`, Apex and Flow test levels, deploying flows as active, destructive changes, environment variables and secrets, Sandbox Preview testing and rollback.
When agents use itUse this whenever the user sets up or debugs a Salesforce pipeline, writes a deploy or validate command, hits a failed deployment, a coverage gate, a `package.xml` or `.forceignore` problem, asks how to promote a change from a sandbox to production, how to delete metadata safely, or how to test against the next release. Also apply it when a "deployment problem" turns out to be a project-structure or environment-strategy problem.
Install
Copilot (VS Code, Visual Studio, Copilot CLI and github.com) reads skills from the repository — commit them so the whole team gets them.
npx skills add AGCO-Global/org-skills --skill salesforce-devops -a github-copilot
# or with the org installer (adds .github/skills/salesforce-devops):
npx -y github:AGCO-Global/org-skills add skill salesforce-devops
Uses the open skills CLI. Works with Claude Code, Codex, Cursor, Copilot, Gemini CLI, OpenCode, Windsurf and 60+ others — it asks which agent to install into.
Installs the salesforce-devops-skills plugin, which bundles all Salesforce / DevOps skills and keeps them updated.
/plugin marketplace add AGCO-Global/org-skills
/plugin install salesforce-devops-skills@org-skills
# or just this skill, in this repository:
npx skills add AGCO-Global/org-skills --skill salesforce-devops -a claude-code
Use Download .zip above, then upload it under Customize → Skills → Upload skill. Team and Enterprise admins can sync this repo as a plugin marketplace instead.
Installs into .agents/skills/, which Codex reads.
npx skills add AGCO-Global/org-skills --skill salesforce-devops -a codex
Installs into Cursor's skills folder.
npx skills add AGCO-Global/org-skills --skill salesforce-devops -a cursor
Installs into Gemini CLI's skills folder.
npx skills add AGCO-Global/org-skills --skill salesforce-devops -a gemini-cli
Any tool with rules, instructions or custom prompts: use Copy SKILL.md above and paste it in. It is plain Markdown.
Commands use your normal git sign-in to GitHub, so they work while the repository is private. Node.js 20+ required.
Try it — example prompts
Prompts this skill is tested against, and what a good answer includes.
Set up a GitHub Actions pipeline for our Salesforce repo that deploys to production.
JWT login with an External Client App and a dedicated integration userlint and Jest before anything touching an orgsf code-analyzer run with a severity thresholdsf project deploy validate then sf project deploy quick --job-idscratch org build to prove the repo deploys from nothingJUnit and coverage artifacts
Our production deploy takes 70 minutes of tests inside the release window.
validate in CI ahead of time and quick-deploy in the windowa validation stays quick-deployable for 10 daysRunRelevantTests or a delta manifest to shorten the validationre-validate if the branch moves
We need to delete an old Apex class and its Visualforce page from production.
destructiveChangesPost.xml manifest--post-destructive-changes on the deploy, in the same deploy as the change that stops using themreviewed by a second personno manual deletion in the org
Should we use scratch orgs or developer sandboxes for feature work?
scratch orgs by default, created and deleted per featuresandbox when the org's metadata cannot be recreatedthe scratch org definition file is a claim about productionCI creates and deletes its own scratch org
Salesforce upgrades our org next month. What should we do?
deploy the release branch to a Sandbox Preview orgrun Apex, Flow, Jest and browser suites thereread critical updates and retirements in the release notesfix before the production upgrade
Skill contents
Salesforce DevOps
Targets: Salesforce Spring '26 (API 66.0), sf CLI · Verified: 2026-09 against https://developer.salesforce.com (Salesforce DX Developer Guide, CLI command reference) and the salesforcecli/plugin-deploy-retrieve and forcedotcom/code-analyzer repositories
Git is the source of truth; an org is a deployment target that people can edit behind your back. Everything in a Salesforce pipeline follows from that: source-tracked development, a validation that is reused rather than repeated, gates that fail fast and cheap, and a release that can be described in one command.
1. Decide first
Question
Default
Change when
Development environment
Scratch org from config/project-scratch-def.json, recreated per feature
The org's metadata cannot be recreated (legacy tangle, huge managed-package estate) → developer sandbox with source tracking
Source of truth
Git, with source tracking pushing to the dev environment
Never the org. Metadata changed by an admin is retrieved into a branch and reviewed like code
Unit of deployment
Metadata from the repo through sf project deploy
Reusable modules shared across teams or orgs → unlocked / 2GP packages (salesforce-frontend-architecture → packaging-and-sharing.md)
Production deploy
sf project deploy validate in CI, then sf project deploy quick --job-id in the window
A small, low-risk change on a quiet org can deploy directly with --test-level RunLocalTests
Test level
RunLocalTests on staging and production
RunSpecifiedTests for a hotfix with a named list; RunRelevantTests (Beta) to shorten long validations; NoTestRun only in scratch/dev sandboxes
Tooling
A pipeline you own (sf CLI in GitHub Actions/Azure Pipelines)
Admin-led org with little git literacy → DevOps Center; large regulated estate wanting delta deploys, backup and audit out of the box → Gearset/Copado, and the gates below still apply
Static analysis
Code Analyzer v5 (sf code-analyzer run) with a committed code-analyzer.yml
Never the retired sf scanner run / standalone PMD plugin
Branching
Trunk-based with short-lived feature branches; release branch cut per release
Scheduled release trains with long stabilisation → main + release/*, hotfix branched from the release tag
2. Project layout and source tracking
sfdx-project.json packageDirectories, sourceApiVersion (bump every release)
config/ project-scratch-def.json, dev-scratch-def.json
force-app/ source-format metadata
manifest/ package.xml, destructiveChangesPre.xml, destructiveChangesPost.xml
scripts/ apex/ (data seeding), shell/
data/ sf data import tree plans for test data
.forceignore profiles, settings and anything the org owns
sf project deploy preview before every deploy shows what would change and, with source tracking, what conflicts with the org.
.forceignore is a design decision, not a dumping ground: usually most profiles (use permission sets), org-specific settings, and package-installed metadata. Everything ignored is metadata nobody reviews — so do not blanket-ignore the four admin profiles, whose FLS the org requires on every new field.
Retrieve admin changes deliberately: sf project retrieve start --metadata Flow:Order_After_Update into a branch, review the diff, merge. "Who changed this in production" is answered by git only if this is a habit.
sourceApiVersion and apiVersion in metadata files drift; bump them on the release cadence, not per file.
3. Environments
Environment
Refresh cadence
Use
Scratch org
Created and deleted per feature (--duration-days 1–30)
Development and CI; the only place you prove the repo builds from nothing
Developer / Developer Pro sandbox
Daily
Dev work that cannot use scratch orgs; Dev Pro holds more data
Partial Copy sandbox
Every 5 days
Integration and UAT with a sampled data set
Full sandbox
Every 29 days
Performance and load testing, migration rehearsals, the final release rehearsal
Sandbox Preview
During each preview window
A sandbox on the next release: run the whole suite there before the org is upgraded, three times a year
Scratch org creation belongs in CI: sf org create scratch --definition-file config/project-scratch-def.json --alias ci --duration-days 1 --wait 20, deleted in an always() step. Leaked scratch orgs exhaust the daily allocation and block everyone.
4. Validate once, deploy fast
# in CI, on the pull request or the release branch
sf project deploy validate --target-org prod --source-dir force-app \
--test-level RunLocalTests --coverage-formatters cobertura --junit \
--results-dir test-results --wait 90 # prints the job id; valid for 10 days
# in the release window, no tests re-run
sf project deploy quick --target-org prod --job-id 0Af0x000017yLUFCA2 --wait 30
A validation is valid for 10 days, so the release window costs minutes instead of an hour of re-running tests. Other commands worth knowing by heart: sf project deploy report --job-id, sf project deploy resume --job-id, sf project deploy cancel --job-id, and --dry-run on deploy start for a local check. Full workflow, delta deploys and artifacts in references/pipeline-workflow.md.
5. Quality gates
Run cheapest first, and fail the build on each:
npm run lint (ESLint @salesforce/eslint-config-lwc) and Prettier with the Apex plugin.
npm run test:unit — Jest for LWC (salesforce-frontend-testing).
sf code-analyzer run --workspace force-app --severity-threshold 3 --output-file code-analyzer.csv — PMD, ESLint, RetireJS, Regex, CPD, the Flow Scanner and the Graph Engine in one result set, configured by a committed code-analyzer.yml (references/code-analyzer-config.md).
sf project deploy validate --test-level RunLocalTests against the target org, with JUnit and coverage output published to the build.
sf flow run test --test-level RunLocalTests for Flow Tests (the CI user needs View All Data), or sf logic run test for Apex and Flow together.
Coverage: the org's bar is 90 %+ across Apex; the platform's 75 % is only the deployment floor, so a build that merely clears 75 % still fails review. Flow coverage matters separately when deploying flows as active (§6).
6. The awkward metadata
Flows: with Deploy processes and flows as active on, a deployed flow version becomes active and the org enforces flow test coverage from Apex tests; with it off, every flow lands inactive. Decide once, per org, and write it down. Details in flow-testing-and-deployment.md in ../../automation/salesforce-automation/references/.
Deletions: --pre-destructive-changes / --post-destructive-changes with a manifest, in the same deploy as the change that stops using the component. --purge-on-delete skips the recycle bin on sandboxes. Never delete by hand in production and "fix the repo later".
Profiles: deploy permission sets and permission set groups for end-user access; keep profiles otherwise minimal, because a profile in a deploy silently carries every unrelated setting the source org had. The exception is deliberate: the four admin profiles (System Administrator, System Specialist, System Specialist Lite, System Integration) carry FLS for every new field, so they need a deployment path — deploy them with an explicit field-permissions-only manifest rather than the whole profile.
Secrets and per-environment values: Custom Metadata for configuration, Named/External Credentials or Credential__c records for secrets (seeded per environment, never deployed), and environment differences expressed as metadata the pipeline selects — never a sed on a deploy artefact.
Managed packages: install them into scratch orgs from the definition file or a script step; a build that needs a hand-installed package is not reproducible.
7. Deliverable format
## Environments — what each org is for, refresh cadence, who owns it
## Branching & release — branch model, cut points, hotfix path
## Pipeline — jobs in order with the exact sf commands and the gate each one enforces
## Deploy — validate command, quick-deploy command, rollback plan
## Gates — Code Analyzer config, test levels, coverage expectations
## Risks — destructive changes, active flows, profiles, package installs, Sandbox Preview date
Checklist
Every change reaches production from git; admin changes are retrieved and reviewed
sfdx-project.json, .forceignore and sourceApiVersion deliberate and current
Feature environments are disposable; CI creates and deletes its own scratch org
Pipeline order is lint → Jest → Code Analyzer → validate → flow tests
Production goes through deploy validate + deploy quick, not a fresh deploy
Test level stated per environment; NoTestRun never targets production
Destructive changes are in a manifest and in the same deploy as the code change
Flow activation policy decided; flow coverage understood before an active deploy
Rollback plan exists: previous package version or a reverse deploy, rehearsed once
The suite runs against a Sandbox Preview org before each Salesforce release
Anti-patterns
Change sets as the release mechanism → source-tracked deploys from git.
sf scanner run / a standalone PMD plugin → Code Analyzer v5 with code-analyzer.yml.
Deploying straight to production with full tests in the window → validate in CI, quick-deploy in the window.
--test-level NoTestRun to "get it out" → fix the tests; NoTestRun is for dev environments only.
--ignore-conflicts as a habit → it overwrites somebody's org change; look at the conflict.
Whole profiles deployed between orgs → permission sets and permission set groups; the four admin profiles travel as field permissions only.
Deleting metadata by hand in production → destructive changes manifest in the deploy.
Long-lived feature branches against a shared sandbox → short branches, disposable orgs.
No Sandbox Preview run → three times a year the release breaks something nobody tested.
Go deeper
references/pipeline-workflow.md — a complete CI/CD workflow with validate, quick deploy, delta deploys, artifacts and rollback.
references/environments-and-release.md — scratch org definitions, sandbox strategy and refresh planning, Sandbox Preview, the release checklist and rollback drill.
references/code-analyzer-config.md — code-analyzer.yml structure, engines and rule selectors, severity gates, suppressions with an expiry habit.
Sibling skills: salesforce-frontend-architecture for packaging decisions, apex-testing and salesforce-frontend-testing for the test suites, salesforce-automation for flow deployment, salesforce-security for the security gates, salesforce-code-review for what a reviewer checks, salesforce-org-conventions for the org's naming and mandated patterns.
---
name: salesforce-devops
description: >
Set up and run Salesforce delivery for Spring '26 — SFDX project layout and `sfdx-project.json`, scratch orgs vs sandboxes and source tracking, the `sf` CLI (`project deploy validate` then `deploy quick`, `retrieve start`, `org create scratch`), branching and release flow, DevOps Center vs Gearset/Copado vs a GitHub Actions pipeline you own, unlocked and 2GP package promotion, quality gates with Code Analyzer v5 and `code-analyzer.yml`, Apex and Flow test levels, deploying flows as active, destructive changes, environment variables and secrets, Sandbox Preview testing and rollback. Use this whenever the user sets up or debugs a Salesforce pipeline, writes a deploy or validate command, hits a failed deployment, a coverage gate, a `package.xml` or `.forceignore` problem, asks how to promote a change from a sandbox to production, how to delete metadata safely, or how to test against the next release. Also apply it when a "deployment problem" turns out to be a project-structure or environment-strategy problem.
metadata:
technology: Salesforce
type: devops
---
# Salesforce DevOps
> **Targets:** Salesforce Spring '26 (API 66.0), `sf` CLI · **Verified:** 2026-09 against https://developer.salesforce.com (Salesforce DX Developer Guide, CLI command reference) and the `salesforcecli/plugin-deploy-retrieve` and `forcedotcom/code-analyzer` repositories
Git is the source of truth; an org is a deployment target that people can edit behind your back. Everything in a Salesforce pipeline follows from that: source-tracked development, a validation that is reused rather than repeated, gates that fail fast and cheap, and a release that can be described in one command.
## 1. Decide first
| Question | Default | Change when |
|---|---|---|
| Development environment | **Scratch org** from `config/project-scratch-def.json`, recreated per feature | The org's metadata cannot be recreated (legacy tangle, huge managed-package estate) → developer sandbox with source tracking |
| Source of truth | Git, with source tracking pushing to the dev environment | Never the org. Metadata changed by an admin is retrieved into a branch and reviewed like code |
| Unit of deployment | **Metadata from the repo** through `sf project deploy` | Reusable modules shared across teams or orgs → unlocked / 2GP packages (`salesforce-frontend-architecture` → `packaging-and-sharing.md`) |
| Production deploy | `sf project deploy validate` in CI, then **`sf project deploy quick --job-id`** in the window | A small, low-risk change on a quiet org can deploy directly with `--test-level RunLocalTests` |
| Test level | `RunLocalTests` on staging and production | `RunSpecifiedTests` for a hotfix with a named list; `RunRelevantTests` (Beta) to shorten long validations; `NoTestRun` only in scratch/dev sandboxes |
| Tooling | A pipeline you own (`sf` CLI in GitHub Actions/Azure Pipelines) | Admin-led org with little git literacy → **DevOps Center**; large regulated estate wanting delta deploys, backup and audit out of the box → Gearset/Copado, and the gates below still apply |
| Static analysis | **Code Analyzer v5** (`sf code-analyzer run`) with a committed `code-analyzer.yml` | Never the retired `sf scanner run` / standalone PMD plugin |
| Branching | Trunk-based with short-lived feature branches; release branch cut per release | Scheduled release trains with long stabilisation → `main` + `release/*`, hotfix branched from the release tag |
## 2. Project layout and source tracking
```
sfdx-project.json packageDirectories, sourceApiVersion (bump every release)
config/ project-scratch-def.json, dev-scratch-def.json
force-app/ source-format metadata
manifest/ package.xml, destructiveChangesPre.xml, destructiveChangesPost.xml
scripts/ apex/ (data seeding), shell/
data/ sf data import tree plans for test data
.forceignore profiles, settings and anything the org owns
```
- `sf project deploy preview` before every deploy shows what would change and, with source tracking, what conflicts with the org.
- `.forceignore` is a design decision, not a dumping ground: usually most profiles (use permission sets), org-specific settings, and package-installed metadata. Everything ignored is metadata nobody reviews — so do not blanket-ignore the four admin profiles, whose FLS the org requires on every new field.
- Retrieve admin changes deliberately: `sf project retrieve start --metadata Flow:Order_After_Update` into a branch, review the diff, merge. "Who changed this in production" is answered by git only if this is a habit.
- `sourceApiVersion` and `apiVersion` in metadata files drift; bump them on the release cadence, not per file.
## 3. Environments
| Environment | Refresh cadence | Use |
|---|---|---|
| Scratch org | Created and deleted per feature (`--duration-days 1–30`) | Development and CI; the only place you prove the repo builds from nothing |
| Developer / Developer Pro sandbox | Daily | Dev work that cannot use scratch orgs; Dev Pro holds more data |
| Partial Copy sandbox | Every 5 days | Integration and UAT with a sampled data set |
| Full sandbox | Every 29 days | Performance and load testing, migration rehearsals, the final release rehearsal |
| **Sandbox Preview** | During each preview window | A sandbox on the *next* release: run the whole suite there before the org is upgraded, three times a year |
Scratch org creation belongs in CI: `sf org create scratch --definition-file config/project-scratch-def.json --alias ci --duration-days 1 --wait 20`, deleted in an `always()` step. Leaked scratch orgs exhaust the daily allocation and block everyone.
## 4. Validate once, deploy fast
```bash
# in CI, on the pull request or the release branch
sf project deploy validate --target-org prod --source-dir force-app \
--test-level RunLocalTests --coverage-formatters cobertura --junit \
--results-dir test-results --wait 90 # prints the job id; valid for 10 days
# in the release window, no tests re-run
sf project deploy quick --target-org prod --job-id 0Af0x000017yLUFCA2 --wait 30
```
A validation is valid for 10 days, so the release window costs minutes instead of an hour of re-running tests. Other commands worth knowing by heart: `sf project deploy report --job-id`, `sf project deploy resume --job-id`, `sf project deploy cancel --job-id`, and `--dry-run` on `deploy start` for a local check. Full workflow, delta deploys and artifacts in `references/pipeline-workflow.md`.
## 5. Quality gates
Run cheapest first, and fail the build on each:
1. `npm run lint` (ESLint `@salesforce/eslint-config-lwc`) and Prettier with the Apex plugin.
2. `npm run test:unit` — Jest for LWC (`salesforce-frontend-testing`).
3. `sf code-analyzer run --workspace force-app --severity-threshold 3 --output-file code-analyzer.csv` — PMD, ESLint, RetireJS, Regex, CPD, the Flow Scanner and the Graph Engine in one result set, configured by a committed `code-analyzer.yml` (`references/code-analyzer-config.md`).
4. `sf project deploy validate --test-level RunLocalTests` against the target org, with JUnit and coverage output published to the build.
5. `sf flow run test --test-level RunLocalTests` for Flow Tests (the CI user needs **View All Data**), or `sf logic run test` for Apex and Flow together.
Coverage: the org's bar is **90 %+** across Apex; the platform's 75 % is only the deployment floor, so a build that merely clears 75 % still fails review. Flow coverage matters separately when deploying flows as active (§6).
## 6. The awkward metadata
- **Flows**: with *Deploy processes and flows as active* on, a deployed flow version becomes active and the org enforces flow test coverage from Apex tests; with it off, every flow lands inactive. Decide once, per org, and write it down. Details in `flow-testing-and-deployment.md` in `../../automation/salesforce-automation/references/`.
- **Deletions**: `--pre-destructive-changes` / `--post-destructive-changes` with a manifest, in the same deploy as the change that stops using the component. `--purge-on-delete` skips the recycle bin on sandboxes. Never delete by hand in production and "fix the repo later".
- **Profiles**: deploy permission sets and permission set groups for end-user access; keep profiles otherwise minimal, because a profile in a deploy silently carries every unrelated setting the source org had. The exception is deliberate: the four admin profiles (System Administrator, System Specialist, System Specialist Lite, System Integration) carry FLS for every new field, so they need a deployment path — deploy them with an explicit field-permissions-only manifest rather than the whole profile.
- **Secrets and per-environment values**: Custom Metadata for configuration, Named/External Credentials or `Credential__c` records for secrets (seeded per environment, never deployed), and environment differences expressed as metadata the pipeline selects — never a `sed` on a deploy artefact.
- **Managed packages**: install them into scratch orgs from the definition file or a script step; a build that needs a hand-installed package is not reproducible.
## 7. Deliverable format
```
## Environments — what each org is for, refresh cadence, who owns it
## Branching & release — branch model, cut points, hotfix path
## Pipeline — jobs in order with the exact sf commands and the gate each one enforces
## Deploy — validate command, quick-deploy command, rollback plan
## Gates — Code Analyzer config, test levels, coverage expectations
## Risks — destructive changes, active flows, profiles, package installs, Sandbox Preview date
```
## Checklist
- [ ] Every change reaches production from git; admin changes are retrieved and reviewed
- [ ] `sfdx-project.json`, `.forceignore` and `sourceApiVersion` deliberate and current
- [ ] Feature environments are disposable; CI creates and deletes its own scratch org
- [ ] Pipeline order is lint → Jest → Code Analyzer → validate → flow tests
- [ ] Production goes through `deploy validate` + `deploy quick`, not a fresh deploy
- [ ] Test level stated per environment; `NoTestRun` never targets production
- [ ] Destructive changes are in a manifest and in the same deploy as the code change
- [ ] Flow activation policy decided; flow coverage understood before an active deploy
- [ ] Rollback plan exists: previous package version or a reverse deploy, rehearsed once
- [ ] The suite runs against a **Sandbox Preview** org before each Salesforce release
## Anti-patterns
- **Change sets** as the release mechanism → source-tracked deploys from git.
- **`sf scanner run` / a standalone PMD plugin** → Code Analyzer v5 with `code-analyzer.yml`.
- **Deploying straight to production with full tests in the window** → validate in CI, quick-deploy in the window.
- **`--test-level NoTestRun` to "get it out"** → fix the tests; `NoTestRun` is for dev environments only.
- **`--ignore-conflicts` as a habit** → it overwrites somebody's org change; look at the conflict.
- **Whole profiles deployed between orgs** → permission sets and permission set groups; the four admin profiles travel as field permissions only.
- **Deleting metadata by hand in production** → destructive changes manifest in the deploy.
- **Long-lived feature branches against a shared sandbox** → short branches, disposable orgs.
- **No Sandbox Preview run** → three times a year the release breaks something nobody tested.
## Go deeper
- `references/pipeline-workflow.md` — a complete CI/CD workflow with validate, quick deploy, delta deploys, artifacts and rollback.
- `references/environments-and-release.md` — scratch org definitions, sandbox strategy and refresh planning, Sandbox Preview, the release checklist and rollback drill.
- `references/code-analyzer-config.md` — `code-analyzer.yml` structure, engines and rule selectors, severity gates, suppressions with an expiry habit.
- Sibling skills: `salesforce-frontend-architecture` for packaging decisions, `apex-testing` and `salesforce-frontend-testing` for the test suites, `salesforce-automation` for flow deployment, `salesforce-security` for the security gates, `salesforce-code-review` for what a reviewer checks, `salesforce-org-conventions` for the org's naming and mandated patterns.