Continuous Integration for Salesforce
How to set up CircleCI for a Salesforce project using a single sandbox for running automated tests.
Set Up Git Repo
Create a Key and Certificate for JWT Authentication
$ mkdir lib
$ openssl genrsa -out lib/ci.key 2048
$ openssl req -new -key lib/ci.key -out lib/ci.csr
$ openssl x509 -req -sha256 -days 3650 -in lib/ci.csr -signkey lib/ci.key -out lib/ci.crt
$ openssl aes-256-cbc -in lib/ci.key -out lib/ci.key.enc -md sha256 -k <pass phrase>
Commit lib/ci.key.enc
to git
Create .circleci/config.yml
and commit to git
version: 2
jobs:
build:
parallelism: 1
shell: /bin/bash --login
docker:
- image: circleci/node:8.6
working_directory: ~/ci
steps:
- checkout
- run:
name: Decrypt Key
command: openssl aes-256-cbc -d -in lib/ci.key.enc -out lib/ci.key -md sha256 -k "$JWT_KEY"
- run: mkdir ~/bin
- run:
name: Get Latest Force CLI Release
command: curl --output ~/bin/force https://force-cli.heroku.com/releases/v0.24.3/linux-amd64/force
- run: chmod +x ~/bin/force
- run: force login -i test -u "$SF_USER" -key lib/ci.key --connected-app-client-id "$CLIENT_ID"
- run:
name: Run Salesforce Tests
command: force import -d src -c -l RunLocalTests -i
Configure Production Org
If possible, create a CI user (e.g. ci@example.com) in the production org, then deactivate the user
Creating the user in the production org allows you to avoid having to create it in the CI org (or orgs, if you later scale to multiple CI orgs) when the sandbox is created or refreshed.
Create a CI sandbox named ci0
Create a Connected App in the production org with settings:
- Enable OAuth Settings
- Callback URL:
http://localhost:3835/oauth/callback
- Use Digital Signatures
- Upload
ci.crt
, created above
- Upload
- Selected OAuth Scopes
Access and manage your data (api)
Perform requests on your behalf at any time (refresh_token, offline_access)
Configure CircleCI
Enable Project
Set up Circle CI for project at https://circleci.com/add-projects/gh/octoberswimmer
Set Environment Variables
- Set
SF_USER
to user created in CI org, e.g.ci@example.com.ci0
- Set
CLIENT_ID
to the Consumer Key for the Continuous Integration Connected App created - Set
JWT_KEY
to the pass phrase used to encrypt the ci.key file above usingopenssl aes-256-cbc
Configure Circle CI to build forked pull requests under Advanced Settings
Enable JWT Authentication
Activate (if created in the production org) or create the CI user in the CI sandbox, e.g. ci@example.com.ci0
Log in as the CI user using the Connected App
After authorizing the Connected App for the CI user, it will be possible to authenticate using the secret key.
$ force login -i test -connected-app-client-id <Consumer Key>
Test JWT Authentication
$ force login -i test -connected-app-client-id <Consumer Key> -u <ci@example.com.ci0> -key lib/ci.key