Template repository for managing Salesforce metadata with Git and CI/CD.
Supports both GUI-based development (retrieve from org) and AI Agent-driven development (direct metadata editing). Push to sandbox deploys to Sandbox; push to main deploys to Production.
→ Quick Start · Deployment Strategy · Documentation
Salesforce orgs accumulate declarative customizations — flows, objects, permission sets, layouts — built through the GUI with no version history. When something breaks, there's no way to diff, revert, or review what changed. AI Agents can't safely contribute without a validation gate.
Pull all metadata into Git. Let CI validate every change (human or AI) before it reaches an org.
GUI changes → sf retrieve → Git → PR → CI validate → merge → deploy
AI Agent edits → Git directly → PR → CI validate → merge → deploy
Both paths converge on the same force-app/ directory and the same CI pipeline.
The Salesforce CLI is bundled as a devDependency — no global install needed. Run it with pnpm exec sf ... after pnpm install.
mise trust
mise install
pnpm installAuthenticate to your Sandbox:
pnpm exec sf org login web --alias sandbox --instance-url https://your-sandbox.sandbox.my.salesforce.compnpm run retrieveBy default, retrieve.sh pulls metadata based on sfdx-project.json package directories. If your org has many managed packages or you need full-org retrieval with package.xml, note:
.forceignore— Excludes managed package metadata (e.g.,**/pi__*) from retrieve/deploy. Uncomment or add patterns for your installed packages.package.xml— If you create a manifest for wildcard retrieval, ensure commonly missed types are included:ApexTrigger,LightningComponentBundle,AuraDefinitionBundle.
pnpm run validatepnpm run deploy:sandboxProduction deploys happen only through CI/CD when changes are merged to main.
| Branch | Target | Trigger |
|---|---|---|
sandbox |
Sandbox org | Automatic on push |
main |
Production org | Automatic on push |
PRs to either branch run dry-run validation (pnpm exec sf project deploy start --dry-run) in CI.
salesforce-metadata-template/
├── force-app/main/default/ # Salesforce metadata (source format)
│ ├── flows/ # Flow definitions
│ ├── objects/ # Custom objects and fields
│ ├── permissionsets/ # Permission sets
│ ├── layouts/ # Page layouts
│ └── ... # Other metadata categories
├── scripts/
│ └── retrieve.sh # GUI change retrieval helper
├── .github/workflows/
│ ├── ci.yml # PR validation (dry-run deploy)
│ └── deploy.yml # Auto-deploy on push
├── docs/ # Setup documentation
├── sfdx-project.json # Salesforce project config (API v62.0)
├── .mise.toml # sf CLI + Node.js version management
└── package.json # CI tooling (oxlint, oxfmt)
Uses JWT Bearer Flow. See docs/jwt-auth-setup.md for step-by-step setup instructions.
Required GitHub Secrets per environment (sandbox / production):
SF_CLIENT_ID— Connected App consumer keySF_JWT_KEY— Private key (PEM format)SF_USERNAME— Admin usernameSF_INSTANCE_URL— Instance URL
- Org and Repository Model — One repo per Production org, multiple Sandboxes, conflict avoidance
- Authentication Guide — Local vs CI/CD authentication, required permissions
- JWT Authentication Setup — Connected App and GitHub Secrets configuration