/evergreen-function-circleci

Example repo using CircleCI to test Salesforce Functions

Primary LanguageJavaScriptMIT LicenseMIT

Example of testing Salesforce Functions with CircleCI

Utilize CircleCI & GitHub to enable CI/CD with Salesforce Functions.

Requirements

Setup

πŸ’» These instructions require a command shell such as bash or zsh on Linux or macOS, and may not be compatible with other operating systems.

  1. create a certificate (public/private key pair) for CircleCI auth with Salesforce Dev Hub
  2. create a "CircleCI" Connected App in your Salesforce DevHub
  3. add CircleCI config to your project
  4. create the CircleCI project for the GitHub repo
  5. start building πŸ—

1. Create a certificate

The certificate will be used for cryptographic verification of authentication requests from sfdx on CircleCI. When prompted, set the certificate's common name to β€œCircleCI”. Other fields will be visible in the Salesforce Connected App's details, but can be safely ignored.

In your command shell:

mkdir circleci-jwt-auth/ && cd circleci-jwt-auth/

export PASS="$(openssl rand -hex 20)"
openssl genrsa -aes256 \
  -passout "pass:$PASS" \
  -out connected-app.pass.key \
  4096
openssl rsa -passin "pass:$PASS" \
  -in connected-app.pass.key \
  -out connected-app.key
rm connected-app.pass.key

# This next command will create the certificate identity;
# fill in sensible values, which will appear in the connected app in Salesforce;
# set the Common Name to "CircleCI".
openssl req -new \
  -key connected-app.key \
  -out connected-app.csr

openssl x509 -req -sha256 -days 365 \
  -in connected-app.csr \
  -signkey connected-app.key \
  -out connected-app.crt
base64 connected-app.key > connected-app.key.base64

🀐 The resulting .key & .key.base64 files contain secret data. Maybe you should save them to a secure note, such as in LastPass, but do not commit them to version control.

2. Create a "CircleCI" Connected App

Create a Connected App in the Salesforce Dev Hub that provides authentication for external services based on the new certificate.

In Salesforce Setup β†’ App Manager, create a New Connected App, with the following set:

  • Name CircleCI
  • Contact Email
    • your own org's admin email
  • Enable OAuth Settings check βœ…
  • Callback URL https://localhost:1717/OauthRedirect
    • allows local sfdx CLI to complete auth flow
  • User Digital Signatures check βœ…
    • select the file (created above) circleci-jwt-auth/connected-app.crt.
  • Selected Oauth Scopes required by sfdx CLI:
    • "Manage user data via APIs (api)"
    • "Manage user data via Web browsers (web)"
    • "Perform requests at any time (refresh_token, offline_access)"
  • Save the new app
    • πŸ“ Note the Consumer Key value of the Connected App for use later in CircleCI's SFDX_CONSUMER_KEY environment variable.

Screenshot of new Connected App

Then, Manage the app:

  • Edit Policies β†’ Permitted Users select:
    • "Admin approved users are pre-authorized"
  • Save the app

Then, Manage Profiles:

  • select: "System Administrator"
  • Save the profile assignment

Screenshot of manage Connected App

3. Add CircleCI config

Copy .circleci/config.yml from this repo into your project, commit, & push to GitHub.

4. Create CircleCI project

Visit your CircleCI Projects dashboard to enable this project.

When enabling it, choose use your own existing config.yml and start building immediately. The first build will fail, because we need to setup the Connected App certificate/JWT auth ❌

Configure the CircleCI project to edit its Environment Variables. Set the following JWT auth environment variables:

  • SFDX_CONSUMER_KEY to the Consumer Key display in Salesforce Setup for the Connected App
  • SFDX_JWT_KEY to the contents of circleci-jwt-auth/connected-app.key.base64
    • clipboard copy on macOS: cat circleci-jwt-auth/connected-app.key.base64 | pbcopy
  • SFDX_USERNAME the Salesforce username of a System Administrator (or whatever Profile you assigned to the Connected App).

5. Start Building

To start building, either click re-run in CircleCI web UI, or push new commits to the GitHub repo.

Now, assuming your tests work, the CircleCI job should be successful βœ