Continuous Integration in Salesforce using Bitbucket

Increase your team’s performance by leveraging bitbucket and salesforce:

If your team gets one place to Plan, Project, Collaborate on code, test, and deploy; every bit and piece of the development process become more organized, proficient and productive.

Atlassian is widely renowned for its several arrays of great developer tools, their corresponding suite of products are compatible with the entire software development lifecycle and they are in fact a unicorn in that. Many of the companies are using Atlassian products to bring more agility to their salesforce team; JIRA and Bitbucket are the most often that we hear about.

Bitbucket is not only a git-based repository but it can be deployed to Salesforce DX for a continuous integration and deployment solution. For certain salesforce use cases integrating Bitbucket with Salesforce make development simpler.

Major challenges in code collaboration

Salesforce development can be really difficult in a collaborative way. Most of the time devs and admins find it very hard to stay on the same page. At present code clobbering is a real issue during Salesforce deployments. For instance; a dev would make a change that would reflect on his colleague’s Org and their changes would clobber each other. The Atlassian workflow aims to avoid this.
The other major challenge crops up when an admin makes some changes in production through UI. If changes are made through UI, it can be difficult for developers to see what has changed for the majority of Salesforce instances, as these changes are never tracked in source control hence developers would not have access. Thus handling these merge conflicts becomes a nightmare.

Salesforce development strategy by Atlassian:

Atlassian rolled out 3 amazing principals in order to address these challenges.

It gets confusing when multiple developers (and admins) are working on the same sandbox on different features. It gets confusing to identify who changed what and why. It is easier to track what is happening and avoid merge conflicts, by only working on one feature at a time. This is called “feature-driven development”.

To ensure that no one is colliding with others during the development of new features, every developer should be working in their own sandbox.

Of course, it’s not easy to build a fully hands-off process, but the goal is to take it as far as we can reduce manual tasks. Things like metadata, configuration change, populating picklist values can be automated so that the team can maintain velocity and stay fully focused on coding.

Working in the Cloud with Source Control

Salesforce is all about the cloud, and so cloud-based development practice really makes sense. Leveraging tools like Cloud9 IDE – a cloud-based code editor and Bitbucket Pipelines – a cloud-based CI extension for Bitbucket (cloud-based version control system). Cloud approaches like this make it easier to set up and maintain a good workflow. Also, it only needs to be set up once.

Sandbox Strategy

One of the fundamental problems often found with Salesforce code collaboration is when someone is working in the same sandbox alongside you, they can easily overwrite your changes. As we already know, this is called “code clobbering”.

This problem can be avoided by setting up the Orgs strategically: It is recommended to keep the production org as bug-free and well tested as possible. A UAT or “staging” environment can closely mirror whatever is happening on production.
The usage of a “full copy sandbox” for its UAT environment is suggested as the final testing happens in the UAT environment before moving to production.
Devs should use a unique sandbox and create their own feature branches from Dev repository to work on a feature. Followed by this, they should test the feature to make sure that the feature is working as expected. Once the results are satisfying, the code gets merged back into the Dev repo’s master branch.
Also having a Master Dev Org that actually represents a simulation environment to merge and test the codes from different developers is recommended. This is to make sure that the things are working well, before pushing them to UAT for final testing. Also, declarative changes are often made here if they are global.
Finally, all developers should have their own personal sandbox, as a copy of the Master Dev Org for experimentation and specific feature development.

Git and Bitbucket
Where Git really shines is that it allows you to easily rollback in case any problem arises and allows people to isolate their work. Atlassian’s Bitbucket is recommended for source control.

To isolate code and avoid affecting other users, every feature should have its own branch.

In the Atlassian workflow, the master branch is always stable. A new branch should be created each time in order to establish new features. Apply various changes on that feature branch to test the work you’ve done, and when results are satisfactory then merge it back into the master branch.
Git forking strategy is used to mirror various Salesforce Orgs with different Git repos. A production repo is tied to the production Org. Then place that production repo into a UAT repo which is attached with the UAT Org, and lastly, fork the UAT repo into a Dev repo which is again tied to the Dev Org and so on.

Code reviews and Pull requests are the two key parts of the Atlassian Salesforce developer workflow which can be obtained by using Bitbucket.

The Salesforce Developer Workflow

Setting up sandbox and source control strategy is only halfway through the journey. You need to set up a specific workflow that people can follow to avoid general confusion and code clobbering. As discussed earlier part of this documentation –
Devs should use a unique sandbox and create their own feature branches from Dev repository to work on a feature. Followed by this, they should test the feature to make sure that the feature is working as expected. Once the results are satisfying, the code gets merged back into the Dev repo’s master branch. Followed by this, two important processes take place 1) Code review and 2) Automated testing.

Code review
This process is performed by another developer, before merging the code into the UAT branch for further testing. The review is important because it ensures good-quality coding and enlightens the team on various features in place.

Automated Testing
Along with the manual review, the code is tested automatically to ensure error-free codings. If any deployment to the Dev branch conflicts with your changes, a notification will be triggered.

After the code review and all tests, it can be merged up to the UAT branch if all results are satisfactory. The code then gets deployed to the UAT Org from the UAT repo using an Ant Script. Further testing may occur at this stage and once it is approved it can be safely deployed to the production.

Working with Admins
It is great to have all your developers work independently in this workflow. However, keeping your awesome admins in mind privileged admin accesses are included in Atlassian flow. Admins can make certain changes to the package.xml as metadata isn’t automatically picked up in the Master Dev Sandbox and can manually trigger a build. They will also be able to add commit messages at this point and from there the process flows the same way.

Example: SFDX Bitbucket Pipelines
Here we will demonstrate how bitbucket pipelines can be used in concurrence with Salesforce DX to yield a continuous integration solution. To start with, make sure that you have access to the Salesforce DX pilot and NPM installed. Even though NPM is not a technical requirement to this to work but it is a major convenience

Initial Setup
1. Follow – “Getting Started Guide” for SFDX
2. git clone ssh://
3. cd sfdx-pipelines
4. npm install
5. Authorize the Hub Org: sfdx force:auth:web:login -d --setdefaultdevhubusername (w/ user created in step 1)
6. Authorize “target” org: sfdx force:auth:web:login -a "target". Login using credentials for a production, sandbox or developer org

Development/Scratch Org Creation
simply run npm run createenv

This performs the following actions:
1. Creates a new scratch org
2. Pushes the source
3. runs data load scripts
You can then open the org by running sfdx force:org:open

Adding Appexchange packages
Add App Exchanges packages to the end of the precreateenv script.
Example: sfdx force:org:create -s -f config/workspace-scratch-def.json -a 'defaultscratchorg' && sfdx force:packageversion:install --id 04t44000000VDdT

vscode is recommended for development. The tooling for sfdx is presently very limited and the inline terminal makes it more endurable. If you want to automatically detect file changes and push source, run: npm run push:watch

Running Tests
simply run npm test

Continuous Integration
In this demonstration, you will use bitbucket pipelines as a CI solution.

Branch Strategy
In this process, commit to master should only be through a pull request. Hence automatic committing to master should be disabled when the Bitbucket pipeline is enabled. Otherwise, any commit to master will be prone to an automatic deployment.
We will also have to prevent mergers into master until the commit is successfully built. In a scratch org, Commits to non-master branches will trigger a validation build against it.

First thing first – set up JWT authentication on a HUB org.

1. Create a self signed certificate
2. Add encrypted signing key to build dir
– Generate an AES key & IV. Store them someplace safe for later (Check how liable this tool is)
openssl enc -aes-256-cbc -in server.key -out build/server.key.enc -K [AES_KEY] -iv [IV_KEY] (it should replace the current server.key.enc)

3. Create a connected app on the HUB org
– Enable Digital Signatures and uploaded the .crt (follow step 1)
– Set callback URL http://localhost:1717/OauthRedirect
– Grant Access your basic information, Perform requests on your behalf at any time & full access scope (Full access is optional)
4. Authorize the connected app user by going to:[clientId]&redirect_uri=[redirectUri]&response_type=code
5. Login to your target org. Repeat steps 3 & 4 to create a connected app that you will use for the deployment pipeline.
6. In the Bitbucket, go to Settings->Pipelines->Environment and add the following values:
AESKEY (secured): AES key from the encryption step
IVKEY (secured): IV key from the encryption
CONSUMERKEY_HUB: It is the Consumer Key from the hub org connected app
USERNAME_HUB: Username that will connect to the Hub org
CONSUMERKEY_TARGET: It is the Consumer Key from the target org connected app
USERNAME_TARGET: Username that will connect to the target org

CI Configuration
The CI build process is defined in bitbucket.pipelines.yml. More information about pipeline configuration can be found here.
You can create a docker image for SFDX so that we don’t have to wait while the SFDX dependencies install each run. To easily debug the pipelines.yml, you can start a docker container with this command: docker run -it --volume=/Users/you/code/repo-dir:/repo-dir --workdir="/repo-dir" --memory=4g --entrypoint=/bin/bash illbilly/sfdx. After the docker container is fired up, you can run the individual commands from the YAML. Be careful at this point as any changes made in the container will update the repository.


Leave a Reply

Your email address will not be published. Required fields are marked *