It’s already a couple of months into the new year, but a lot of us are still likely thinking about what we can improve on....by Tiffany Chang
March 5, 2019
I have always wished that Salesforce deployments were easier. As a developer, I have seen so many days wasted due to its tedious and error-prone deployment process.
A typical Salesforce deploy looks something like this:
As you can see this is a pretty long list. Each step must be performed manually and the entire process is prone to error. If you want to deploy to multiple environments then you have to repeat this entire process for each one.
I have encountered many issues with this process, including:
I wanted to use the same deployment system that we use for everything else at PagerDuty. We use an in-house deployment system named Igor controlled through our Lita bot called OfficerURL (URL for short). URL allows us to deploy our code with a single command in Slack.
!deploy salesforce <branch:default is master> to <environment>
So, for example, to deploy the master branch of our Salesforce code to production we would type:
!deploy salesforce to production
The bot will then tell us whether it succeeded or failed. It also links us to the deployment logs in Igor.
Here is a screenshot of an actual Salesforce deployment I did recently:
It’s really that easy.
At a high level, our bot / deployer duo does the following:
The tool that enabled this workflow is https://github.com/neowit/tooling-force.com.
A major advantage of this tool is that it enables deployments that remove components in Salesforce that no longer exist in the working directory. In effect it makes Salesforce’s copy of the project match your working directory as much as possible. Most other tools only deploy the files in the working directory; they don’t remove components in Salesforce that no longer exist locally. This can result in code remaining active in Salesforce when it should have been removed entirely.
The following is the command that runs when you deploy through chat:
java -jar path.to.jar --action=deployAllDestructive --config=path.to.properties --projectPath=. --responseFilePath=/dev/stdout --maxPollRequests=200 --specificTypes=./src/package.xml --typesFileFormat=packageXml | tee deploy.stdout grep 'RESULT=SUCCESS' deploy.stdout
You can download a jar of the tool at https://github.com/neowit/tooling-force.com/releases.
Note that the path.to.properties has a variable that represents the environment to deploy to so that we can deploy to multiple environments.
The properties file:
sf.username=username sf.password=password sf.serverurl=https://login.salesforce.com or https://test.salesforce.com
The package.xml file is checked into git and specifies which components to deploy. I use:
<?xml version="1.0" encoding="UTF-8"?> <Package xmlns="http://soap.sforce.com/2006/04/metadata"> <types> <members>*</members> <name>ApexClass</name> </types> <types> <members>*</members> <name>ApexComponent</name> </types> <types> <members>*</members> <name>ApexPage</name> </types> <types> <members>*</members> <name>ApexTrigger</name> </types> <types> <members>*</members> <name>StaticResource</name> </types> <version>34.0</version> </Package>
This would have been harder to implement without our awesome DevTools team. They maintain the bot that provides common functionality such as handling the git checkout, status notifications, and logging when running a deploy script.
Also thanks to Andrey Gavrikov (neowit on GitHub) for providing the tooling-force.com command line application which enables easy Salesforce deployments from a folder.