If you haven’t used the Force.com migration tool to move metadata from one org to another you are missing out. While there are several ways to move metadata between orgs the Force.com migration tool is powerful and a great addition to your Salesforce toolbelt. There are tons of resources to get you going. This one will get you a grasp of what you are working with and this has the list of metadata types you can retrieve and deploy. When working with Salesforce to migrate metadata the Force.com migration tool synonymously referred to as Ant. Getting your machine setup involves Java, the Ant build tool, and the Force.com migration tool jar. After you install all the prerequisites and get force.com migration tool working the TLDR main pieces are:
ant-salesforce.jar: allows you to use ant to interact with the Salesforce metadata API
Every release has a new version which relates to the release API
build.properties: your credentials and login endpoints
build.xml: the commands[targets] you can run
package.xml: your list of metadata to retrieve or deploy
destructiveChanges.xml: remove metadata from your org, separate from deploy
destructiveChangesPre.xml: remove metadata before your package deploys
destructiveChangesPost.xml: remove metadata after your package deploys
As you work with retrieving and deploying metadata you will find and possibly build a few things that are a little less used but still certainly useful. A few I’m going to talk about here are:
listMetadata
Retrieving the package.xml of a change set
Retrieving foldered metadata like reports
Execute a shell script from an ant build.xml
There may be several ways to get this kind of information but this can be another tool you put in your tool box.
After you’ve used the retrieve and deploy tasks, which you will use a lot, look at the readme for some other less commonly used but powerful tasks like listMetadata.
I used listMetadata this week to get a specific list of CustomMetadata. I entered the metadataType as CustomMetadata in my build.xml for the target listMetadata.
From the command line I executed that target
$ ant listMetadata
Which gave me an output listing all the CustomMetadata in my org with the following format
sf:listMetadata] FileName: customMetadata/Mapping.Education_Call.md
[sf:listMetadata] FullName/Id: Mapping.Education_Call/m02c00000007XyOAAU
[sf:listMetadata] Manageable State: unmanaged
[sf:listMetadata] Namespace Prefix: null
[sf:listMetadata] Created By (Name/Id): David Meyer/00541000002a2BUAAY
[sf:listMetadata] Last Modified By (Name/Id): David Meyer/00541000002a2BUAAY
I used that to filter what I was looking for and output only the Names I was interested in. I’ve found this useful to quickly get a list of metadata to include in my package.xml Sometimes the member names are not straightforward with some characters needing to be encoded in your package.xml
listMetadata is quick way to get exactly that, lists of different metadata types in your org which you can use in a variety of ways. Share with your friends, build into scripts, whatever you like.
You may have some colleagues that put together a massive change set to move from one org to another and now you want to move that same stuff from the org it was moved to on to a third org. Instead of rebuilding a change set you can get the content of that change set. The package.xml that could be used as well as the current state of the metadata associated to that package.xml
Get the name of your Change Set
Create a target in your build.xml that creates a directory and retrieves the Named Package
Execute your target from the command line
Which will retrieve a package.xml and the metadata listed in the Change Set
Looking at the metadata types you can retrieve you will notice some are allowed to be retrieved with a wildcard, ApexClass, and others have to be explicitly listed, CustomLabel.
Others like reports need even more detail. The name of the report and the name of the folder.
The challenge is to get the reports and the folders.
On my Mac I am going to use a shell script, some templates, the listMetadata task, and a bulkRetrieve task to retrieve all the report folders and the reports they contain.
We’ll use listMetadata to retrieve all the report folders using the ReportFolder metadata type. Once we’ve got all the folders we’ll loop through that list using bulkRetrieve to get all the reports in that folder. Each call using bulkRetrieve generates a package.xml for that folder so after we’ve retrieved all the reports for all the folders we’ll traverse our foldered directories and build a package.xml that includes all the Reports/files.
You can find the code on github.
To get started, I navigate to the directory where my files are located.
We define:
The result of the call is that all the folders for the specified metadata type are stored as an array in ‘folders’
We iterate through the array, adding bulkRetrieve tasks for each folder to get-Reports.xml. Then we execute the target retrieveType we just built. Retrieving all the reports. Finally, we write the beginning of our final package.xml. Traverse all the files and write the members to our package.xml and close our package.
Now that we can run this shell script to get our metadata we may want to invoke it from an ant process. To do that we could add a target[run-getAllsh] to a build xml specifying the path to our script and the argument we've been passing [Report]. All good fun with the Force.com migration tool, ant, and a shell script.