Archive | InBrief

Fun with the migration tool

Fun with the migration tool

If you haven’t used the 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 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 migration tool synonymously referred to as Ant. Getting your machine setup involves Java, the Ant build tool, and the migration tool jar. After you install all the prerequisites and get 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 

  • 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/

  • [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.

Retrieving the package.xml of a change set

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

Retrieving foldered metadata like reports

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.

  • Open and populate my credentials along with the path to my ant-salesforce.jar.
  • Open a terminal window and execute the script passing as a parameter the type of foldered metadata you want to retrieve [Report,EmailTemplate,Dashboard,Document
  • The script puts the passed in parameter $1 in the ‘which’ variable.

We define:

  • Which api version number to be used in scripts
  • tmpPkgXml: the file we will use to build our ultimate package.xml
  • buildFile: this will contain a target with all our bulkRetrieve commands to get the foldered
  • metadata
  • srcPath: the path where we will retrieve our metadata to
  • The line that starts with folders=( makes listMetadata call using the file get-folders.xml.

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.

Execute a shell script from an ant build.xml

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 migration tool, ant, and a shell script.   

Explore our latest perspectives