A version control system can be an invaluable tool in enabling productive team development and release management. Force.com allows easy integration with such external tools (version control systems, IDE & scripting tools) to facilitate the development and deployment of applications in the cloud.
The power of Force.com lies in the fact that traditional development tools and processes can easily be incorporated into your process for developing Force.com applications, thus reducing the learning curve as well as leveraging industry best practices. In this short tutorial we will show you how you can start using Subversion, a free, open source version control system with Force.com to enable team development.
Two developers, Harry and Sally, need to collaborate to develop the business and testing logic for the Mileage example from the Force.com Workbook. Though we recommend that you take a quick look at the example and the code, understanding the code is not required to follow along. This tutorial shows how Harry and Sally can interface and develop as a team by using a code repository.
The structure of the tutorial is as follows:
Finally, the tutorial provides a little background information on metadata, and a number of resources to get you going.
We're going to be using Subversion as our source code repository. Subversion has both a server and clients. In this section we'll look at setting up the server. You would typically use a single Subversion server. In our case, Harry and Sally will be connecting to this single shared repository using their own Subversion clients.
As an alternative to managing your own SVN server there are a number of preconfigured online subversion services like ProjectLocker which allow you to keep your source code management in the cloud.
If you're using OS X, subversion is already installed.
The repository stores the files that are under the control of the version control system.
> svnadmin create c:\software\svn-test\repos
Go to c:\software\svn-test\repos\conf and uncomment the following lines in svnserve.conf in the [general] section of the file.
[general] anon-access = read auth-access = write password-db = passwd
In the same folder, open the file called passwd and uncomment the two lines as shown below
[users] harry = harryssecret sally = sallyssecret
Open a command prompt window and type in the command below to
> svnserve --daemon --root "c:\software\svn-test\repos"
Open a second command prompt window and type the following
> svn mkdir -m "Directory created for Mileage project" svn://localhost/mileage
The default admin password is blank so just hit return. For a given project, it is a common practice to create child directories to hold the main line of development, branch copies and the tag directories. By convention these are called trunk, branches and tags respectively. Let's go ahead and create them as shown below. We will only be working on the main line in this example.
> svn mkdir -m "Trunk" svn://localhost/mileage/trunk > svn mkdir -m "Branches" svn://localhost/mileage/branches > svn mkdir -m "Tags" svn://localhost/mileage/tags // After the successful execution of each of these command // you should see a message "Committed revision n". // You can list all the directories created with the list command > svn list svn://localhost/mileage branches/ tags/ trunk/
Now that you have set up a Subversion server, let's look at the development environments for Harry and Sally.
Both Harry and Sally should have their own org to build and test against. Either a Developer Edition or Developer Sandbox can be used for this purpose - see An Introduction to Environments to learn more about environments. We use Developer Edition (DE) orgs in this tutorial.
Each developer machine should also have a copy of the Force.com Migration tool. The Force.com Migration Guide referenced on this page has detailed installation instructions. Sample files required for the scenario is attached Migration-tool-files.zip. There are three files in this download -
build.properties that has the connection information (username and password),
build.xml which has custom Ant tasks and
package.xml that lists the components that will be retrieved and deployed. The
build.properties file should be updated for each developers environment - in particular you'll need to set up the authentication details for the orgs. So Harry and Sally would change it to point to their own DE orgs. Finally, you would need the Subversion client on each of the developer machines.
The logical structure is depicted in the following figure.
For the rest of this tutorial we're going to use a
svn application from the command line. We got this application by installing a Subversion client. In fact, if you install the Subversion server, you get the client installed as well. Typically however, you will run the clients on each developer's machine, and the server on another. See the Additional Resources section below for more pointers to Subversion clients.
With Subversion installed and the developer's individual environments, we are ready to begin developing code. We will assume that Harry and Sally use their own favorite Force.com tool or even just a text editor to actually write the code. We will focus on getting the code into Subversion and deploying it in their org. Here's a typical team interaction:
> ant retrieveCode
In terms of the metadata files, the above object and classes will be found in the files Mileage__c.object, MileageUtil.cls, MileageTrackerTestSuite.cls, and MileageTrigger.trigger - available in the data retrieved using the Ant task.
> svn import temp svn://localhost/mileage/trunk -m "Initial import"
The initial set of files that was retrieved into the temp directory by the Ant command can now be deleted - they're now all in the repository.
> svn checkout svn://localhost/mileage/trunk // You will see a message similar to below A trunk\triggers A trunk\triggers\MileageTrigger.trigger A trunk\triggers\MileageTrigger.trigger-meta.xml A trunk\objects A trunk\objects\Mileage__c.object A trunk\package.xml A trunk\classes A trunk\classes\MileageUtil.cls A trunk\classes\MileageUtil.cls-meta.xml A trunk\classes\MileageTrackerTestSuite.cls A trunk\classes\MileageTrackerTestSuite.cls-meta.xml Checked out revision 5.
> svn checkout svn://localhost/mileage/trunk // Message similar to above should appear
Now Sally has a local copy of the source code under Subversion control, just like Harry.
> ant deployCode
Now Harry and Sally have the same code running in their own individual DE orgs. They also have local copies of that code retrieved from the shared Subversion server.
// find difference between local copy and the one in the repository svn diff MileageUtil.cls // Harry is satisfied so he updates the repository. // The update will tell us if there are any conflicts > svn update MileageUtil.cls // There are none in this case so he can commit it. The changes // are now visible in the repository. > svn commit -m "Coded the business logic" MileageUtil.cls
> svn update MileageUtil.cls // Conflict detected - choose (e) Conflict discovered in 'MileageUtil.cls'. Select: (p) postpone, (df) diff-full, (e) edit, (mc) mine-conflict, (tc) theirs-conflict, (s) show all options: e // The file is opened in an editor. Delete the version you don't need and save the file // Then select (r) to resolve the conflict Select: (p) postpone, (df) diff-full, (e) edit, (r) resolved, (mc) mine-conflict, (tc) theirs-conflict, (s) show all options: r G MileageUtil.cls Updated to revision 7. // Now commit the change > svn commit -m "Changed daily mileage limit - 300 to 500 miles per day" MileageUtil.cls
> svn update MileageTrackerTestSuite.cls > svn commit -m "Unit tests for MileageUtil" MileageTrackerTestSuite.cls
Note the merge process - Subversion uses a versioning model call Copy-Modify-Merge that allows developers to simultaneously work on the same file by requiring the developers to manually merge any changes which can't be figured out by syntactical merging. A common practice is to branch of a main line of development (trunks and branches) and merge changes on a periodic basis.
The version control system thus becomes the single source of truth since all code sharing between the developers take place only through check in and checkout from the repository. Notice how much superior it is to ad-hoc sharing - now we can track who made what change when and even revert back to an older version if needed. If you have used version control system before the work cycle implied above should be very familiar. This highlights a benefit of Force.com we mentioned earlier, easy integration into your existing development practices. The only difference is that instead of compiling and executing the code on our local machine we deploy it to an org where these activities can take place. The Force.com Migration tool bridges the environment on the developer machine to their org environment.
After the development is done, the code can then be pushed to something like a full copy Sandbox environment (see An Introduction to Environments) for further testing (integration testing, user acceptance testing and so on). The process is similar - check out the code from Subversion and deploy into Sandbox. See the figure below. The promotion from full copy Sandbox to production is similar. Since the version control system is our definitive and single source of truth for all our code, we can be confident that we are promoting the correct code.
Here, we have a staging machine. Logically, you'd typically have this to serve as the conduit to the production or testing environment. In reality, it could simply be Harry or Sally's machine - whoever has the rights to push stuff to production.
The Force.com Migration Tool provided the bridge between the code in an org running in the cloud, and the developer machine with the Subversion repository. The files deployed to, or retrieved from, an org are driven by the package.xml file, as we saw in our sample above. (See the references below on the metadata API to learn more about this file). Notice that, in addition to each source code file, the retrieve task also retrieves another XML file e.g. MileageUtil.cls-meta.xml. This XML document is the metadata associated with the class file MileageUtil.cls. All components on Force.com have associated metadata and for some components there is no 'code' - it is all metadata.
The Force.com Metadata API is in fact a SOAP-based web sevices - and it provides commands to retrieve and deploy metadata. The migration tool we have been using is a simple client built on top of that API. Retrieve and deploy are atomic operations, and the content of each call is driven by the associated package.xml manifest file.
Though the Force.com IDE provides a rich environment for editing Apex code and Visualforce pages, it can be awkward to directly edit other XML metadata files. In this case Force.com (see An Introduction to Point-and-Click App Building with Force.com) with its GUI tools provides the best environment to build and change things, while the Metadata API/migration tool provides the mechanism to move changes from one org to another or to a version control system.
At this time some amount of manual configuration is still needed in the target org, because the Metadata API does not expose every bit of customization done in an org. Furthermore, there is a limit of 1500 components that can be retrieved or deployed in a single operation. If you have a larger number of components you will have to split it into batches.
Subversion (and almost all version control systems) is agnostic to what it stores - code, documents and even binary data can be stored and versioned. We highly recommend that you take advantage of this feature to store everything related to your project (components, migration tool files, client code, documentation etc.) into Subversion using scripting tools to make the process automated whenever possible.
Using a version control system as part of your development effort improves team productivity and makes your release management smoother and more predictable. This tutorial looks at using Subversion, a free, open source solution; but integration with other version control systems like CVS, VSS, etc. would work in a similar manner. These tools provide many more features than those covered in this article to help with development and release management, and should be part of every development project.
We used the command line tools to demonstrate the concepts and to show you how you can incorporate the migration tool and Subversion into your own scripts. There are many GUI tools available - Subclipse, a plug-in to Eclipse IDE and Tortoise SVN a Windows client are all worth checking out. This blog post shows how to use Subclipse with Force.com IDE.
Subversion is free and open source so you can install it at no cost, but that still leaves you with the hassle of configuring, maintaining, and backing up the software. Another popular option is to leverage a cloud-based version control provider.
Open source hosting sites like Google Code offer free version control repositories for open source projects, and are a good choice if you are not concerned about others viewing and using your code. See Developer Force's Code Share for many projects that use this kind of version control.
For commercial projects, there are many choices of paid providers. CollabNet maintains the Subversion open source project and has a large base of enterprise customers, but a quick search will turn up a large number of other options.
Nick Simha is a Partner Enablement Manager and Platform Evangelist working with Salesforce.com's consulting partners to help them build innovative cloud applications for our customers. He would like to thank Jon Plax, Jon Mountjoy and Jesse Lorenz for their insightful feedback on this article.