Tweet |
Force CLI Part 4 - Deploying Metadata
Introduction
In previous posts in this series I’ve covered Getting Started, Extracting Metadata and Accessing Data via the Force CLI. In this post I’ll cover the functionality that I use probably 95% of the time that I use the Force CLI - deploying metadata from the local filesystem to a Salesforce instance.
The Building Blocks
Like other tools for deploying to Salesforce (e.g. migration tool, Eclipse IDE) there are a two items required to deploy via the Force CLI
Project Manifest (aka package.xml)
The package.xml file defines the metadata components that will be deployed - you can find out more about this in the Salesforce Metadata API Developer’s Guide.
Metadata Components
The metadata components need to appear in the directory structure expected by the metadata API - e.g. Apex classes in a directory named ‘classes’, Visualforce pages in a directory named ‘pages'
I don’t make the rules (but I do make the deployment directory)
The rule when deploying is that the components specified in the package.xml manifest file need to match those present in the metadata components directory structure. If you specify components that are missing you will get an error, and if you provide additional components that aren’t mentioned in the package.xml, you’ll get a different flavour of error.
My metadata comes from GIT, so the metadata components structure of my entire project is defined there. However, I don’t always want to carry out a full deployment so I create a new structure in a temporary directory and create a package.xml file reflecting that. I also use a naming convention for my temporary directory so that I can look back at the order that I did things in - drop_<YYYYMMDDhhmmss>, where YYYYMMDD is the year/month/day of the date and hmmss is the hours/minutes/seconds of the time. The reason I go with this naming convention is that when I use the ls command, my directories are listed in order of creation:
$ ls -l drwxr-xr-x 6 kbowden wheel 204 16 Sep 14:39 drop_20160916141152 drwxr-xr-x 6 kbowden wheel 204 17 Sep 10:11 drop_20160916184125 drwxr-xr-x 6 kbowden wheel 204 17 Sep 12:45 drop_20160917121232 drwxr-xr-x 6 kbowden wheel 204 18 Sep 12:56 drop_20160918092957 drwxr-xr-x 6 kbowden wheel 204 18 Sep 19:21 drop_20160918185148 drwxr-xr-x 6 kbowden wheel 204 20 Sep 15:39 drop_20160920152837
To use a very simple example, here’s the directory structure to deploy just the User object. My starting directory is /tmp/drop_20160923080432:
/tmp/drop_20160923080432/target/objects/User.object /tmp/drop_20160923080432/target/package.xml
My package.xml file just contains an entry to deploy the objects directly (it’s called CustomObject, but covers both standard and custom):
<?xml version="1.0" encoding="UTF-8"?> <Package xmlns="http://soap.sforce.com/2006/04/metadata"> <types> <members>*</members> <name>CustomObject</name> </types> <types> <members>*</members> <name>ApexPage</name> </types> <version>37.0</version> </Package>
Deploy all the Metadata
Once the directory structure and manifest are in place, use the force import command to deploy your metadata, using the -d switch to specify the directory containing the metadata:
force import -d /tmp/drop_20160923080432/target
The Force CLI will update you every five seconds on progress
Not done yet: Queued Will check again in five seconds. Not done yet: InProgress Will check again in five seconds. Not done yet: InProgress Will check again in five seconds. Not done yet: InProgress Will check again in five seconds. Not done yet: InProgress Will check again in five seconds. Not done yet: InProgress Will check again in five seconds.
Once the deployment is complete, you’ll get details of successes/failures - the default behaviour is simply the to output the number of each
Failures - 0 Successes - 24 Imported from /tmp/drop_20160923080432/target
While if you specify the -v switch, you'll get full details of each success/failure:
Successes - 24 User.DFP_Id__c status: unchanged id=00N80000005st6iEAA User.Default_Tab__c status: unchanged id=00N80000005st6kEAA User.Department__c status: unchanged id=00N80000005st6lEAA ...
Deploying to Production
As everyone in the Force.com world knows, in order to deploy metadata to production you need to run some unit tests. The Force CLI provides support for this via the -l switch, which takes the same options as the migration tool:
- NoTestRun
- RunSpecifiedTests
- RunLocalTests
- RunAllTestsInOrg
Verification Only
Another very useful switch is -c. This carries out a verification only deployment and rolls back all changes upon completion. I use this as part of our continuous integration environment to make sure I can successfully deploy to a clean development environment.