Continuous Integration (CI) in Salesforce using Team Foundation Server (TFS) – Video

Step by step guide to set up Continuous Integration (CI) for Salesforce using Team Foundation Server (TFS) with video tutorial

I have already written some Continuous Integration (CI) posts for Salesforce previously using different tools like Jenkins. In this blog post we will go through steps to use Microsoft Team Foundation Server (TFS) to set up Continuous Integration.

We can either use cloud based Team foundation Server (TFS) or locally installed on network. For ease, we would be using cloud based TFS for this blog post.

Step 1: Creating developer account on VisualStudio Online

Navigate to https://www.visualstudio.com/ and choose Get Started for free in Visual Studio Team Services section. You may need to create a new Microsoft developer account, if you don’t have it already.

Step 2: Using TFS as source code repository

Once we are able to login to TFS, lets start by creating a code repository. That’s right, you don’t need separate Bitbucket or Github account to save your code/metadata unlike in Jenkins. So, our start with TFS is really good and impressive till this point 🙂 . Wizard to create new project is self explanatory and would look like below image

Visual Studio Team Foundation Server - New Project Screen
Visual Studio Team Foundation Server – New Project Screen

Once new Project is created in Team Foundation Server, we can use any git client, like tortoise git to save code. For authentication purpose, we can either use normal username password flow or generate SSH key and use that key for authentication. This youtube video or blog post will help you to generate SSH key, if its something new to you. Once key is generated, we would need to save it on TFS so that it can validate authenticity of user.

If you think you are little bit lost here, don’t worry :). I have posted video as well at the end of this blog post, showcasing everything in detail.

Step 3 : Create & test ANT deployment script on local system

If you have visited this article, chances are high that you are well aware about ANT script to deploy metadata into Salesforce. If not, no worries, I got you covered here as well. This blog post will serve a purpose of guide and key to fantasy world of ANT migration toolkit.

Lets create a build.properties file, which will have all of your credentials and important information about deployment

build.properties

# build.properties 
sfSandbox.serverurl = https://test.salesforce.com
sfPRO.serverurl = https://login.salesforce.com

sfdc.cb.df14.username=Salesforceusername
sfdc.cb.df14.password=Salesforcepassword
sfdc.cb.df14.retrieveTarget=src
sfdc.cb.df14.unpackaged=src\\package.xml
sfdc.cb.df14.retrieveMessage = Script to retrieve metadata from Salesforce

sfdc.cb.df15.username=Salesforceusername
sfdc.cb.df15.password=Salesforcepassword
sfdc.cb.df15.retrieveTarget=src
sfdc.cb.df15.unpackaged=src\\package.xml
sfdc.cb.df15.retrieveMessage = Script to retrieve metadata from Salesforce


sfdcJarFile=ant-salesforce.jar 

build.xml

<project name="Deployment Scripts" default="deploy" basedir="." xmlns:sf="antlib:com.salesforce">
 	   
    <property file="build.properties"/>  
	
	<target name="df14"> 	
	<taskdef resource="com/salesforce/antlib.xml" uri="antlib:com.salesforce" classpath="${sfdcJarFile}"/>
				
		<echo message="${sfdc.cb.df14.username}"/> 
		<sf:retrieve username="${sfdc.cb.df14.username}" password="${sfdc.cb.df14.password}" serverurl="${sfPRO.serverurl}" retrieveTarget="${sfdc.cb.df14.retrieveTarget}" unpackaged="${sfdc.cb.df14.unpackaged}" /> 
	</target>  
	
	<target name="deploy">
	<taskdef resource="com/salesforce/antlib.xml" uri="antlib:com.salesforce" classpath="${sfdcJarFile}"/>
				
		<sf:deploy username="${sfdc.cb.df15.username}" password="${sfdc.cb.df15.password}" serverurl="${sfPRO.serverurl}" deployRoot="src" maxPoll="1000" testLevel="NoTestRun" checkOnly="false" pollWaitMillis="10000" rollbackOnError="true"/>
	</target> 
	
</project>

Important difference to notice above is that how Salesforce jar is referred. In some situations where we have access to system, we simply put address of jar file of Salesforce migration toolkit in classpath. However in this scenario, as we are using cloud based solution for Continuous Integration, we need to refer jar file location relative to code base. Therefore while pushing build.properties and build.xml as a code in git, we would need to push ant-salesforce.jar file as well.

Once all above settings are in place, try to run command

ANT df14 deploy

Target df14 will retrieve source code from one Salesforce instance and would deploy same code to df15 instance in our example.

Step 4 : New Build definition in Team Foundation Server

In this step, we will create New build definition informing TFS which ANT target to invoke.

Navigate to Build & Release | New definition | Build | Ant

Team Foundation Server (TFS) - New Build definition
Team Foundation Server (TFS) – New Build definition

In next screen, we would need to select repository. It has few options like Github, some remote Git repository or SVN. As we have already created Git project in TFS itself, we have selected that. Next option we have is to choose a Git branch. It is possible that we need nightly build on one branch and hourly build on some other code base branch. So to address these kind of situation, we can have multiple builds in same project with different branches.

Team Foundation Server (TFS) - New Build definition - Select repository
Team Foundation Server (TFS) – New Build definition – Select repository

Next screen would be to add build steps of ANT. In our example, we have already specified default target however you can add ANT target depending on requirements. Once we save below screen, we are all set to test our Continuous Integration project using Microsoft’s Team Foundation Server.

Team Foundation Server (TFS) - New Build definition - add build steps
Team Foundation Server (TFS) – New Build definition – add build steps

Below video explains everything we discussed in this post. Please don’t forget to drop your feedback on this post.

Related posts