Sunday, March 29, 2015

Implementing Continuous Integration Using Jenkins and Git for Salesforce Development

Continuous Integration (CI) is a development practice the allows developers to check-in their changes into a shared repository unlimited number of times. Each check-in is then verified by an automated build system, thus eliminating the changes of breaking some other part of the application while fixing one part.

By implementing Continuous Integration, you can detect errors quickly and locate them more easily. I always recommend to implement Continuous Integration in any kind of software projects. I personally implemented CI multiple times for Java and C++ projects in my career. Now last week, I implemented the same for Salesforce development. In today's post, I will explain how to do that.

Below are the prerequisite softwares -
Before we go further, I recommend you to go through the below posts to understand the concept.
Below picture will give you a high level overview about what I am going to achieve by implementing CI.

Step 1 - 
Install Jenkins on your local machine by downloading the Java Web Archive (.war) from here. Once downloaded, execute the below command from the directory where you have saved -
java -jar jenkins.war
After that open your browser and go to http://localhost:8080/. You will find that Jenkins is running on your local machine. Great!! So you have successfully configured Jenkins on your local machine.

Step 2 -
In this step, we will install Git plugin. You can do that by clicking on Manage Jenkins | Manage Plugins | Available and search for Git. Select Git Plugin to install the plugin and the restart your Jenkins.

Step 3 -
In this step, we will configure Jenkins by giving JDK, Git and Ant installation location. You can do that by clicking on Manage Jenkins | Configure System. Below is the screenshot from my system -
  
Step 4 -
In this step, we will setup Bitbucket account.
For that we need to generate SSH key for authentication. You can use eclipse to generate SSH key. Once you generate your SSH key, please upload the public key in Bitbucket by "Manage Account | Security | SSH Keys | Add Key". You need to save the private key with extension "ppk" in your local machine.

Step 5 -
In this step, we will configure our eclipse workspace for Sandbox 1 and check-in the code into Bitbucket repository.

To do that, first we need to download the Force.com Migration tool from Sandbox. Once downloaded, create a folder "lib" in eclipse and add the ant-salesforce.jar file there. After that add build.xml, build.properties and package.xml

Once added, please check-in the code into your bitbucket repository. 

Step 6 -
Now we will create a new projects in Jenkins by navigating "Home Page | New Item". Give appropriate name and choose "Freestyle project" as displayed below -
In the "Source Code Management" we need to choose Git. Here we need to provide the Git repository URL (Please provide Bitbucket URL for SSH Protocol). For connecting to Git repository, we need to add credentials also. For credential, click on "Add" button, choose "SSH Username with private key".
Provide username and paste the key saved in "ppk" file (Step 4).
Below is the screenshot -
Step 7 -
In this step, we need to prepare our build.xml, build.properties and package.xml so that it can fetch code from Sandbox 1 and deploy in Sandbox 2
Below is the build.xml -
<project name="Sudipta Deb - Continuous Integration Demo" default="test" basedir="." xmlns:sf="antlib:com.salesforce">

    <property file="build.properties"/>
    <property environment="env"/>

    <target name="fetchChanges">
        <sf:retrieve username="${sf1.username}"
                     password="${sf1.password}"
                     serverurl="${sf1.serverurl}"
                     retrieveTarget="src"
                     unpackaged="package.xml"/>
    </target>
    
    <target name="deploy">
        <sf:deploy username="${sf2.username}" 
                     password="${sf2.password}" 
                     serverurl="${sf2.serverurl}" 
                     deployRoot="src"
                   runAllTests="true"
                   logType="Detail" />
    </target>
</project>

build.properties - (Note: Personally I don't like giving username+password details in build.properties file, rather I will give those details in next step while configuring ant build step.)
sf1.serverurl = https://test.salesforce.com
sf2.serverurl = https://login.salesforce.com
package.xml -
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>*</members>
        <name>CustomObject</name>
    </types>
    <types>
        <members>*</members>
        <name>ApexClass</name>
    </types>
    <types>
        <members>*</members>
        <name>ApexPage</name>
    </types>
    <version>33.0</version>
</Package>


Step 8 -
Here we will configure how frequently Jenkins should check for changes and start build process. For that we need to choose "Poll SCM" option and give "H/15 * * * *" as schedule which will make sure that every 15 mins Jenkins will check for new changes. Below is the screenshot -

Step 9 -
Now we need to add build steps. We can do that by Build | Add Build Steps | Invoke Ant. Here is the step -

Step 10 -
Now we will add post build step which will send the build notification email. Below is the setup -

We are done. Now we can use Jenkins to first retrieve the changes from Sandbox 1, then execute the test cases and finally deploy the changes into Sandbox 2.

I hope now you can configure Continuous Integration for Salesforce Development. Please provide me your feedback. Thanks in advance.


8 comments:

  1. Sudipta, Very nice article on the CI integration pattern. I used Drone as CI with bitbucket + eclipse. Currently, each time code is pushed into bitbucket, it triggers build of the ant script which takes the whole src folder from the repository and deploys it into a sandbox. My intention is actually to push only the changes(for example only the class that is changed) and not the whole source folder.I tried using the target 'fetchChanges' as shown in your build.xml, but looks like it retrieves the whole source folder and not just the changes, is it possible only to deploy the changed class file for example(without specifying it in the package.xml) ?

    ReplyDelete
  2. Sudipta, Very nice article on the CI integration pattern. I used Drone as CI with bitbucket + eclipse. Currently, each time code is pushed into bitbucket, it triggers build of the ant script which takes the whole src folder from the repository and deploys it into a sandbox. My intention is actually to push only the changes(for example only the class that is changed) and not the whole source folder.I tried using the target 'fetchChanges' as shown in your build.xml, but looks like it retrieves the whole source folder and not just the changes, is it possible only to deploy the changed class file for example(without specifying it in the package.xml) ?

    ReplyDelete
  3. How is this polling for changes? Looking at the Package.xml, it appears that it just retrieves everything and deploys it from the src to the target. I'm not very good with git and don't use bitbucket, is there some step that is using Jenkins to pull the diff of the latest push and HEAD^ and generate the Package.xml with just the changed metadata?

    ReplyDelete
  4. hello admin.i am truly cherish it your blog.Because your clarification insightful every one of the themes are excessively good.I got enough information from your blog.Thanks for sharing more.. Devops Training in Bangalore
    Devops Training Institute in Bangalore
    Best Devops Training in Bangalore

    ReplyDelete
  5. I acknowledge the author for his brilliant work for making this exceptionally useful and informative content to guide us.
    salesforce form builder

    ReplyDelete
  6. Nice information my sincere thanks for sharing this post Please Continue to share this post
    Devops Training in Bangalore

    ReplyDelete
  7. Very nice Blog relating SalesForce Development with Jenkins and Git Thank you Sharing.

    Devops Training

    ReplyDelete
  8. Very Nice Blog on Continuous integration... Thank you for the Blog.
    Devops Training in Bangalore"

    ReplyDelete