A ready-made release system for Salesforce teams. Each release deploys only what changed and runs the Apex tests. If the deploy or the tests fail, it rolls back to a backup taken just before the release. It comes as templates for five CI platforms (the services that run each release), and it keeps every org login out of the code, stored as a secret. Two VSCode extensions sit on top. Pipeline Manager sets the pipeline up once per project, and Developer Tools handles day-to-day development.
Every push starts the pipeline, and a settings file, ci-config.json, decides what happens next. A feature branch gets a check-only deploy of the whole package to the Dev org. Salesforce confirms the package would deploy without saving anything, so each pull request is known to deploy before it merges. An environment branch runs every step: sign in, work out what changed, back up the org, deploy the change and tag it, run the tests, and roll back if anything fails.
flowchart TD
A["Git Push"] --> B["Read ci-config.json"]
B --> C{"Branch type?"}
C -->|"feature/*"| D["feature/* branch"]
D --> F["Validate the full package
against Dev (check-only)"]
F --> H["PR into dev"]
C -->|"env branch"| E["env branch
(dev / sit / qa / uat / staging / main)"]
E --> I["Authenticate org
(SFDX auth URL)"]
I --> J["sfdx-git-delta
detect changed metadata"]
J --> K["Generate destructiveChanges.xml
for deletions"]
K --> Q["sf project retrieve start
back up the org"]
Q --> L["sf project deploy start
deploy the delta"]
L --> O["Tag deployed/#lt;env#gt;"]
O --> M["sf apex run test
run local tests"]
M --> N{"Passed?"}
N -->|"Yes"| Z["Release done"]
N -->|"No"| P["scripts/rollback.sh
redeploy the backup"]
L -->|"deploy fails"| P
%% Blueprint tokens as literal hex (Mermaid cannot parse CSS vars or color-mix)
classDef trigger fill:#e0be621f,stroke:#e0be62,stroke-width:1.5px;
classDef ci fill:#8b93e81f,stroke:#8b93e8,stroke-width:1.5px;
classDef sf fill:#62d99a1f,stroke:#62d99a,stroke-width:1.5px;
classDef decision fill:#e0be621f,stroke:#e0be62,stroke-width:1.5px;
classDef ok fill:#62d99a1f,stroke:#62d99a,stroke-width:1.5px;
classDef fail fill:#e697521f,stroke:#e69752,stroke-width:1.5px;
class A trigger;
class C,N decision;
class B,D,E,F,H ci;
class I,J,K,Q,L,O,M sf;
class Z ok;
class P fail;
Map any branch pattern to any org. By default, feature/* branches are validated, and named branches (dev, sit, qa, uat, staging, main) move each release through the environments in order.
With no deployed/<env> tag yet, the first run deploys what changed in the latest commit. To start from the current commit, run Initialise Deploy Tag in Developer Tools and push the tag. Only a repository with a single commit gets a full deploy from package.xml.
Each release ships only what changed. sfdx-git-delta compares the latest commit with the last deploy to work out exactly what changed, including anything deleted, and deleted items are removed from Salesforce as well. A commit that only changes documents deploys nothing.
A one-file change deploys one file. There is no full deploy on every push, so releases stay quick as the org grows.
Each deploy touches only the components that changed, so there are fewer side effects elsewhere in the org.
Anything deleted from the project is removed from Salesforce too. sfdx-git-delta writes the destructiveChanges.xml file for it, so nobody keeps a list of deletions by hand.
The release steps are the same on every platform. Each template only handles that platform's differences: how it fetches the full Git history, what it calls the branch, how it passes in secrets, and how it publishes test results.
fetch-depth: 0 for full history. Secrets via secrets.<NAME>. Test artifacts via upload-artifact.
Full clone via fetchDepth: '0'. Auth URLs injected via env block. Results via PublishTestResults.
GIT_DEPTH: 0 for history. Base image node:20. JUnit via artifacts:reports:junit.
GitSCM checkout with shallow: false. Credentials via credentials(). Results via junit post step.
clone: depth: full. Base image node:20. Developer Tools can switch Pipelines on through the Bitbucket API.
Before each deploy, the pipeline backs up the org's current metadata with sf project retrieve. If the deploy or the tests fail, scripts/rollback.sh deploys that backup to the org before the pipeline ends. The backup covers nine common metadata types, listed below, and anything new that the release added stays in the org.
After each deploy, if tests are switched on (the default), scripts/run-tests.sh runs the org's own Apex tests (skipping those from installed packages) with sf apex run test. The results are published as JUnit reports, and any failure triggers the rollback.
Each org's login, an SFDX auth URL, is stored as a secret in the CI platform and never in the code. There is one secret per org, named <ORGALIAS_UPPER>_AUTH_URL. Pipeline Manager lists exactly which secrets to add.
| Secret name | Purpose |
|---|---|
| DEV_AUTH_URL | Dev environment, feature validation target |
| SIT_AUTH_URL | SIT environment |
| QA_AUTH_URL | QA environment |
| UAT_AUTH_URL | UAT environment |
| STAGING_AUTH_URL | Staging environment |
| PROD_AUTH_URL | Production |
ci-config.json holds every pipeline setting: which branch deploys to which org, the deploy options and the test settings. The setup wizard writes it, VSCode checks it against a JSON schema while you edit it, and the pipeline reads it on every run.
Pipeline Manager's setup wizard writes all of these files, with one pipeline file for the CI platform you chose. Before the first run, trim package.xml to the metadata types your project uses, as its own comments ask.
Pipeline Manager is for setup. A wizard creates the pipeline once, and a panel keeps track of it. Developer Tools is for every day: deploy, validate, test and manage orgs without leaving the editor.
Run once per project. A four-step wizard writes the pipeline files for your CI platform and tells you exactly which secrets to add. Afterwards, a panel in the editor shows the current settings.
For every day. Deploy the open file or everything committed since the last release, validate without saving, run Apex tests, switch orgs, refresh the pipeline's org logins, and export a Confluence space to Markdown, all from the editor.