Baby Steps in Continuous Delivery for Salesforce
Taking on the DevOps boss in 9 levels
Of all the elements that every Salesforce project contains, the most underrated one has to be the deployment process. Sure, getting the work done in a timely and accurate way is the ultimate goal, but if you can’t get it into production, who cares?
After spending a Sunday evening fixing a P1 bug and looking at one too many deployment fish, I decided enough was enough. What could I do to guarantee that any push to production was simple and error-free? Down the internet rabbit hole I went, deep into the world of DevOps.
Turns out I was late to the party — Continuous Delivery was the solution I was looking for, and Salesforce DX was built upon its tenets. With “agile” in mind, I set about on the journey, one step after the other.
Continuous Delivery is an approach where teams release quality products frequently and predictably from source code repository to production in an automated fashion.
Level 1: The source of truth
It goes without saying that the most important aspect of any deployment is what exactly is being deployed. Change Sets do this well — All components are listed in one view that can be paged through 200 rows at a time. But what if one of those components or one of its dependents is currently being worked on by someone else? What about when you’re actually ready to deploy only to be told “Change Set Unavailable”? Also, wouldn’t it be nice to see the entire “who-when-what” history of, say, a page layout?
That’s where source control comes in. Just like any of the safe & versionable document storage systems we’re all used to (SharePoint, Dropbox), all the work done on any Salesforce org should be immediately available and up-to-date with the customizations and code that other folks are working on.
To start off, let’s grab everything from an org and save it (also known as “retrieve” or “pull down”). Logically, there are only 3 steps involved, and each corresponds to one command in either the Salesforce CLI or Git¹:
Level 2: What comes down must go up
What’s the opposite of retrieving/pulling? Deploying/pushing! Given that the source has everything that needs to be deployed from step 3 above, only two steps are needed here:
Level 3: The party pooper
Now that you’ve drastically simplified the process of retrieving & deploying Salesforce customizations & code, everyone is happy and everything is working in perfect harmony!
Except for that one time.
In an effort to delight the business first thing Monday morning, Jake² spent all Sunday on a new flow that automatically updates a Contact’s address from its Account. He ran a few tests right around midnight and everything looked good, so he used the brand new process to get it to production in no time at all! Having worked overtime, he decided to set his alarm a little later than usual, and looked forward to a standing ovation when he strolled into work the next morning.
Fast-forward a few hours, and Jake’s supervisor Brianna has 10 urgent emails from the business about users not being able to edit Contacts in Salesforce, and no idea what happened other than Jake’s name being at the top of the Setup Audit Trail. Sound familiar?
Whether it’s a point-and-click configuration or a line of code, anyone’s work should always be checked by someone else. To this extent, nearly all source control tools include the concept of a code review in order to have others validate what is being saved.
Using Bitbucket as an example, Brianna can prevent any more blunders by requiring Jake to create a pull request any time he wants to change something in the source. From this request, she can easily see what Jake changed and leave comments directly on the component or line that may look wrong. Once the back and forth is complete and Brianna leaves her “LGTM”, only then can Jake deploy his work to production.
Level 4: A requirement appears!
In addition to the CLI referenced above, the ability to quickly spin up an environment for any purpose was a significant new feature delivered with Salesforce DX. Instead of having to create a new sandbox from production or go through the Developer org signup form, a scratch org can be setup with test data and users in 3 steps:
- Create the environment:
- Import test data:
- Create user(s):
With this new org, admins and developers alike can then use the steps from Levels 1 and 2 above to deploy and retrieve their work on request. Because of the simplicity of this process, they can also spin up new environments to isolate each and every bug to fix or feature request.
Level 5: Keeping in touch
As the number of orgs grows and grows, so too does the need to make sure everyone is working on the latest and greatest version of what has been built so far. Although this can be as easy as ringing a bell to let others know when a change was made, technically this problem was already partially solved by Level 2 above — All that needs to be done here is automating it.
The key challenge then can be rephrased as follows: How can a change to the source trigger a set of commands to be run in a specific Salesforce org? Thankfully a number of tools exist that take care of the heavy lifting, and we’ll use Bitbucket Pipelines as an example to boil it down to 4 steps:
- Create a Pipeline that includes the Salesforce CLI
- Add the commands from Level 2 (login + deploy)
- Configure the username & Connected App parameters that enable the Pipeline to automatically login to the target org
- Test it out!
While this level is likely the most technically challenging, it’s also one of the best documented, with step-by-step instructions for many leading tools including Bitbucket, Travis CI, Jenkins, and Circle CI.
Level 6: Trust the process
With your first Pipeline now setup, the question is no longer “how” but “what”. In essence, all of the previous levels can be automated in order to create a streamlined end-to-end development process:
- In one click, admins and devs spin up a scratch org pre-loaded with test data and any ongoing work or historical change
- After their changes are complete, they are versioned and peer reviewed
- Once reviewed, the changes are automatically pushed to any org
Looking back on the promise of Continuous Delivery, we’ve therefore achieved the following:
- More dependable releases — Deployments to production can be tested and validated in as many orgs as needed
- More frequent releases — Changes can be deployed on demand and/or automatically
- Less busy work — Time is no longer spent on preparing and setting up deployments
Levels 7, 8, 9: Quality over quantity
For all the hours and emails saved by setting up code reviews (Level 3), sometimes there are things that mere mortals like Brianna and Jake may miss or simply cannot anticipate. Sure, a thorough QA check of all user workflows wouldn’t let anything slip by, but at what cost?
The key to this challenge is automated testing which consists of code that can be run on demand, both in the UI and against backend services, to validate that the work being done meets quality standards and does not break existing integrations and user workflows.
Here again, a number of tools (such as Selenium) exist to help build these checks, but it’s important to note that they must reach beyond Apex and Lightning tests, which are not geared towards point-and-click configurations. Nevertheless, even with just a subset of your source covered, the final 3 levels are then within reach:
7. Continuous Integration: Run automated tests in one sandbox (commonly called “System Integration Testing”, or “SIT” for short) at least daily
8. Continuous Integration II (sometimes also called “Continuous Delivery”): Automate tests and deployments to all sandboxes
9. Continuous Deployment: Automate tests and deployments in all sandboxes + production
With the Salesforce CLI here to stay and new features being added weekly, consider adding it to the New Year’s resolutions for your org — Those deployment fish will do just fine without you!
^¹ The commands listed are tailored to non-scratch orgs, such as sandboxes or developer orgs, and are slightly simplified for clarity. For complete details, check out this foolproof step-by-step guide and the following Trailhead modules on setting up the Salesforce CLI and Git basics.
^² Any resemblance to actual persons or actual events is purely coincidental 😉