Salesforce CI/CD Using Bitbucket Pipelines

August 31, 2018 Abhishek Saxena

Salesforce Release Management using Ant Migration Tool (ANT) can be cumbersome and time-consuming, especially when there are crucial go-live deadlines to reach. What if we could automate SRM and catch errors while deploying it to all environments seamlessly? 

Sounds dreamy, right? Using Continuous Integration (CI) and Continuous Deployment (CD) tools in your project can make this dream a reality. 

Challenges to overcome
Some challenges come up during Salesforce project delivery. These may include: 

  • Change tracking, prevention of code overriding, and monitoring evolution of codebase.
  • Deployment errors cropping in everytime we migrate the codebase from sandbox to sandbox until it reaches the production environment.
  • Package.xml creation and maintenance as well as removal of invalid manifest items from it.

Traditionally, we use Ant Migration Tool on our local system to perform deployments, but these problems raise an important question — if you want to build for the cloud, why not build in the cloud?

Version Control + CI to the rescue
Source control facilitates code traceability and accountability as well as enable code reviews. All of this is down with continuous integration that allows us to identify deployment issues early and ensure that our changes will successfully deploy at the time of release. The setup for Bitbucket Pipelines is much simpler than Jenkins and Bamboo, as there is ’s no need to set up cloud agents, and EC2 servers or local server instances.

In the toolbox…
Let’s look at the tools required:

  • GIT - A version control system for tracking changes in files and coordinating work on those files across the team . All metadata items, whether modified on the server or locally, are tracked via GIT. This provides us with a version history as well as traceability.
  • Bitbucket - Bitbucket is a cloud-based GIT server from Atlassian used for hosting our repository. It provides a UI to navigate the GIT repository and has many additional features like pull requests. These are used for approving and merging changes.
  • Docker - Docker provides a way to run applications securely, packaged with all its dependencies and libraries. So, we will be using it to create an environment for running a Force.com Migration tool.
  • Bitbucket Pipelines - Bitbucket Pipelines is an add-on for Bitbucket cloud that will allow us to kick off deployments and validations when updates are made to the branches in Bitbucket.

What is Docker?
If you have always worked in Salesforce, then it’s quite possible that Docker containers sound alien to you. So what is Docker? In simple terms, Docker can be thought of as a virtual machine in the cloud. Docker provides an environment in the cloud where applications can run. Bitbucket Pipelines support Docker images for running the Continuous Integration scripts. So, instead of installing Ant, JDK in your local system, you’d now specify them to be installed in your Docker image, so that our CI scripts can run Migration tool.

Docker Hub has many public images, which anyone can use simply by specifying their name in the YML file. Let’s refer to a Docker Image created specifically for Salesforce Deployments, which can be used publicly. 

Not too complicated, right? We’ve just specified a bunch of tools we might need when running our pipelines. 

Downloading Force.com Migration Tool
To perform Salesforce Deployments, we would require the Ant Migration tool. It can be downloaded from Salesforce’s official page. Like we installed some of the other setuptools in the Docker image, we could also install the migration tool. However, to provide greater flexibility in updating the migration toolbox, we will include it in our repository, so that we could simply replace it whenever a newer version is available.

Let’s put the toolbox inside a builds/lib folder, in the root of your git repo. 

Along with the migration tool, we will need two other files, namely build.xml and build.properties to specify the migration jobs and org credentials, respectively. Create them inside the builds folder and replace the code with the following:

Build.xml

Build.properties

Setting up your repository

Note: 
We have configured a sample repository for you to look at the setup yourself, check it out if you are stuck somewhere.

Now that we’ve done most of the pre-work, let’s log in to Bitbucket and enable Bitbucket pipelines to bring CI to life.

  • Create a repo in Bitbucket for your project
  • Enable Pipelines for your repo  
    • Within your BitBucket repository, click the Pipelines link in the left sidebar.  
    • Now,  click the Enable Pipelines button.
    • BitBucket will auto-generate your bitbucket-pipelines.yml. Then it will update the file as shown below; the actual code-snippet is hosted here:

  • The ANT commands execute the deployment. This includes merging the variables from your Pipelines environment variables to inject into your build.xml. You can leave these untouched unless you wish to add more variables.
  • Pipelines Environment Settings - These are key-value pairs entered in your Bitbucket account. You'll find them under your settings, beneath Pipelines. Each key provided here will be exposed as an environment variable in your build job. Set up repo-level environment variables as follows:
    • SFDC_USERNAME:  The full username for your Salesforce deployment user (example,  bitbucket@example.com.dev)
    • SFDC_SERVERURL: test.salesforce.com (for your sandboxes) or login.salesforce.com (for dev/production orgs) 
    • SFDC_PASS: Salesforce user password for your deployment user, assuming your Pipelines deployment user password will be shared across your Salesforce production and sandbox instances. You'll also want to go ahead and mark this one as a secured value, so it isn't revealed to observers.
    • SFDC_TOKEN:  The security token for that user on that particular instance. This is important; else, your job will fail to authenticate. Use the token since you can’t rely on whitelisting an IP range here. 

Validating our setup
With everything set now, it’s time for us to test our CI setup.

  • Open VScode/Force.com IDE 2. Create a branch called feature/helloWorld and create an Apex class HelloWorld in it.
  • Commit the class and push the changes.

This should trigger validation behavior and we can navigate to Bitbucket UI to check the status of the pipeline.


Any errors that occur, while your job is trying to validate your package, should appear in the second step. Troubleshooting these should be easy, especially if you're comfortable with the Force.com Migration Tool. If you have your test Org open you can also watch the Deployment Status page. When the Ant job runs, you should see a validation process in your Org.

  • Once the build has been successful, we can create a pull request that asks the leads to review the changes made, and then merge it. As soon as they merge it to the master branch, bitbucket pipeline would be triggered and it will deploy the code. Again, check the Pipelines page to view the status of any errors or merge conflicts. If present, they would show up there. If no errors are present and we have a successful build of the master branch, then we can go to the QA org and verify if the deployment has been done.



Starting over with a CI system needs comprehensive learning and understanding, but once you get comfortable with it, there’s no looking back. Version Control with Continuous Integration and Continuous Delivery is a perfect combination to get started with DevOps and move your organization towards a streamlined delivery process. 

If this is awesome, then you’re in for a surprise as this is just a miniscule of Appirio‘s DX capabilities. With SalesforceDX now generally available, there’s a lot more our DevOps experts have to offer. Learn more about how Appirio DX provides a reliable internal DevOps strategy for your project. We’d love to transform digital experiences for your workers and customers!

Previous Article
Salesforce Triggers the Next-Generation IoT Experience
Salesforce Triggers the Next-Generation IoT Experience

Orchestration may sound new to you, but if you are a Salesforce user, it’s time to dive deep into orchestra...

Next Video
Salesforce + Appirio = Successful Outcomes
Salesforce + Appirio = Successful Outcomes

Are You Ready for Salesforce Lightning?

Read More