sf-devops-ci-cd
Skill15 starsChanged 7 months agoMITView on GitHub
Use when setting up Salesforce CI/CD pipelines. GitHub Actions, JWT auth, scratch org workflows, sandbox promotion, and deployment automation.
- Reads credentials
- Installs packages
In this repository58 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- asideSkill
- checkpointSkill
- configure-sccSkill
- continuous-agent-loopSkill
- mcp-server-patternsSkill
- model-routeSkill
- prompt-optimizerSkill
- refactor-cleanSkill
- resume-sessionSkill
- save-sessionSkill
- search-firstSkill
- security-scanSkill
- sessionsSkill
- sf-2gp-security-reviewSkill
- sf-agentforce-developmentSkill
- sf-agentforce-mcp-actionsSkill
- sf-apex-async-patternsSkill
- sf-apex-best-practicesSkill
- sf-apex-constraintsSkill
- sf-apex-cursorSkill
- sf-apex-enterprise-patternsSkill
- sf-apex-testingSkill
- sf-api-designSkill
- sf-approval-processesSkill
- sf-aura-developmentSkill
- sf-build-fixSkill
- sf-cli-referenceSkill
- sf-data-modelingSkill
- sf-debuggingSkill
- sf-deployment-constraintsSkill
- sf-deploymentSkill
- sf-docs-lookupSkill
- sf-e2e-testingSkill
- sf-experience-cloudSkill
- sf-flow-developmentSkill
- sf-governor-limitsSkill
- sf-harness-auditSkill
- sf-helpSkill
- sf-integrationSkill
- sf-lwc-constraintsSkill
- sf-lwc-developmentSkill
- sf-lwc-testingSkill
- sf-metadata-managementSkill
- sf-platform-events-cdcSkill
- sf-quickstartSkill
- sf-security-constraintsSkill
- sf-securitySkill
- sf-soql-constraintsSkill
- sf-soql-optimizationSkill
- sf-tdd-workflowSkill
- sf-testing-constraintsSkill
- sf-trigger-constraintsSkill
- sf-trigger-frameworksSkill
- sf-visualforce-developmentSkill
- strategic-compactSkill
- update-docsSkill
- update-platform-docsSkill
The file
Files
Salesforce DevOps and CI/CD
Reference: @../_reference/DEPLOYMENT_CHECKLIST.md, @../_reference/DOCKER_CI_PATTERNS.md
When to Use
- Setting up GitHub Actions CI/CD pipelines for Salesforce projects
- Configuring JWT authentication for non-interactive CI/CD deployments
- Implementing scratch-org-per-branch development workflows
- Automating deployments across sandbox, staging, and production environments
- Troubleshooting SF CLI v2 deploy, retrieve, or test commands
SF CLI v2 Key Commands Reference
Org Management
sf org login web --alias myOrg # Browser-based login
sf org login jwt --client-id <id> --jwt-key-file server.key --username user@org.com --alias ci-org
sf org list # List all authenticated orgs
sf org open --target-org myOrg # Open org in browser
sf org create scratch --definition-file config/project-scratch-def.json --alias myScratch --duration-days 7
sf org delete scratch --target-org myScratch --no-prompt
sf org display --target-org myOrg # Show org details including access tokenSource Deploy and Retrieve
sf project deploy start --source-dir force-app --target-org myOrg
sf project deploy start --manifest manifest/package.xml --target-org myOrg
sf project deploy validate --manifest manifest/package.xml --target-org myOrg
sf project deploy quick --job-id <id> --target-org myOrg
sf project retrieve start --source-dir force-app --target-org myOrg
sf project deploy start --source-dir force-app --test-level RunLocalTests --target-org myOrgApex Execution and Testing
sf apex run --file scripts/apex/setup.apex --target-org myOrg
sf apex run test --test-level RunLocalTests --result-format human --target-org myOrg
sf apex run test --class-names AccountServiceTest --result-format json --target-org myOrg
sf apex run test --test-level RunAllTestsInOrg --code-coverage --result-format json --output-dir results/
sf apex tail log --target-org myOrg # Stream live debug logsJWT Authentication Setup
JWT auth enables non-interactive CI/CD authentication without browser prompts.
Step 1: Create Connected App in Salesforce
- Setup > App Manager > New Connected App
- Enable OAuth Settings
- Callback URL:
http://localhost:1717/OauthRedirect - Selected OAuth Scopes:
api,refresh_token,offline_access - Enable "Use digital signatures"
- Upload your certificate (.crt file)
- Manage > Edit Policies > IP Relaxation: Relax IP restrictions
- Note the Consumer Key (Client ID)
Step 2: Generate Certificate and Private Key
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr
openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt
base64 -i server.key | tr -d '\n' # Encode for GitHub Secrets storageStep 3: Configure GitHub Secrets
SALESFORCE_JWT_SECRET_KEY-- base64-encoded server.key contentSALESFORCE_CONSUMER_KEY-- Connected App Consumer KeySALESFORCE_USERNAME-- target org username
Complete GitHub Actions CI/CD Workflow
# .github/workflows/ci.yml
name: Salesforce CI/CD
on:
push:
branches: [develop, staging, main]
pull_request:
branches: [develop, staging, main]
jobs:
validate-pr:
name: Validate Pull Request
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install SF CLI
run: npm install -g @salesforce/cli
- name: Authenticate to sandbox
env:
JWT_SECRET_KEY: ${{ secrets.SALESFORCE_JWT_SECRET_KEY }}
CONSUMER_KEY: ${{ secrets.SALESFORCE_CONSUMER_KEY }}
USERNAME: ${{ secrets.SALESFORCE_USERNAME_SANDBOX }}
run: |
echo "$JWT_SECRET_KEY" | base64 --decode > server.key
sf org login jwt \
--client-id "$CONSUMER_KEY" \
--jwt-key-file server.key \
--username "$USERNAME" \
--alias validation-org \
--set-default
rm server.key
- name: Validate deployment
run: |
sf project deploy validate \
--source-dir force-app \
--test-level RunLocalTests \
--target-org validation-org \
--wait 30
deploy-production:
name: Deploy to Production
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
environment: production
steps:
- uses: actions/checkout@v4
- name: Install SF CLI
run: npm install -g @salesforce/cli
- name: Authenticate to Production
env:
JWT_SECRET_KEY: ${{ secrets.SALESFORCE_PROD_JWT_SECRET_KEY }}
CONSUMER_KEY: ${{ secrets.SALESFORCE_PROD_CONSUMER_KEY }}
USERNAME: ${{ secrets.SALESFORCE_PROD_USERNAME }}
run: |
echo "$JWT_SECRET_KEY" | base64 --decode > server.key
sf org login jwt \
--client-id "$CONSUMER_KEY" \
--jwt-key-file server.key \
--username "$USERNAME" \
--instance-url https://login.salesforce.com \
--alias prod \
--set-default
rm server.key
- name: Validate deployment
id: validate
run: |
VALIDATION_RESULT=$(sf project deploy validate \
--source-dir force-app \
--test-level RunLocalTests \
--target-org prod \
--wait 60 \
--json)
echo "VALIDATION_JOB_ID=$(echo "$VALIDATION_RESULT" | jq -r '.result.id')" >> "$GITHUB_ENV"
- name: Quick deploy
run: |
sf project deploy quick \
--job-id "$VALIDATION_JOB_ID" \
--target-org prod \
--wait 10Do not use
--use-most-recentfor quick deploy in multi-team orgs. Another team's deployment between validate and quick-deploy invalidates the job. Always pass--job-idexplicitly.
Branch Strategy
feature/ABC-123-account-service
|
v
develop ---- CI: validate + deploy to dev sandbox
|
v
staging ---- CI: validate + deploy to staging sandbox (RunLocalTests)
|
v
main ---- CI: deploy to production (RunLocalTests)feature/*-- individual work, scratch org per developerdevelop-- integration branch, auto-deploys to dev sandboxstaging-- pre-production, mirrors production as closely as possiblemain-- production. Requires pull request review + CI green
Scratch Org Per-Branch Workflow (CI)
test-in-scratch-org:
name: Test in Scratch Org
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/heads/feature/')
steps:
- uses: actions/checkout@v4
- name: Install SF CLI and authenticate Dev Hub
env:
JWT_SECRET_KEY: ${{ secrets.DEVHUB_JWT_SECRET_KEY }}
CONSUMER_KEY: ${{ secrets.DEVHUB_CONSUMER_KEY }}
USERNAME: ${{ secrets.DEVHUB_USERNAME }}
run: |
npm install -g @salesforce/cli
echo "$JWT_SECRET_KEY" | base64 --decode > server.key
sf org login jwt \
--client-id "$CONSUMER_KEY" \
--jwt-key-file server.key \
--username "$USERNAME" \
--alias devhub \
--set-default-dev-hub
rm server.key
- name: Create scratch org
run: |
sf org create scratch \
--definition-file config/project-scratch-def.json \
--alias ci-scratch \
--set-default \
--duration-days 1 \
--no-ancestors
- name: Push source and run tests
run: |
sf project deploy start --source-dir force-app --target-org ci-scratch
sf apex run test \
--test-level RunLocalTests \
--result-format human \
--code-coverage \
--target-org ci-scratch
- name: Delete scratch org
if: always()
run: sf org delete scratch --target-org ci-scratch --no-promptDeployment Test Level Strategy
| Environment | Test Level | Rationale |
| Feature CI | RunLocalTests | Fast feedback, catches regressions |
| Dev Sandbox | RunLocalTests | Full local test suite |
| Staging | RunLocalTests | Near-production confidence |
| Production | RunLocalTests | Required by Salesforce (75% min) |
| Full release | RunAllTestsInOrg | Complete org-wide regression |
Change Detection: Deploy Only Changed Metadata
#!/bin/bash
# scripts/get-changed-metadata.sh
BASE_BRANCH=${1:-main}
CHANGED_FILES=$(git diff --name-only origin/$BASE_BRANCH...HEAD)
SF_CHANGED=$(echo "$CHANGED_FILES" | grep "^force-app/")
if [ -z "$SF_CHANGED" ]; then
echo "No Salesforce metadata changes detected"
exit 0
fi
# Use sfdx-git-delta plugin
# Verify command syntax with: sf sgd --help
sf sgd:source:delta \
--to HEAD \
--from origin/$BASE_BRANCH \
--output-dir changed-sources \
--generate-delta
# Deploy only changed sources
TEST_CLASSES=$(cat changed-sources/test-classes.txt 2>/dev/null | tr '\n' ',' | sed 's/,$//')
if [ -n "$TEST_CLASSES" ]; then
sf project deploy start \
--source-dir changed-sources/force-app \
--test-level RunSpecifiedTests \
--tests "$TEST_CLASSES" \
--target-org $TARGET_ORG
else
sf project deploy start \
--source-dir changed-sources/force-app \
--test-level RunLocalTests \
--target-org $TARGET_ORG
fiInstall sfdx-git-delta plugin:
sf plugins install sfdx-git-deltaRelated
- Constraints:
sf-deployment-constraints-- deployment safety rules
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

