Share via


Versioning and Deploying Salesforce Metadata using TFS/VSTS

In this blog, I will show how you can use Visual Studio Team Services (VSTS) version control system to version control Salesforce.com Metadata.  I will also show how the Build feature in VSTS can enable you to deploy Salesforce Metadata from one Salesforce development instance to a Salesforce QA instance.  Finally, we will configure Continuous Integration (CI) so that each time you commit and push a change to a VSTS git repository, a build is triggered, which deploys to the Salesforce QA instance giving you immediate feedback on whether your changes broke anything in the Salesforce QA instance.

This walkthrough assumes some familiarity with Salesforce.com programming as well as git based version control system.  Also, we will use VSTS but most steps apply to TFS as well.  Note that you can get a VSTS account for free at https://www.visualstudio.com/products/visual-studio-team-services-vs

Before we start make sure your system has the following:

 

In this document we will go over the following:

  1. Create a Team Project in VSTS called MySalesforceApp
  2. Connect to MySalesforceApp from Eclipse IDE and clone the repository
  3. Create a Force.com project, connect it to the Salesforce development instance and retrieve its metadata
  4. Store the retrieved metadata in VSTS git version control system
  5. Set up a Continuous Integration build and deploy to the Salesforce QA instance
  6. Verify the CI behaves as expected

 

Create a Team Project in VSTS called MySalesforceApp

Login to your VSTS account if you already have one.  If not, create one here.  Once signed up, you can create a new Team Project by clicking “New”

test

 

Enter the Team Project name, select a Process Template and version control as shown below and then click “Create Project”

2_TP_create_dialog

 

Connect to MySalesforceApp from Eclipse IDE and clone the repository

In Eclipse, change Perspective to  ‘’Team Foundation Server Exploring”.  If you don’t see that perspective, get this plugin

3_TFS_Perspective

 

Within Eclipse’s Team Explorer,  go to “Home” -> “Projects” -> “Connect to Team Projects…”

4_Eclipse project

 

5_Eclipse_Project

 

Click “Servers” and add your VSTS url and then click “OK”

 

6_Project_eclipse

 

Once server is added, you can click next.  You will be presented with a login page.  Enter your username and password.  Once authenticated, you will be presented with list of team projects.

Select the “MySalesforceApp” Team Project and then click “Finish”

7_Eclpise_Project 8_eclipse_project

 

In “Team Explorer “, click on “Git Repositories”, then right click on “MySalesforceApp” and click “Import Repository”

9_repos

 

Select “MySalesforceApp” repository and click “Next”

10_git_repo

 

Enter the clone parameters.  Take note of the location in which you are cloning the repository.  Make sure that this location is the same as the Eclipse Workspace location.  You will need to create the Salesforce project in same location

11_clone_params

 

Clicking “Next” would show the summary page.  You can click “Next” and then choose “Create generic Eclipse projects for selected folders”

12_project_impott

 

Click “Next” and then “Finish”

 

Create a Force.com project, connect it to the Salesforce development instance and retrieve its metadata

Before you create the “Force.com” project, make sure that Eclipse’s Workspace is at the same location as the location where the repository was copied in the previous step

To find the current Workspace location, go to “File” -> “Switch Workspace” -> “Other”.  The workspace should show

13_select_workspace

 

Let’s create the Force.com project.  In Eclipse, go to “Force.com” perspective

14_Open_persepective

 

Go to “File” -> “New” -> “Force.com Project”.

Enter the project info.  For “Project name” enter the same name as VSTS Team Project name (MySalesforceApp).  Also, you will need to enter your Salesforce.com org credentials.  Click “Next” and then click “Finish”.

15_create_force

 

Note: in some instances, a Security Token is required.  If you don’t enter one, you would get an error window along with the instructions on how to get a valid Security Token.

At this point, the project structure should look like this:

16_eclipse_prjct_structure

 

 

Store the retrieved metadata in VSTS git version control system

To store the code in VSTS git repo, you will need to commit the changes and push the branch to the remote repository in VSTS.  To commit the changes, you can either do so from the command line or from Eclipse by going to “Team Foundation Server Exploring” perspective and clicking “Git Repositories” and right clicking “MySalesforceApp” and selecting “Open”

17_tfs_exploring

Right click on the repo and select “Commit”

18_commit 19_initialCommit

 

Check all the files and then click “Commit and Push”.  This would add the project to the remote repository.

20_pushBranch

 

Click “Next” and then “Finish”.  At this point you should have the code pushed to the repository in VSTS.  To check that, login to VSTS and then go to the “Code” hub; there you can see the project we just pushed.

21_vsts_repo

 

 

 

Setup Continuous Integration build

Get the Force.com Migration Tool from Salesforce.  Login to Salesforce.com -> Setup -> Build -> Develop -> Tools.  This page contains a number of tools made available by Salesforce.com.

22_sf_tools

 

The tool we are interested in is “Force.com Migration Tool”.  Click on the link and the tool would download.  Once downloaded, unzip the file and copy “ant-salesforce.jar” file.

Create a folder called “deploy” inside the force.com project and paste the “ant-salesforce.jar” file into the “deploy” folder

Create “build.xml” file inside the “deploy“ folder and paste the following:

 <project name="Sample usage of Salesforce Ant tasks" default="deployCodeAndRunTests" basedir="." xmlns:sf="antlib:com.salesforce">

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

    <!-- Setting default value for username, password and session id properties to empty string 
         so unset values are treated as empty. Without this, ant expressions such as ${sf.username}
         will be treated literally.
    -->
    <condition property="sf.username" value=""> <not> <isset property="sf.username"/> </not> </condition>
    <condition property="sf.password" value=""> <not> <isset property="sf.password"/> </not> </condition>
    <condition property="sf.sessionId" value=""> <not> <isset property="sf.sessionId"/> </not> </condition>

    <taskdef resource="com/salesforce/antlib.xml" uri="antlib:com.salesforce">
        <classpath>
            <pathelement location="ant-salesforce.jar" />          
        </classpath>
    </taskdef>
          

    <!-- Deploy code and run tests.  If test fails, rollback deploy. -->
    <target name="deployCodeAndRunTests">
      <sf:deploy username="${sf.username}" password="${sf.password}" sessionId="${sf.sessionId}" serverurl="${sf.serverurl}" maxPoll="${sf.maxPoll}" deployRoot="..\src" testLevel="RunAllTestsInOrg" rollbackOnError="true" logType="Debugonly"/>
    </target>
        
</project>

 

Create “build.properties” inside the deploy folder and paste the following

 # build.properties
#

# Specify the login credentials for the desired Salesforce organization
sf.username = yourUser
sf.password = YouPasswordAndSecurityTokenWithNotingInBetween
#sf.sessionId = 
#sf.pkgName = 
#sf.zipFile = 
#sf.metadataType = 

# Use 'https://login.salesforce.com' for production or developer edition (the default if not specified).
# Use 'https://test.salesforce.com for sandbox.
sf.serverurl = https://login.salesforce.com

sf.maxPoll = 20
# If your network requires an HTTP proxy, see https://ant.apache.org/manual/proxy.html for configuration.
#

Make sure you enter the correct credential information for the Salesforce QA instance in the code above.

At this point your project structure should look like this

23_eclipse_force

 

Update the remote repository with our changes by committing and pushing to VSTS as shown earlier

24_commit_changes

 

Now your code in VSTS should look like this

25_vsts_repo

 

Now we can create a build in VSTS.

Go to “Build” hub in VSTS, and click the (+) icon to create a build

26_build_create

Click the option to start with empty template

27_select_template

 

Choose the defaults and then click create:

28_createNewBuild

 

Click "Add build step..." link

29_addBuildStep

Add “Ant” task

30_add_ant_task

 

Configure the task.  Go to “Ant Build File”

31_select_path

 

Uncheck “Publish to TFS/Team Services”

32_save_build_definition

 

In Triggers tab, make sure “Continuous Integration” is checked

33_save_Build

 

Click “Save” and name the build “CI Build”

To test the build, click on “Queue Build”

34_queueBuild

 

Click OK

35_QuereBuildOptions

 

Check the build log and ensure that it passed

36_buildLogs

 

 

 

Verify that CI behaves as expected

Create an Apex class along with its unit test in your Salesforce development instance.  Add a class called “Math” and add the following code:

 public with sharing class Math {
    public Math(){
    
    }
    
    public Integer add(Integer a, Integer b){
        return a+b;
    }
}

Add a test class called “MathTest” and add the following code:

 @isTest 
private class MathTest {

    static testMethod void addTest() {
       Math m = new Math();
       Integer result = m.add(4, 5);
       System.assertEquals(result, 9);
    }

}

 

Once you add the code to Salesforce, import the changes to Eclipse by right click on “src” then “Force.com” then choose “Refresh from Server”

37_refresh_fromServer

 

Once done, commit and push.  This should trigger the build.

38_commit_changes

 

To verify the build has been triggered, login to VSTS and go to the “Build” hub, click on “CI Build” then click on Queued tab.  If you don’t see anything in the list, there is a good chance that the build has already completed.  You can check completed builds by clicking on “Completed” tab

39_verifyBuildTriggered

 

This would deploy code to the Salesforce QA instance.  To check the status in Salesforce, login to Salesforce, then go to “Setup” and then “Monitor” then “Deployment Status”

40_sf_deployResults

 

Let’s simulate a deploy failure by intentionally making the test case fail.  In your Salesforce development instance, replace the code inside MathTest with this

 @isTest 
private class MathTest {

    static testMethod void addTest() {
       Math m = new Math();
       Integer result = m.add(4, 5);
       System.assertEquals(result, 10);
    }

}

 

Commit and push.

41_vsts_buildFail

 

Checking the deploy status in Salesforce QA instance

42_sf_deploty_fail

 

Also, if you go to the code, you will notice that the change made in development instance was not deployed to the QA instance.  We have just implemented CI for Salesforce metadata using VSTS.

We just showed how you can store Salesforce Metadata in VSTS git repository.  We also showed how to setup Continuous Integration and deploy Salesforce Metadata to a QA environment.   Please leave us your feedback.

Comments

  • Anonymous
    September 16, 2016
    Very usefull thanks for the effort. Quick question: Works well for a complete metadata deployment. Is it possibleto do a partial deployment somehow?Much appreciatedMusa
    • Anonymous
      November 29, 2016
      Keep in mind that this is using the Migration Tool from Salesforce.com. If the Migration Tool allows it then you should be able to plug it in in your CD/CI pipeline.
  • Anonymous
    November 08, 2016
    Hi,When I am creating project in force.com it is saying project name should be unique.Can you please help me out.RegardsSampath
  • Anonymous
    November 29, 2016
    HelloThank you very much for your post. It's really great. Well detailed and really helpfulI have a weird issue that maybe has happened to you before. The deployment is triggered but when it's finished it's not refreshed in the console (even if it's successful) and then it reaches the timeout of TFS and mark it as failed. Do you happen to know why would this happen?Thanks in advance for your kind answer
    • Anonymous
      November 29, 2016
      No I have never seen this. Are you using your own agent or the hosted agent? If you are using the hosted agent I would try to deploy your own agent and use it and see if that helps. Follow this resource for details:https://www.visualstudio.com/en-us/docs/build/admin/agents/v2-windows
  • Anonymous
    November 29, 2016
    HelloThank you very much for your post. It's really great. Well detailed and really helpfulI have a weird issue that maybe has happened to you before. The deployment is triggered but when it's finished it's not refreshed in the console (even if it's successful) and then it reaches the timeout of TFS and mark it as failed. Do you happen to know why would this happen?Thanks in advance for your kind answer
    • Anonymous
      November 29, 2016
      Same as above
  • Anonymous
    December 06, 2016
    Really, this is a great post !! Today, I have learned something new. I would like to say a big thank for the detailed and explanatory information.
  • Anonymous
    April 10, 2017
    Can you please help me understand how can we achieve CODE QUALITY with this CI approach?Thanks in advance.
    • Anonymous
      April 10, 2017
      The comment has been removed
  • Anonymous
    May 15, 2017
    Many Thanks for the useful information!!.Facing issue on configuring the VSO. I cannot create VSO and Salesforce project with the same name. Is there any work around or i am missing something. Much Appreciated!Thanks