A blog dedicated to Salesforce Ohana

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.


Share:

Lightning strikes Trailhead - Fun way to learn Lightning


Trailhead is one of my favourite approach to learn new stuffs from Salesforce in an interactive way. I highly recommend employers to encourage all it's developers and administrators to check trailhead and learn new stuffs.

Trailhead brings a new module "Lightning Components" which will help developers to understand lightning concepts. In today's post, I will review this new module "Lightning Components".

This module comes with 9 different sub modules. All the sub modules are organised so well that at the end of 9th sub module, you will feel really comfortable and at the same time feel the power of lightning which will definitely inspire you to explore the unexplored world.

Let's start discussing each sub module.

Sub Module 1: Getting Started with Lightning Components -
This is the first sub module which will give you an overview of Lightning Components. By the end of this module you will understand below important concepts -
  • What is all about Lightning Component Framework?
  • Difference between Lightning and Visualforce
  • What are the different places where you can use the Lightning Component framework?
This sub module mainly tells you how you can go for component based development. Google is having Polymer, Facebook is having React and now Salesforce is also having Lightning Framework - Component based development.

After completing the challenge, you can earn 100 points.
Sub Module 2: Creating Components -
This is the module where you will get familiar with creating lightning components, adding style to that and finally making the lightning component available in Salesforce1. Another important thing you will get to know the list of resources in a component bundle.

This module documented the concept of component bundle by the the following table -
In this module, you will also get to know how to refer elements in CSS to add styles. I have prepared the below document for my reference which I am sharing here -
Below is the CSS to add styles -
Now here is the resulting page -
After completing the challenge, you can earn 500 points.
Sub Module 3: Defining Component Attributes -
This is the module where you can make yourself familiar with passing attributes to components, creating multiple instances of the same component and setting attribute values on a component reference. I really enjoyed going through this module and after completing this module, I have prepared a small demo -
StudentComponent.cmp -
<aura:component >
    <aura:attribute name="studentName" type="String"/>
    <aura:attribute name="score" type="Integer" />
    <aura:attribute name="passedOrNot" type="String"/>
    
    <div class="studentDetails">
        <div class="name">Student Name: {!v.studentName}</div>
        <div class="score">Student Score: {!v.score}</div>
        <div class="passed">Passed: {!v.passedOrNot}</div>
    </div>
    <div>
        <ui:button label="Check whether passed or not" press="{!c.check}"/>
    </div>
</aura:component>
StudentComponent.css -
.THIS {
}
.THIS.studentDetails{
    background-color: yellow;
    padding: 30px;
} 
.THIS .name{
    color: red;
}
.THIS .score{
    color: green;
}
.THIS .passed{
    color: black;
}
StudentComponentController.js -
({
    check : function(component) {
        if(component.get("v.score")>80){
            component.set("v.passedOrNot","YES");
        }else{
            component.set("v.passedOrNot","NO");
        }
    }
})
Now it's time for StudentApp.app -
<aura:application >
    <h1>STUDENT 1</h1>
    <c:StudentComponent studentName="Peter" score="98"/>
    <h1>STUDENT 2</h1>
    <c:StudentComponent studentName="John" score="75"/>
</aura:application>


Below is the screenshot -
After completing the challenge, you can earn 500 points.
Sub Module 4: Using Expressions -
This is the section where you can understand how to use expressions to make your components dynamic, how to pass conditional expressions. If you are comfortable with VisualForce, then for your this sub module will be very easy. But the important section of this sub module comes where you can learn how to refer/get browser and locale information both from component and controller.

After completing the challenge, you can earn 500 points.
Sub Module 5: Using Standard and Force.com components -
In this section, you will get to understand how you can make your GUI more attractive by using Standard and Force.com components. You will get to know all the events available to that particular components. At the end of the section, you will get an exercise which is really good for you to check your understanding.

For all available component attributes and events, see the component reference @ https://<mySalesforceInstance>.lightning.force.com/auradocs/reference.app, where<mySalesforceInstance> is the name of the instance hosting your org; for example, na1 .

After completing the challenge, you can earn 500 points.
Sub Module 6: Handling Events with Client-Side Controllers -
This is the section where you can understand how to write client side controller to handle events, create events to communicate between different components. In this module you will know the differences between application event and component event and different types of Salesforce1 events also.

After going through this module, I have developed a small application to make myself comfortable with inter component communication.
SendName event -
<!-- SendName event -->
<aura:event type="APPLICATION" description="Send Name Event" >
    <aura:attribute name="firstName" type="String" />
    <aura:attribute name="lastName" type="String" />
</aura:event>
SendNameSender component -
<!-- SendNameSender component -->
<aura:component >
    <aura:registerEvent name="SendNameEvent" type="c:SendName"/>
    <ui:button label="First Student" press="{!c.send}"/>
    <ui:button label="Second Student" press="{!c.send}"/>
</aura:component>
SendNameSender controller -
({
    send : function(component, event, helper) {
        var whichButtonClicked = event.source.get("v.label");
        if(whichButtonClicked=="First Student"){
            firstName = "Peter";
            lastName = "Sasse";
        }else{
            firstName = "James";
              lastName = "Hau";
        }
        $A.get("e.c:SendName").setParams({
            firstName: firstName,
            lastName: lastName
        }).fire();
    }
})
SendNameReceiver component -
<aura:component >
    <aura:attribute name="fullName" type="String" default="none" />
    <aura:handler event="c:SendName" action="{!c.prepareFullName}" />
    Full Name: {!v.fullName}
</aura:component>
SendNameReceiver controller -
({
    prepareFullName : function(component, event, helper) {
        var firstName = event.getParam("firstName");
        var lastName = event.getParam("lastName");
        component.set("v.fullName", firstName + " " + lastName);
        //component.set("v.fullName", firstName );
    }
})
Finally the application -
<aura:application >
    <c:SendNameSender />
    <br />
    <c:SendNameReceiver />
</aura:application>
Below is what you will receive -
    & 
After completing the challenge, you can earn 500 points.
Sub Module 7: Using Javascript Controllers with Components -
In this section, you will get to understand how to use JavaScript API to work with components, get user input and validate that in client side, how to create components dynamically, how to show error messages by creating dynamic error message window. In this section, you will know how to handle exceptions.

After completing the challenge, you can earn 500 points.
Sub Module 8: Using Apex in Components -
This is the section where you can understand how to load record data and display it in a component. This module will teach you how to call an Apex controller to fetch/edit/save the data.

After completing the challenge, you can earn 500 points.
Sub Module 9: Debugging your Components -
In this section, you will get to understand how to debug your lightning code using $A.log and $A.warning.You will also get to know how to use Debugger statement to examine the code execution in the browser.

After completing the challenge, you can earn 50 points.

I really enjoyed going through each sub module and now I am feeling inspired to explore more Lightning.
I am feeling good that I am having 6 Trailhead badges now.

Share:

Salesforce Deployment Guide using Ant Migration Tool


In Salesforce, we have three different ways by which we can perform the deployment activities. They are -
  • Change Sets - This is available from Salesforce.com site.
  • By using "Deploy to force.com server" option in Eclipse.
  • Using Java based tool - ANT.
In this post, I will provide a complete deployment guide using Ant Migration Tool.

Before I start, let me tell you the prerequisite for doing deployment using Ant Migration Tool.
  • Requirement - Java: You should have java installed in your machine. To verify whether you have java installed, do the below steps -
    • Open a command prompt
    • At the prompt, type java -version. You should see something like below which indicates your installed java version
  • Requirement - Ant: You should have ant installed in your machine. To install ant, do the below steps -
    • Download ant from http://ant.apache.org/bindownload.cgi
    • Set environment variable "ANT_HOME" which should be the path of your installation. Add the bin folder to your path as well like %ANT_HOME%/bin
    • Verify by issuing the command ant -version from command prompt. You should see something like below which indicates your installed ant version.
Once you have configured Java and Ant successfully into your machine, it's time to download the Force.com Migration Tool. You can download the same by logging into your Org and then Setup | Develop | Tools and then click Force.com Migration Tool. Once downloaded, extract the zip file and copy ant-salesforce.jar file to the lib directory of your ANT installation path.

To start with the deployment process, you need mainly below files -
  • build.xml - This file will exercise the deploy and retrieve API calls
  • build.properties - This file will be used to store your Salesforce credentials and other properties in order to run sample ant tasks.
  • package.xml - This file will be used to identify what are the stuffs we are interested from org (ex. Custom Objects, Standard Object, Custom Fields, Apex Classes, VisualForce Pages etc.)
Now we will do two exercises here. In first exercise, we will retrieve/download specified items from Salesforce Org and save it in own local machine. And in the next exercise, we will upload the previously downloaded items to our Production Org.

Exercise 1 -
In this exercise, we will retrieve/download specified items from Salesforce Org and save it in own local machine. 
The build.properties file is -
The package.xml file is - 
Note - In my Sandbox, I have created a new custom object names Country (API Name: Country__c). This object is not present in my Production environment. What I am trying to do is download County__c and save it in my local machine.

The build.xml file is -

Now we will execute the ant command ant fetchNewItems to download the item from Salesforce and Save it into my local machine.
As a result, we will see that a new folder with retrieveOutput is created and content from Salesforce is copied into that folder. 
So COOL. We now know how to copy items from Salesforce Org to Local Machine. 
Just for your information, you can download not only Custom Objects, but you can download anything like Standard Object, Standard Fields, Custom Fields, Apex Classes, Visual Force Pages etc. The only thing is that you need to mention that in your package.xml file.

Below is one example package.xml file, which can be used to download -
  • All Custom Objects
  • All Apex Classes
  • All Visual Force Pages.

Now let's move to the new exercise.
Exercise 2 -
In this exercise, we will upload the previously downloaded items to our Production Org.
The build.properties file is -
The package.xml file is -
This is the same package.xml mentioned in Exercise 1.
The build.xml file is -
Now we will execute the ant command ant deploy to deploy the items present in the folder "retrieveOutput" into Production environment.

DONE. So with the above two exercises, we now know how to deploy changes from one Org to another with Ant. We can combine steps from the above two exercised to achieve the below requirement -

I am sure you are now feeling more comfortable in using Ant for deployment purpose. Please let me know if you have any specific doubts. Thanks.
Share:

Use Case 3 - WebSphere Cast Iron Integration - MySQL and Salesforce.com

Preface - This post is part of "WebSphere Cast Iron Cloud Integration with Salesforce.com" series.

Today I will post how you can use WebSphere Cast Iron for integrating MySQL with Salesforce. Toady, in this example, I will fetch records from MySQL Table and then create the Salesforce object based on that record. So READY, STEADY and GO!!

Note: I have used http://www.freemysqlhosting.net/ for creating free MySQL Database.

Use Case:
Below is the object structure -
MySQL table looks like  - 

Implementation:
Before we start implementing the above requirement, let's create the Endpoints first.
Endpoint - FTP:
Endpoint - Salesforce:

So all set. Now we will configure the integration by putting activities inside the Orchestration.
Activity# 1: Database - Get Inserted Rows:
In this activity, I will fetch the inserted rows from the database. Below are the configuration details -

Activity# 2: Add If - Else Condition:
The requirement is - if the Airport Name is blank, then terminate the process, else do an upsert into Salesforce.com
The configuration is displayed below -
Activity# 3: Salesforce Upsert Objects:
Below are the configuration details for this step - 

We are done. The final Orchestration looks like -
Test the Integration -
It's time to test the configuration. First we need to start the orchestration and we can do that from Orchestration | Start Orchestration.
After 5 seconds, if we see our Salesforce Airport object, we will be able to see that two records being created as shown below -
COOL!!!
If you follow the steps mentioned in this post, you will be able to configure this integration very easily. 
Please let me know if you need any details. Thanks.
Share:

Use Case 2 - WebSphere Cast Iron Cloud Integration - Fetch CSV File from FTP Server and Insert Data into Salesforce.com

Preface - This post is part of "WebSphere Cast Iron Cloud Integration with Salesforce.com" series.

Today I will post how you can use WebSphere Cast Iron for integrating FTP with Salesforce. Toady, in this example, I will fetch a CSV file present in a FTP server, read that file and then create the Salesforce object based on that record. Finally I will send the response also. So let's not waste time here and get straight into the business.

Use Case:
Below is the object structure -
Below is the CSV File(All_Airports.csv) I would like to read and load from FTP server.
Once done, the final requirement is to create Salesforce records based on the data present in the CSV file.

Implementation:
Before we start implementing the above requirement, let's create the Endpoints first.
Endpoint - FTP:
Endpoint - Salesforce:
Endpoint - HTTP:
Create a default HTTP endpoint with port number 80.

Now we will create the Flat File Schema as shown below. This flat file schema will be used to read to CSV file present in the FTP server.

So all set. Now we will configure the integration by putting activities inside the Orchestration.

Activity# 1: HTTP Receive Request:
Below you will find all the configuration details related to Receive Request activity.
Activity# 2: FTP Get File: 
This activity will fetch the CSV file from the FTP Server. The configuration of this activity is displayed below -

Activity# 3: Transform Read Flat File:
Activity# 4: Salesforce.com Create Objects:
In this activity we will create Salesforce records for the custom object Aiport__c based on the data from the previous activity. Below are the details of the configuration.
Activity# 5: Write XML:
Below are the configuration details for this step.
Activity# 6: HTTP Send Response:
This is the last activity and in this one, we will send the response back. Below are the configuration details
We are done. The final Orchestration looks like -

Test the Integration -
It's time to test the configuration. First we need to start the orchestration and we can do that from Orchestration | Start Orchestration.
Then let's call the HTTP post method as displayed below -
I have used a Chrome Extension named DHC for my testing. 
You can do HTTP POST by clicking on Tools | HTTP Post Utility.
Below is the response I am getting back -
In Salesforce also, records are created.

GREAT!!!
If you follow the steps mentioned earlier, you will be able to configure the integration very easily. Please let me know if you need any details. Thanks.

Share:

Follow Me

Enter your email address:

Delivered by FeedBurner

Popular Posts

Labels

Salesforce (105) Apex (44) admin (27) ADM (20) visualforce (20) dev 501 (19) integration (18) learn salesforce (18) 501 (16) SOAP (13) lightning (12) tutorial (11) Certification. (9) javascript (8) Trigger (7) test class (7) unit testing (7) Sharing and Visibility (6) design pattern (6) report (6) security (6) trailhead (6) Advanced Admin (5) Certification (5) Kitchener Developer Group (5) New Features (5) SOQL (5) css (5) dashboard (5) debug (5) developer (5) formula (5) mobile (5) salesforce release (5) service cloud (5) solution management (5) use case (5) JSON (4) Lightning Experience (4) Salesforce DX (4) WebSphere (4) best practice (4) cast iron (4) component (4) deployment (4) github (4) html (4) polymer (4) profiles (4) responsive (4) tdd (4) ui (4) Advanced Apex (3) Architect (3) Live Chat (3) Online Event (3) Performance (3) Products (3) Role (3) Sales Cloud (3) Scratch Org (3) Study Notes. (3) Summer15 (3) Tips (3) Web Technology (3) dynamic apex (3) event (3) license (3) map (3) mapbox (3) singleton (3) version controlling (3) Bulkify (2) Data Architecture and Management Certification (2) Devops (2) Distributed Version Controlling (2) ES6 (2) Eclipse (2) Einstein (2) Enterprise Territory Management (2) Financial Services Cloud (2) Force.com IDE (2) Governor Limit (2) Groups (2) IBM (2) Implicit Sharing (2) JourneyToCTA (2) Kitchener User Group (2) Lightning Design System (2) Live Agent (2) Metadata (2) Opportunity (2) Price Book (2) REST (2) SOSL (2) Sharing (2) Spring 15 (2) Summer17 (2) Territory (2) ant (2) automation tool (2) basic (2) chatter (2) coding (2) communication (2) console (2) controller (2) documentation (2) flow (2) git (2) jquery (2) logging (2) object (2) permission (2) process builder (2) release (2) salesforce1 (2) strategy (2) xml (2) Action Plan (1) Action Plan Template (1) Agent Productivity (1) Analytics (1) Apex Sharing (1) Arrow (1) Asynchronous callout (1) Aura Framework (1) Bots (1) Browser (1) Bulk data load (1) CTA (1) Calendar (1) Canon (1) Case Management (1) Cheat Sheet (1) Classic (1) Community (1) Constructor (1) Contact Center (1) Continuation (1) Continuous Integration (1) Convert (1) Cookie (1) Custom Metadata (1) Custom Object (1) Customer (1) Decorator Design Pattern (1) Dev Hub (1) Diwali (1) Email (1) FSC (1) Function (1) Goals (1) Guide (1) Household (1) Ideas (1) Improvement (1) KPIs (1) Large Data Volume (1) LastModifiedDate (1) Lightning Web Component (1) Manual Sharing (1) Metrics (1) New (1) OOPS (1) OWD (1) Omni-Channel (1) Partner (1) Person Account (1) Photo (1) Pipeline (1) Platform Developer I (1) Presentation (1) Product Schedule (1) Profile (1) Promise (1) Prototype (1) Public Site (1) Query Plan (1) QuickReference (1) Reports (1) Retrieve (1) Role Hierarchy (1) SFDX (1) Salesforce Optimizer (1) Session (1) Sharing Rule (1) Sharing Sets (1) Site (1) Skills (1) Snap-ins (1) Spring 17 (1) Summer14 (1) Summer16 (1) Switch (1) SystemModStamp (1) User License (1) Users (1) Webservice (1) Winter'15 (1) Winter'17 (1) access (1) agile (1) app (1) approval process (1) aura (1) awesome (1) backup (1) bitbucket (1) book (1) campaign (1) change set (1) code (1) code coverage (1) configuration (1) csv (1) custom button (1) custom settings (1) customization (1) data loader (1) database (1) delegate Admin (1) describe (1) dom (1) dreamforce (1) duplicate (1) dynamic (1) equals (1) error (1) field-level security (1) folder (1) ftp (1) generic (1) gift (1) global describe (1) hashcode (1) import wizard (1) jenkins (1) keynote (1) long running requests (1) monitoring (1) mysql (1) page layout (1) personal (1) power of one (1) record type (1) relationship (1) request (1) review (1) sub-tab (1) tab (1) username (1) visual workflow (1) workflow (1)

Total Subscribers

Total Pageviews