Use Development and Application Lifecycle Workflow

As you develop with Salesforce Functions, integrate your function code into your development and application lifecycle workflow. This process can include tasks like:

  • Collaborating on function development with other developers on your team
  • Adding Salesforce Functions to your application lifecycle management process to ensure your functions are properly verified in a sandbox environment before being deployed to production
  • Automating parts of your workflow, such as using automated testing and deployment for your functions

Because Salesforce Functions code is not stored in your org, you must use additional DX tools and commands to integrate Salesforce Functions in your workflow.

Maintain and Share Function Source Code 

Because Salesforce Functions code isn’t saved to your org, save your functions project in a source code control system. You can use git repos on GitHub to save your project code along with the rest of your DX project. After your functions project is in GitHub, you can use git branches, merges, and pull requests to track and safely merge development changes across your team.

To add an existing Salesforce Functions project to GitHub, see Add Project to GitHub.

When making Salesforce Functions project changes, always start by creating a branch in your git repo. Work in this branch as you change your function code, or org-side changes like permission set changes. After you’re ready to test in a scratch or sandbox org, be sure to commit first. After you’ve verified your changes, push your project commit to GitHub, create a pull request for review, and merge your reviewed changes to the main branch of your rep.

Apply Functions and Application Lifecycle Management 

To integrate your Salesforce Functions development and deployment in your application lifecycle management (ALM) process:

  1. Plan your Salesforce Functions development. Understand what compute work your function is doing, what permissions your function needs, and where a user invokes your function from. Determine what language-specific packages beyond the Salesforce SDKs your function needs and include them. Determine which development, test, and integration orgs to create.
  2. Develop your function. Develop and debug functions locally using the Salesforce CLI. Use git and GitHub to track function project changes and coordinate changes across your development team. Develop your Apex code and any org-side changes needed to invoke the function.
  3. Test your function in a development org. Test your function locally and then deploy and test in your development (scratch or sandbox) orgs. Use scratch orgs to test just your changes, or use development sandbox orgs to coordinate testing with others on your team.
  4. Deploy your function to your integration sandbox orgs. Create compute environments based on your preferred set of sandbox orgs used for testing.
  5. Test your function in your integration sandbox orgs.
  6. Release (deploy) your function to your production org.

Here’s a simplified example walkthrough of some of the previous steps for a developer on a team developing with Salesforce Functions. This walkthrough assumes that the development team already has a DevHub org with Salesforce Functions enabled, and each team member has the appropriate DX tools installed.

  1. For initial planning, the team determines that they need a new development sandbox and integration sandbox. The developer creates the sandboxes, either via the Salesforce UI or via CLI commands like the following:
1sf org create sandbox --definition-file config/dev-sandbox-def.json --wait 90 --target-org DevHubOrgAlias --alias Dev_SB # Dev Sandbox
2sf org create sandbox --definition-file config/int-sandbox-def.json --wait 90 --target-org DevHubOrgAlias --alias Int_SB # Integration Sandbox
  1. The developer logs into the Dev Hub and dev and integration sandbox orgs. The developer also authenticates the Salesforce CLI to Salesforce Functions:
1sf org login web --alias DevHubOrgAlias --set-default-dev-hub
2sf org login web --alias Dev_SB --instance-url https://cs45.salesforce.com
3sf org login web --alias Int_SB --instance-url https://cs45.salesforce.com
4sf login functions

The developer creates a project and commits it to git for everyone to work on:

1sf project generate --name BillingProj
2cd BillingProj
3git init
4git add .
5git commit -m "Initial project commit after project creation"
6git remote add github https://github.com/exampleco/billingproj.git

Now, the developer can create a branch and develop function code, Apex code, and any other code required for the project:

1git checkout -b calc-and-send
2sf generate function -n calculateTax -l javascript
3sf generate function -n sendInvoice -l javascript
4cd force-app/main/default/classes
5sf apex generate class --name calculateTax
6sf apex generate class --name sendInvoice

At this point the developer can also run the function locally using a scratch org.

  1. The developer has done some local testing using scratch orgs and wants to test in the development sandbox. They must first ensure they’ve done a git commit for their project:
1git add -A
2git commit -m "Add tax calculation and invoice sending features"

Next they must create a compute environment for their developer sandbox. The compute environment only needs to be created one time and other developers on the team can deploy to the same compute environment:

1sf env create compute -o Dev_SB -a BillingDev_SB

The developer can then deploy the Salesforce Functions project to the compute environment connected to the development sandbox for testing:

1sf deploy functions -o Dev_SB

And finally the developer deploys whatever project-side changes, such as Apex classes, to the development sandbox directly:

1sf project deploy start --target-org Dev_SB

At this point the developer can test the function and org-side changes in the development sandbox.

  1. After testing has been completed, the developer wants to deploy and test in the integration sandbox. First, the developer pushes their git branch to GitHub:
1git push -u github calc-and-send

The developer uses the GitHub web UI to create a pull request and get a review from someone on the team before merging into the integration branch. After the changes are merged, the developer pulls the integration branch to make sure he has all the latest changes for that branch before he deploys:

1git pull github integration

Next the developer creates a compute environment for the integration sandbox that can be used by all developers on the project:

1sf env create compute -o Int_SB -a BillingInt_SB

The developer is ready to deploy his functions to the integration sandbox compute environment, and any project changes to the integration sandbox:

1sf deploy functions -o Int_SB
2sf project deploy start --target-org Int_SB

The developer can now test and validate the functions and org-side changes in the integration sandbox.

After all the testing and validation is complete, a user with production access can deploy this function to a production org:

  1. Clone the GitHub project and switch to the correct branch.
  2. Navigate to the correct branch.
  3. Log in to the production org.
  4. Log in to Salesforce Functions.
  5. Create a compute environment for the production org.
  6. Deploy your function to the compute environment and deploy source files to the production org.
  7. Invoke your function as needed by your workflow.

See Deploy a Function for details.

Add Continuous Integration/Continuous Deployment Authorization With JWT 

Use JavaScript web token authorization (JWT) to set up your Salesforce Functions code to run on a Continuous Integration/Continuous Deployment (CI/CD) service. Use this process to authenticate your testing and production flow with Salesforce Functions.

Enable Functions For Production 

If you haven’t done so already, enable Salesforce Functions in your production org. In Setup, search for Functions and toggle on Enable Production Space. Enabling Salesforce Functions allows the CI/CD service to deploy your functions code. For more information, see Configure Orgs for Functions.

Create Private Key and Certificate 

If you don’t have one already, use OpenSSL to create a private key and a self-signed certificate to use with a Connected App. The key and certificate allows your CI/CD tool to authenticate with Salesforce CLI and Salesforce Functions. Run the following commands in the root of your Salesforce Functions project:

1mkdir jwt-auth && cd jwt-auth
2
3# create key
4export PASS="$(openssl rand -hex 20)"
5openssl genrsa -aes256 \
6  -passout "pass:$PASS" \
7  -out connected-app.pass.key \
8  4096
9openssl rsa -passin "pass:$PASS" \
10  -in connected-app.pass.key \
11  -out connected-app.key
12rm connected-app.pass.key
13
14# use key to create certificate
15# fill in values when prompted and set name to CI
16openssl req -new \
17  -key connected-app.key \
18  -out connected-app.csr
19
20openssl x509 -req -sha256 -days 365 \
21  -in connected-app.csr \
22  -signkey connected-app.key
23  -out connected-app.crt
24base64 connected-app.key > connected-app.key.base64

This process creates two files: connected-app.key and connected-app.key.base64. These files contain secret information that you must use to set up your CI/CD tool. Don’t commit these files or push them to GitHub.

Create a Connected App 

Create a Connected App and use your key and certificate to authorize the app for use with your CI/CD tool.

In your production org’s Dev Hub, click Setup and search for App Manager. Click New Connected App and fill in the following values:

  • Name: CI
  • Contact Email: the org admin’s email
  • Enable OAuth Settings: yes
  • Callback URL: https://localhost:1717/OauthRedirect
  • Use Digital Signatures: yes; select jwt-auth/connected-app.crt created in the previous step
  • Selected OAuth Scopes:
    • Manage user data via APIs (api)
    • Manage user data via Web browsers (web)
    • Perform requests at any time (refresh_token, offline_access)
  • Save the app

After you create the app, click Edit Policies and then Permitted Users. Select “Admin approved users are pre-authorized” and save the app.

Finally, in the Profiles section of the page, click Manage Profiles. Select “System Administrator” and save the profile assignment.

Note the Consumer Key in the Connected App as you use it when you set up your CI/CD service.

Set Up Your CI/CD Service 

When you set up a CI/CD project to run your Salesforce Functions code, set environment variables and configure the tool.

Create Environment Variables 

Use the information from previous steps to set the following environment variables:

  • SFDX_CONSUMER_KEY: the Consumer Key displayed in your Connected App
  • SFDX_JWT_KEY: the contents of jwt-auth/connected-app.key
  • SFDX_USERNAME: the Salesforce username of a System Administrator

Set Up Functions Project in CI/CD 

In your CI/CD tool, set up a project to run your Salesforce Functions code. This process matches your existing CI/CD configuration for any other Salesforce app, except for authenticating your CLI. To authenticate in your CI/CD app, use sf login functions jwt to log in to both Salesforce CLI and Salesforce Functions with one command:

1sf login functions jwt -u user@example.com \
2  -f jwt-auth/connected-app.key \
3  -i ######

Run CI/CD With Every Code Commit 

After running through the setup steps above, every commit to the main branch of your GitHub project will trigger CI/CD to automatically run your functions project.

For an example project that uses CircleCI and GitHub to automate testing of a function, see this CircleCI and Salesforce Functions example.

For more information on continuous integration, see Continuous Integration in the Salesforce DX Developer Guide.

Product Retirement Announcement

Salesforce Functions is no longer available for purchase or renewal. To preserve the capabilities that Salesforce Functions provided to your org, deploy an alternative solution before your existing order term ends. See Salesforce Functions Retirement for more information on migrating your functions. Contact your Salesforce Account Executive for more information on Heroku.