4

I'm using mdapi:deploy. How do I tell it to deploy ONLY the metadata is defined in my package.xml instead of all the metadata files on my local filesystem?

Ex package.xml:

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>MyObj__c</members>
        <name>CustomObject</name>
    </types>
    <version>43.0</version>
</Package>

When I run sfdx force:mdapi:deploy -u <me> -d ./metadata it tries to deploy metadata/objects/* and I get errors saying <object> not defined in package.xml

Why do I need to even have a package.xml if it is going to deploy everything specified in -d anyways...

UPDATE: I've made a tool to solve this problem. mdapi-smart-deploy. Would appreciate feedback. Note it is intended for non-production deploys (ex: sandbox).

UPDATE 2: I've abandoned my tool for now, in favor of Illuminated Cloud for IntelliJ. While I'm not a fan of IntelliJ, it solves all the problems discussed here (and more). I highly recommend.

5

The Metadata API expects a self-consistent package file set, meaning the package.xml and the metadata source are exactly aligned with one another. Salesforce DX's Metadata API commands aren't doing any special magic; it's zipping up that MDAPI source and package file and deploying it just like Ant or Workbench would. MDAPI is much older than Salesforce DX and in many ways a bit weird by the standards of modern deployment tools.

SFDX, when the force:source:convert command is issued, builds such a consistent MDAPI file set from the current DX project. If you want to deploy only a portion of your overall project, you can edit the package.xml and file tree to match, or break up your DX project into logically separate artifacts and convert them individually to MDAPI-deployable packages.

| improve this answer | |
  • 1
    Something I had discovered during one of the CI implementations. Had posted an idea to see if this behavior can be customized so that package.xml picks only what's defined in it instead of scanning the source folder. This would have been very helpful in case of delta deployments. – Jayant Das Jul 31 '18 at 0:32
  • Thanks David. I still don't understand the need for a package.xml if the metadata files are the source of truth. – rynop Jul 31 '18 at 0:58
  • @JayantDas I'm writing an OSS tool to fill the gap I'm looking for in this question. I'll post it back here when I'm done. – rynop Jul 31 '18 at 1:00
  • @rynop That sounds super useful. I'd like to see it too! – David Reed Jul 31 '18 at 1:01
  • @rynop That will be indeed helpful. – Jayant Das Jul 31 '18 at 1:26
2

The issue has to do with the tool you are using, rather than with the metadata api itself.

It is entirely possible to have a package that contains a definition of a custom object that is ignored on deployment if it isn't included in the package.xml file.

I believe the relevant setting in the deploy call is autoUpdatePackage. From the metadata api documentation:

If a file is in the .zip file but not specified in package.xml, specifies whether the file is automatically added to the package. A retrieve() is issued with the updated package.xml that includes the .zip file.

Do not set this argument for deployment to production orgs.


A simple deployment package with two new objects defined:

[martin@localhost Test-CreateObject]$ unzip -l package.zip 
Archive:  package.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  07-31-2018 09:49   objects/
      426  07-31-2018 09:49   objects/CreateMe_1__c.object
      426  07-31-2018 09:49   objects/CreateMe_2__c.object
      236  07-31-2018 09:40   package.xml
---------                     -------
     1088                     4 files

The contents of the files, showing the package manifest only lists one object:

[martin@localhost Test-CreateObject]$ cat package.xml objects/*
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>CreateMe_1__c</members>
        <name>CustomObject</name>
    </types>
    <version>37.0</version>
</Package>
<?xml version="1.0" encoding="UTF-8"?>
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
    <deploymentStatus>Deployed</deploymentStatus>
    <nameField>
        <label>CreateMe 1</label>
        <trackFeedHistory>false</trackFeedHistory>
        <trackHistory>false</trackHistory>
        <type>Text</type>
    </nameField>
    <label>CreateMe 1</label>
    <sharingModel>Private</sharingModel>
</CustomObject>
<?xml version="1.0" encoding="UTF-8"?>
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
    <deploymentStatus>Deployed</deploymentStatus>
    <nameField>
        <label>CreateMe 2</label>
        <trackFeedHistory>false</trackFeedHistory>
        <trackHistory>false</trackHistory>
        <type>Text</type>
    </nameField>
    <label>CreateMe 2</label>
    <sharingModel>Private</sharingModel>
</CustomObject>

The results of the deployment showing just one object created:

enter image description here

| improve this answer | |
  • Do you know if this deploy option was recently added? I don’t recollect if this was available earlier. – Jayant Das Jul 31 '18 at 3:21
  • It's been around for a few years. I don't have a specific api version at the moment though. – martin Jul 31 '18 at 3:30
  • Thanks. That’s interesting because I was in same situation few years back and that I recollect reaching out to support and was responded, that’s how it works by design. I had gone ahead posting an idea for this (link in one of the comments in David’s answer). Interestingly many of us really are not aware of this option. – Jayant Das Jul 31 '18 at 3:33
  • Yeah, It's there in the raw api, it just comes down to whether or not your tool supports it. I made my own thing a few years back because I was frustrated with ant. I haven't looked into the sfdx tool enough to know whether or not this option is something you can configure there. – martin Jul 31 '18 at 3:37
  • 1
    Your prob going to laugh, but after writing v1 of my tool, I ended up just using Illuminated Cloud, because dev'ing the last 10% of was going to take too much time. For others reading this, I would highly recommend Illuminated Cloud. I appreciate your post because it forced me to think hard about not re-inventing the wheel. – rynop Aug 3 '18 at 3:59
0

For those who is still not clear about autoUpdatePackage option, which I admittedly found quite confused before too.

autoUpdatePackage -> autoAddComponentsFromFilesToPackageXml

However, it does not handle auto removal components in your folder but not in package.xml. That means if you want to deploy a subset, you would have to go through your directory and remove the files manually.

Package.xml is almost useless when you set autoUpdatePackage = true & allowMissingFiles = true. The only critical value it brings, in this case, is the api version to deploy against.

| improve this answer | |
  • With the autoUpdatePackage value set to false, there should be no need to remove files at all. This flag signals to salesforce to ignore those components that are not listed in the package manifest. With the right tool, if you want to deploy a subset of files in a directory, you should just need to update the package.xml file to remove the metadata components you don't want to deploy. – martin Aug 27 '18 at 5:27
  • I actually tested this a number of times before and always ran into this error <object> not defined in package.xml even if I set autoUpdatePackage to false. @martin when was the last time you tried ? would be good to reconcile this so others won't have to guess ;) – Tam Aug 27 '18 at 6:21
  • Were you deploying a custom object, or something else, like an Apex class? – martin Aug 27 '18 at 6:38
  • I did custom object, field, validation rules, ... same scenario & error that @rynop mentioned in this thread. – Tam Aug 27 '18 at 7:01
  • It should work for custom objects. Although for sub-components that can be deployed explicitly like custom fields, validation rules, workflow rules/alerts/field-updates, and custom labels, they can't be ignored. Profiles and page layouts can be ignored though, probably since their sub-components can't be explicitly included in a package manifest. Static resources can be ignored since they are just singular components, although apex classes can't be ignored. – martin Aug 27 '18 at 7:07
0

I reduce the manual task of removing each component from the "src" which were not involved in the package.xml through a Java Program. Yes I know it's not a complete solution for now, but still. Go through the repo and let me know what further enhancements can be done in it.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.