As part of a controlled Meta Data API release and source control strategy it is important to understand how API versions influence working patterns, especially where teams of developers share source control repositories (Git or others) and deployments are performed using Ant scripts, Jenkins or other continuous integration tools.
This post considers how the Meta data API (referred to in this document as “the API”) versions affect this process and how it should be used in conjunction with a managed source control process (referred to in this document as “the Git Repo” but it applies to others as well).
Every time Salesforce releases a new application version, its API version is updated as well. At the time of writing we had just released Summer 2013, which introduced API version 28.
This API version means that when you deploy changes using the API (e.g. using the Eclipse Force.com IDE plugin) and use version 28, your target SFDC Org will deploy these changes with the logic it associates with that particular version of the MetaData API (28). So for example, version 28 introduces a new field on the object ApexPage called isConfirmationTokenRequired. If you try to upload an Apex Page which contains that field and you are trying to do so using API version 27, your deployment script will fail because that field is not known for that API Version. On the other hand, if you would upload the same file specifying API version 28, it would work fine.
A key principle to understand is that whilst SFDC may release version 28 of the API, the deployment logic associated with version 27 is still available for use as long as you force the API to use version 27. In Eclipse, using the Force.com IDE the version of the API being used is specified in the ./src/package.xml file. Open it in a text editor scroll to the bottom and you will find a line similar to:
It important to note that your version of Eclipse may not be able to deploy Meta Data files with an API version which is higher than the one supported by your Force.com IDE plug-in. So if you are using Eclipse with Force.com IDE version 27, you may not be able to deploy Meta Data files with API version 28. The latest version info on the Force.com IDE and how to upgrade can be found here.
This concept may lead to utter confusion and numerous errors if the teams are not consistent with which API version they are using.
Let’s look at an example:
- Mary is an Apex developer. She’s been using Eclipse for about 6 months and the Force.com IDE API version she is using in Eclipse (package.xml) is version 27.
- Bob joins the team – installs Eclipse, installs the force.com IDE and refreshes his environment from a recently released SFDC org which is running Summer 2013. His package.xml file will therefore contain API version 28.
- Mary and Bob are working on the same project and share the same Git Repo. Mary is working on an Apex Trigger: Account_Update whilst Bob is working on a trigger Contact_Update.
Let’s look at a few possible scenarios:
Bob and Mary keep their own system up to date using the Git Repo.
- Bob refreshes his eclipse project from the target SFDC Org.
- He’s using API version 28 so the Apex Pages he downloads will include the new isConfirmationTokenRequired field .
- He makes his code changes to the contact trigger and checks them into the Git Repo.
- Mary updates her (local) repository from this Git Repo, so downloading Bob’s Meta data which includes Apex Pages, including the field isConfirmationTokenRequired and the changes to Bob’s contact trigger.
- Mary makes some changes to her account trigger and checks them into Git.
- Mary tries to deploy changes to the target SFDC org using Eclipse, but they will fail because her system is configured to use API version 27. The target org will complain that the field isConfirmationTokenRequired she is trying to upload is not an acceptable Meta data field for this API version.
Bob and Mary keep their own system up to date by refreshing from the target org – not the Git Repo.
This scenario will lead to similar issues when Mary is the last person to check in her changes to the Git Repo as the Ant Script executing after that commit will pick up Mary’s API version (27) whilst also trying to deploy Bob’s changes which include the isConfirmationTokenRequired field which is unknown to that API version.
How to avoid these issues:
In the above scenarios the Git Repo will contain inconsistent versioning information where meta data for version 28 (isConfirmationTokenRequired) exists together with Mary’s (she was last..) package.xml file, which contains version 27. Clearly this is an undesirable situation which should be rectified as soon as possible. As a rule, the entire team (including none developers) sharing a source control repository have to use the same version of the Meta Data API throughout.
How to resolve these issues:
There are two obvious ways in which to resolve the issues in the above scenario:
- We make sure that Bob goes back to using version 27
- We make sure that Mary upgrades and starts using version 28
In the interest of progress and to avoid any backwards compatibility issues – I’m going to ignore the first option as it seems counterproductive to downgrade to an old version of the API!
So to get Mary in sync with Bob:
- Mary commits all her changes to the Git Repo
- Bob commits all his changes including his trigger Contact_Update to the source control system (so package.xml version is 28) – So make sure that the last person to commit to the Git Repo is the one with the target / new version of the API!
- Mary upgrades her Force.com IDE version in eclipse to version 28
- Mary pulls the latest version of source from the Source Control system
After this, Mary has:
- The latest version of the Force.com IDE
- The most up to date code from the source repository
At this stage Mary may want to consider the following optional steps:
- Upgrading the API version of the trigger she is working on to 28
- Running the Apex verification test to make sure that this upgrade was successful against the target org.
Introducing Julie – the System Administrator:
The above example will illustrate how Mary and Bob can jointly work together as developers on a project. There are however a number of other people (e.g. Julie) who may on a regular basis make declarative changes to the SFDC org. To ensure that the Git Repo contains all relevant components (including for example the workflow that Julie has created on the Accounts object) should end up in Git as well.
To ensure this happens, an agreed process needs to be in place where changes made by Julie (probably on a sandbox) are pulled from that org and are merged with the code that Bob and Mary are working on and are pushed back into the Git Repo.
Again – API versions need to be considered here as the API version used in the SFDC org Julie is working on (e.g. 28) has to correspond to the version of the API in Git and the Force.com IDE used to extract changes from the target org.
What about Ant?
The above scenario may lead to another issue. When Bob and Mary are both using version 28 of the API and they use the Ant (see doc here) ant-salesforce.jar file, they need to make sure that the version of ant-salesforce.jar is aware of Version 28. To do that – make sure that your Ant environment is upgraded to the latest jar version when it becomes available by downloading it from your target org as described in the above hyperlink.
Summarizing all of the above in a set of best practices in a source control / continuous integration environment – when a SFDC org is being upgraded to the next version of the API:
- Make sure the ant-salesforce.jar is updated to that version ASAP.
- Until the next version of the Force.com IDE is released (this may be after the org has been upgraded) ensure that your developers and source control repository do not reference this new API version.
- When the next version of the Force.com IDE is released, upgrade all developers to the latest version of the Force.com IDE and ensure that this new version is used throughout your team.
- Consider that config (declarative) changes are made in Salesforce by people outside of your development team, which you may want to manage in your source control system.