Continuous Integration and Continuous Delivery (CI / CD) are the processes used by development teams to help test and deliver code in the fastest and safest way possible. When a developer is finished with his or her task, they commit their code to a version control system to share the rest of the team. When they do this, an automatic process on a different computer picks up their code and runs a variety of tests on it. If the tests pass, then the new code gets the green light and is then distributed to the rest of the team or maybe even promoted to production. But if any of the tests fail, the process shuts down and the developer is alerted of the issue with their new code.
CI and CD should be considered an essential part of modern software development, and Salesforce DX has been designed to allow developers to use most CI tools for Salesforce development. The most common example of this would work is having your automation process create a new scratch org, deploy the contents of your DX project to this new org, run all your apex tests, then delete the org. This allows you to flag any potential issues with your DX code before you deploy to a sandbox or production.
Salesforce offers an excellent Trailhead module that reviews step-by-step how to use Salesforce DX with a CI / CD tool called Travis CI. But there is one point in the tutorial where the process starts to get a little cumbersome - logging into your Developer Hub org.
The CI automation tools needs to be able to log into your Developer Hub org on your behalf to be able to create a new scratch org. However, you do not want to store your Salesforce password any place where it can access by anyone else. In fact, Salesforce never wants you to store your password in any system other than their own. That is why they have switched to OAuth for all their developer tools, including Salesforce DX.
To log into your Developer Hub org for DX on your own computer, you must run the web authentication command in your command line:
$ sfdx force:auth:web:login -d -a Hub_Org
What this does is open up a web browser pointed to the Salesforce login page. You log into Salesforce with your username and password, and you click a confirmation button acknowledging that you wish to share your login with Salesforce DX.
Salesforce will then create an access token for your DX tool and save it onto your computer. This token is unique gibberish and has no traces of your actual username or password on it. This token will allow DX to continue to log into your Salesforce org on your behalf without ever needing to prompt you for a password again. If your computer ever falls into the wrong hands, you or your admin can click “Revoke” under the "OAuth Connected Apps" section of your Salesforce user page to render the token invalid from that point on. More information regarding auditing and revoking OAuth apps in your org can be found here.
The OAuth flow is a very genius method of having you only give your password directly to Salesforce when using external tools. You never save your password on your computer nor do you give it to any third party who can steal it from you. And this works very well because your computer is able to open the separate web browser and have you log in on the Salesforce login page.
But what happens when your CI process needs to make the same login all by itself?
Your CI tool is a robot that lives on a seperate computer somewhere on the internet. If a seperate web page pops up on its desktop prompting for a password, the robot probably does not know how to point, click, and type into it. But even if the robot did know how to use a website, how does it know what your username and password is? Will you be around every time it runs to tell it? Will you save it somewhere that might be hacked and stolen by someone else?
Neither of these are good solutions. As of the time of this writing, the Trailhead tutorial we mentioned earlier provides a complicated process that involves generating a Self-Signed SSL Certificate and Private Key, creating a connected app on the Salesforce org, then utilizing the force:auth:jwt:grant command to have your CI tool log in for you. But the team at CRM Science found this solution too difficult to repeat for all of our projects, so we took some of the ideas from it and developed a much easier solution.
DX provides three options for login - the common web login, the complicated jwt login, and the simple SFDX URL option. The SFDX URL is a unique URL in the format of force://<clientId>:<clientSecret>:<refreshToken>@<instanceUrl>. It is automatically created by DX after you do the web browser login and can be used in the future to log in again without prompting for a password.
To view the SFDX URL for the Developer Hub you logged into earlier, run the following command in your command line:
$ sfdx force:org:display -u Hub_Org --verbose
The URL will be listed under “Sfdx Auth Url” and will start with “force://”. Copy this url and paste it into its own file in your DX project’s main directory called “dev-hub-login.txt”. This text file is all you or your CI tool needs to be able to login again, and it has the same revocable protection that your OAuth token does. But it also means that anyone can login to your account if they ever obtained this file, which is very possible if you share it with your CI tool.
You must come up with a new, unique, unguessable password for the sake of protecting this text file. I recommend using any random password generator. Do not worry about remembering it, you will only be using it twice.
The first use of this new password is to encrypt your text file. Follow the Tailhead tutorial for installing OpenSSL on your computer, then use the encryption command to encrypt your dev-hub-login.txt file with your new password.
$ openssl enc -aes-256-cbc -k “This Is My Password” -in dev-hub-login.txt -out dev-hub-login.txt.enc
You will notice that you can open your original text file and view your SFDX URL, but you are not able to open the new “.txt.enc” file without seeing gibberish. This encrypted file can only be viewed by those who know the password you used in the previous command. As long as you keep the password to yourself, you are free to share the file to anyone.
You will share this file with everyone - including the CI tool - by committing it to your version control system. Delete the original .txt file and commit your encrypted txt.enc file to your code repository.
The second use of your new password would be to allow your CI tool to decrypt the SFDX URL file. Your tool should allow you to set environment variables for your project, and it will probably provide an “encrypted” or “secure” option for each variable. This is a one way save option for your sensitive information. When you use this option, you enter your password once during setup and save it to your tool. After that point, no one else (including yourself) will be able to see what you had entered. You would have to reset the whole thing in order to edit it.
Create a secure environment variable called DEVBOXPASS and save your random password. You can then disregard your random password. In your CI running script, include the following line to decrypt your file:
- openssl enc -d -aes-256-cbc -in dev-hub-login.txt.enc -out dev-hub-login.txt -k $DEVBOXPASS
And then include the following line to use the decrypted file to log into your dev hub:
- sfdx force:auth:sfdxurl:store -f dev-hub-login.txt -d -a Hub_Org
This is all the CI tool needs to be able to log into your Developer Hub on your behalf. It starts with a direct login from you to Salesforce using your DX tools. You obtain a personal URL for the login that can be saved and used again to replicate the login in the future. You encrypt the URL and share it to your CI tool. Your CI tool decrypts the URL and logs in. Your Salesforce password is never saved and all sensitive information is hidden from others.
This login strategy can also be used for all Salesforce org types, not just your Developer Hub. You can create SFDX URLs for your sandboxes and production orgs. This would be used for your Continuous Delivery process. Expand your scripts to automatically deploy your DX projects to a QA sandbox after they pass all tests in your CI scratch org, and then run all your tests again on the QA sandbox. If it looks good, then consider having the script deploy directly to production as well. As long as you trust the results of your test scripts, then CD makes your development process fast, safe, and efficient.
Have a question on this blog post or want to geek out over Salesforce Development with us!?
Tweet us @CRMScience or reach out on our contact page!