Create a Salesforce CI/CD pipeline using Gitlab CI (or any other)
With Salesforce DX not being general, available having a good delivery pipeline on Salesforce is quite cumbersome. We show you how to do it using Gitlab CI.
So in short, how this will work:
- We setup the needed tools
- We grab all the metadata from your Salesforce Org
- We commit the relevant parts of your code
- We create a pipeline testing and deploying the code to one or more Salesforce Orgs
Need help setting this up? Contact us.
#1 Setting up the tools
We use the Salesforce Metadata API to deploy new code and possibly other things like permissions to different environments. For this you can use the Force.com Migration Tool but that simply s*cks. There is this awesome force-dev-tool (a npm package) that wraps the whole thing much more usable. Install it using:
npm install --global force-dev-tool
Next you should be able to run the following command:
$ force-dev-tool
Usage:
force-dev-tool <command> [<args>...]
force-dev-tool -h | --help
force-dev-tool --version
Configure your different environments (Salesforce orgs).
$ force-dev-tool remote add development user pass --default
$ force-dev-tool remote add production user pass
Check if you can login.
$ force-dev-tool login development
Logged in successfully to remote development.
Use the following URL to open Salesforce in your web browser:
https://mynamespace.my.salesforce.com/secur/frontdoor.jsp?sid=REDACTED
#2 Grabbing the metadata
Create a new folder for your project:
$ mkdir your-sf-project
To download all the latest metadata from your production org (or any other) run:
force-dev-tool fetch --progress production
force-dev-tool package -a production
force-dev-tool retrieve production
This will create a src
folder with all your metadata. The src/package.xml
file will contain all the different items we want to deploy (sync to other orgs).
The hard part now is to strip the src
folder and src/package.xml
to only contain the relevant parts you want to have deployed. Let’s say you only want to deploy all things Apex. Edit src/package.xml
to only contain something like:
<?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>
<version>38.0</version>
</Package>
Remember, not all types support the *
(wildcard) in members
.
Next remove all folders from src
except:
src/classes/
src/components/
src/triggers/
#3 Committing the code to Gitlab
Get into an empty project directory to grab your Salesforce environment.
$ cd your-sf-project
$ git init . # or an existing Gitlab project repo
$ git add .
$ git commit -m "My first Salesforce metadata."
# Add your remote repo and push your code (to Gitlab / Github / Bitbucket / ..)
#4 Creating an automated pipeline
Your CI/CD pipeline will use two commands. One to test deployments without actually doing a thing. Another to really deploy.
force-dev-tool -ct development # This will do a dry-run
force-dev-tool -t development # This will test and deploy
In Gitlab this is super easy, just create the following .gitlab-ci.yml
file:
stages:
- test
- deploy
image: node:7.2.0
before_script:
- npm install --global force-dev-tool --silent &>/dev/null
cache:
paths:
- /usr/local/lib/node_modules
untracked: true
test_deploy_development:
stage: test
script:
- force-dev-tool deploy -ct development
test_deploy_production:
stage: test
allow_failure: true
script:
- force-dev-tool deploy -ct production
deploy_development:
stage: deploy
environment: development
only:
- develop
script:
- force-dev-tool deploy development
deploy_production:
stage: deploy
environment: production
when: manual
script:
# The -t makes sure we run tests
- force-dev-tool deploy -t production
Commit this file to your repo, push it to Gitlab and whach your changes being deployed automagically. To deploy to your production
environment / org you still need to press the play button.
Need help setting this up? Contact us.