Using ant for dynamic deployments

The Migration Tool performs the deployment of metadata from one org to another using Apache Ant and custom tasks defined by the tool.  The custom tasks have many different parameters that give developers the flexibility to configure their deployments in different ways. In this post, I look at a way to use the sf:deploy task to deploy components in a dynamic way.

Typical Scenario

One way to deploy using ant is to build up a package.xml manifest file that specifies the components that will be deployed. You might first use an sf:retrieve task to retrieve the components specified in the package.xml from a source org and then deploy them to a target org. Alternatively, you might retrieve the source from your version control system and deploy it to a target org (commonly done with continuous integration, for example).  These are typical use cases that work well, but what if you need to make some changes after you’ve retrieved the source components, but before you deploy it to the target org?

Adding in a Build Step

You can specify a deployRoot in the sf:deploy which will deploy all components in the specified directory. For example, for deploying a project it would be the src directory and specifying that would deploy everything that you have specified in the package.xml at src/package.xml.

However, if you need to make some modifications to what is being deployed prior to deploying you can add in a step to copy what you need to, to another directory (e.g., “build”) and then deploy from there.  For example, you may need to remove some XML elements from a .profile file.  Your deploy task would now be something like:

That’s gives you the added benefit of being able to clean certain things up and/or make changes dynamically prior to deploying, but what if you want to change what it is that you are actually deploying?

Selectively Deploying

As I stated in the typical deployment scenarios, a package.xml manifest file specifies which files should be deployed. Now that you have the build source in a different directory, you can use various techniques to alter or generate a package.xml that has the correct entries you want in it. For example, if you wanted to deploy all Apex classes you could generate a package.xml file that has the following entry.

There is another way that you can change what it is that is being deployed. In the step where you copy from the src to the build directory, a filter can be added to the ant copy task to selectively include or exclude certain files. For example, you might want to copy all components that start with myAspect (e.g., MyAspect.cls, myAspect.component, etc.). For this, the copyToBuildSrc task becomes more than just a simple copy.

To generalize that task a bit, we could change the filter to be a property (really we should change all parts — e.g., todir, etc. — to be properties, but KISS for the example). We could also add an excludes.

How to generate the package.xml when the includes or excludes could be anything? The lesser known autoUpdatePackage parameter of the sf:deploy task allows you to deploy components regardless of whether they are in the package.xml or not. Add in another step to generate an empty package.xml file (generateEmptyPackageXml task body not shown in this post) and change the sf:deploy task to have autoUpdatePackage=true.

It should be noted that the autoUpdatePackage parameter comes with a statement in the documentation that it should not be used to deploy to production, so if you use it, you may want to limit it to your own controlled development-related orgs and be sure you know what you are doing.


Leave a Reply

Your email address will not be published. Required fields are marked *