Change Sets served a generation of Salesforce teams. They also gave us deployment windows that ran past midnight, production hotfixes that nobody could trace back to a commit, and the kind of "it worked in sandbox" mystery that still haunts release managers. A proper Salesforce CI/CD pipeline replaces all of that with something repeatable: every change tracked in version control, every deployment triggered by a merge, every test suite run automatically before anything touches production. This guide walks through how to build a pipeline that actually holds up as your team and codebase grow.
Why Change Sets Cannot Scale
Change Sets have three fundamental problems that accumulate as orgs mature. First, they are not tracked in version control — there is no way to look at a Change Set and know exactly what metadata was in it at the point of deployment, who approved it, or whether it has ever been deployed before. Second, they require manual dependency management: the developer building the Change Set must manually identify and include every metadata dependency, and missing one breaks the deployment in production. Third, they cannot be automated — Change Sets require manual clicks in the Salesforce UI, which means every deployment is a manual activity that cannot be integrated into a broader release pipeline.
The consequence of all three problems together is that Change Set-based teams cannot release with confidence. Every deployment carries uncertainty because the state of the Change Set depends on what the developer remembered to include, and validation against production is the only way to find out if they got it right. Teams typically respond to this uncertainty by bundling more changes into fewer, larger deployments — which creates bigger blast radius when something goes wrong, longer deployment windows, and more complex rollback scenarios.
The Four Stages of a Salesforce CI/CD Pipeline
A well-designed Salesforce CI/CD pipeline follows a consistent four-stage structure regardless of the specific tools used to implement it.
Stage 1 — Source Control (Developer Sandbox → Git)
Every change begins in a developer sandbox and is pulled into a feature branch in Git using the Salesforce CLI. The command sf project retrieve start pulls changes from the sandbox into the local project directory, where they are committed and pushed to the remote repository. This is the transition from org-based development — where the org is the source of truth — to source-driven development, where Git is.
Source-driven development is the prerequisite for everything else in a CI/CD pipeline. If your metadata is not in version control, your pipeline has nothing to work with. The first time a team adopts this model, there is typically a migration effort to bring all existing metadata out of production and into a Git repository — this is called the initial metadata retrieve, and it is worth doing properly rather than rushing, because an incomplete initial retrieve becomes a persistent gap in your pipeline's reliability.
Stage 2 — Automated Validation (Feature Branch → CI Environment)
When a developer pushes a feature branch, the CI platform (GitHub Actions, GitLab CI, or similar) triggers an automated validation run against a designated CI target org. The validation uses sf project deploy validate, which runs all specified Apex tests and checks metadata validity without committing any changes. If validation fails — a test fails, a metadata dependency is missing, a syntax error is present — the developer is notified immediately and the failure is visible in the pull request.
The CI target org for validation should be a Developer Pro sandbox dedicated to this purpose. It needs to have current metadata (it should be refreshed from production or your main branch on a regular schedule) and enough data for your test suite to run meaningful assertions. Keeping this environment stable and representative is one of the ongoing maintenance tasks of a CI/CD pipeline.
Stage 3 — Integration and QA Deployment (Main Branch → Integration Sandbox)
When a pull request is merged into the main branch, the pipeline deploys the changes to an integration sandbox — a shared environment where all merged features are combined and tested together. This is the first time features built by different developers on different branches come together, which means this is where integration conflicts surface. A dedicated integration sandbox with automated post-deployment tests (ideally running your full test suite) makes this conflict visible hours after the merge, not days later when someone manually tests in QA.
Stage 4 — Production Deployment (Release Tag → Production)
Production deployments are triggered by a release tag or a merge to a release branch, not by an automatic trigger on every merge to main. Before production deployment, the pipeline runs a full validation against production — including all Apex tests — using a quick deploy if validation passes (which allows Salesforce to skip re-running tests if they passed within the previous 10 days). The deployment itself is audited automatically: the commit hash, the deploying user, the timestamp, and the deployment result are all logged.
Salesforce deployments that run themselves
DeployEzee gives mid-market Salesforce teams a fully managed deployment pipeline — automated validation, environment management, and deployment history — without building and maintaining pipeline YAML from scratch.
See DeployEzee →Branch Strategy for Salesforce Teams
A Salesforce CI/CD pipeline needs a branch strategy that maps to your environment hierarchy. The most common pattern for mid-sized teams is a three-branch model:
| Branch | Environment | Who Deploys | Trigger |
|---|---|---|---|
| feature/* | Developer sandboxes | Developers | Manual or on push (validation only) |
| main | Integration sandbox | CI pipeline | Merge from feature branch |
| release/* | Full sandbox → Production | CI pipeline (gated) | Release tag or manual trigger |
The gating on release deployments is important. Production deployments should require explicit human approval — typically a pull request review or a manual trigger in the CI platform — even if all automated checks pass. This is not about distrust in the pipeline; it is about maintaining a human decision point for changes that affect live users.
Handling Metadata That Cannot Be Source-Tracked
Not all Salesforce metadata supports source tracking. Standard value sets, some platform encryption settings, and certain managed package configurations cannot be retrieved through the Salesforce CLI. These metadata types require special handling in your pipeline — typically maintained as static metadata files in your repository that are deployed manually when they change, with change notes recorded in your release log rather than in automated pipeline history.
The existence of non-trackable metadata is not a reason to avoid source-driven development — it is a reason to document clearly which parts of your org are tracked and which are not. Most orgs have a relatively small set of non-trackable metadata that changes infrequently, making manual management workable alongside an otherwise automated pipeline.
Frequently Asked Questions
What tools are used in a Salesforce CI/CD pipeline?
The core toolchain consists of Git for version control, the Salesforce CLI for metadata operations, a CI platform (GitHub Actions, GitLab CI, Jenkins) for pipeline orchestration, and optionally a dedicated Salesforce release management tool. Most teams start with Salesforce CLI plus GitHub Actions and add dedicated tooling as complexity grows.
What is the difference between a validation and a deployment in Salesforce CI/CD?
A validation runs Apex tests and verifies metadata validity without committing changes to the org. A deployment commits the metadata changes to the target environment. Feature branch pushes trigger validations. Production deployments require the validation to pass and an explicit human approval gate before the commit runs.
How do you handle Salesforce metadata dependencies in a CI/CD pipeline?
The best defence is source-driven development where your entire org's metadata lives in version control and deployments are calculated diffs rather than hand-crafted packages. Tools like the Salesforce CLI's source tracking and purpose-built deployment tools handle dependency resolution automatically, eliminating the manual dependency hunting that makes Change Sets unreliable.
Should you run all Apex tests on every pipeline run?
A practical compromise is to run relevant tests on feature branch validations and the full test suite on merge to main and before production deployments. Running all tests on every pipeline run is safest but can be prohibitively slow — a full test suite in a mature org can take 30 to 90 minutes.
What is source-driven development in Salesforce and why does it matter for CI/CD?
Source-driven development means your Git repository is the source of truth for your org's metadata — every change is tracked in version control and deployed through an automated pipeline. Without it, your pipeline is building on top of org state that may not match what is in Git, making deployments unreliable.