forcedotcom / cli

Salesforce CLI
https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta/sfdx_cli_reference/
BSD 3-Clause "New" or "Revised" License
488 stars 78 forks source link

sfdx force:source:deploy with specified manifest having specific fields deploys everything in the local object folder #156

Closed dmgerow closed 3 years ago

dmgerow commented 5 years ago

Summary

When using the org development model, the salesforce cli will deploy the entire object file if you specify a package.xml specifying child components of that object (ValidationRule,CustomField,etc.).

Steps To Reproduce:

Scenario: You want to deploy a single custom field from your workspace (that is in dx format) to a Sandbox (org development model).

  1. You make a package.xml in the manifest folder named package.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>Account.MyCustomField__c</members>
        <name>CustomField</name>
    </types>
    <version>46.0</version>
    </Package>
  2. I then run the following command to deploy the custom field to the sandbox:

    sfdx force:source:deploy -u myuser@example.com  -x manifest/package.xml -w 10

Expected result

I would expect that the cli zips up that specific custom field and deploys it to the target org, with the below package.xml:

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>Account.MyCustomField__c</members>
        <name>CustomField</name>
    </types>
    <version>46.0</version>
</Package>

Actual result

The cli generates an object file with every single component in my local directory related to the custom object (fields, record types, etc.), and creates the following (incorrect) package.xml:

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
  <types>
    <name>CustomObject</name>
    <members>Account</members>
  </types>
  <types>
    <name>CompactLayout</name>
    <!-- all local account compact layouts -->
  </types>
  <types>
    <name>FieldSet</name>
    <!-- all local account field sets -->
  </types>
  <types>
    <name>CustomField</name>
    <!-- all local account custom fields -->
  </types>
  <types>
    <name>ListView</name>
    <!-- all local list views -->
  </types>
  <types>
    <name>RecordType</name>
    <!-- all local record types -->
  </types>
  <types>
    <name>ValidationRule</name>
    <!-- all local validation rules -->
  </types>
  <types>
    <!-- all local web links -->
    <name>WebLink</name>
  </types>
  <version>46.0</version>
</Package>

It then proceed to deploy all of that metadata instead of the single custom field that should have been deployed.

Additional information

The only workaround I have is to add all of the unwanted components to the forceIgnore file which is not reasonable for hundred to thousands of components when I want to deploy a single field.

SFDX CLI Version:

sfdx-cli/7.20.1-d88ae4707c darwin-x64 node-v10.15.3

SFDX plugin Version:

@oclif/plugin-commands 1.2.2 (core)
@oclif/plugin-help 2.2.1 (core)
@oclif/plugin-not-found 1.2.2 (core)
@oclif/plugin-plugins 1.7.8 (core)
@oclif/plugin-update 1.3.9 (core)
@oclif/plugin-warn-if-update-available 1.7.0 (core)
@oclif/plugin-which 1.0.3 (core)
@salesforce/sfdx-trust 3.0.5 (core)
analytics 1.2.1 (core)
generator 1.1.1 (core)
salesforcedx 46.10.2 (core)
├─ force-language-services 46.14.0 (core)
└─ salesforce-alm 46.13.0 (core)

sfdx-cli 7.20.1 (core)

OS and version:

ProductName:    Mac OS X
ProductVersion: 10.14.6
BuildVersion:   18G87
eric-bw commented 4 years ago

has anyone found a workaround? this seems to be saying that we shouldn't be using sfdx for deployments if we dont have fine grained control over object deployments.

JeffArwady commented 4 years ago

I have experienced this exact same thing. Hoping someone has a workaround other than using force:mdapi.

eric-bw commented 4 years ago

I have experienced this exact same thing. Hoping someone has a workaround other than using force:mdapi.

can we use mdapi with the source format? We're using sfdx with manifest at the moment so our format is all source. If we have to convert the source every time to deploy mdapi that would be a pretty janky workaround.

JeffArwady commented 4 years ago

The best workaround I have is this:

Using the same package.xml for source you can:

sfdx force:mdapi:retrieve -k package.xml -r deploy

then

sfdx force:mdapi:deploy -f deploy/unpackaged.zip

This will at least deploy only what you want. But yes, it would be better if we could just source.

dmgerow commented 4 years ago

My workaround is similar but on the retrieving end. I wrote a plugin that first wipes the object folders and then doest the force:source:retrieve. This way what is in your local is only what is in the package.xml.

Still not ideal but it is the best I have for now.

I wonder if we should open an issue with jsforce since that is what the plugin is using internally.

clairebianchi commented 4 years ago

Hi, can you provide more information on why you would only want only 1 custom object field instead of the full object and its fields? Just trying to get to the bottom of the use case.

eric-bw commented 4 years ago

A single field deployment can increase in scope to 400+ items because the full object is being included in the deployment. thats 399 possible points of failure that have nothing to do with the intent of the deployment.

this relates to deployments of additional fields after the initial deployment has been completed sometime in the past. Until that day that we can do bare-metal deployments to production we need to be able to incrementally deploy changes.

clairebianchi commented 4 years ago

@eric-bw Thank you! This is about both speed and decreasing the risk of the deployment

dmgerow commented 4 years ago

@clairebianchi more importantly, there are many times where you may have parallel projects going live at different times with some overlap on objects.

For example, if Team A is implementing a quoting solution and team B is implementing a field service solution, both teams will be adding or updating different metadata on the Account object. Rather than trying to merge every change that is introduced upstream in a QA environment which can be tedious with XML documents, we should be able to trust that if we specify a single CustomField to be deployed that the entire object is not deployed.

Since it is deploying more than what is specified in the package manifest, the release manager may be unknowingly overwriting a larger number of changes on the related object even though the manifest does not indicate it.

clairebianchi commented 4 years ago

@dmgerow, thank you, that is great feedback. I am adding a story to our backlog and when we get into planning after dreamforce I will see where it fits in.

payensa-sf commented 4 years ago

Hi @clairebianchi this behaviour should also apply to the command force:source:convert -x which is currently keeping the whole object in the target folder even when you only specified a single part of it. Thanks!

dmagyar-veeva commented 4 years ago

Hi @clairebianchi, as mentioned by @payensa-sf this also happens when using the convert command, so we're still using ant for packaging before committing it to source control. Thank you!

Update: Although we found a workaround, VSCode plugin: ForceCode

sauloefo commented 4 years ago

Hi @clairebianchi, I'd like to bring you an other user case: here in company we have a few custom fields for an object from a managed package. In this scenario, I want to deploy only my custom field. My work around today is simply keep this out of my automated deployment. :/ Cheers,

renanlq commented 4 years ago

We are facing the same issue, then we search for some plugins to help with managing our folders to keep on it only metadata that is in the manifesto.

Here it is one of them that we are testing: sfdx-essentials, then the option: filter-metadatas It creates another folder based on the manifesto, so that deploy only this content folder.

Hope Salesforce could provide some help and give some attention to it.

renanlq commented 4 years ago

Other good information based on documentation.

source:deploy

Parameters -x | --manifest MANIFEST Optional The complete path for the manifest (package.xml) file that specifies the components to deploy. If you specify this parameter, don’t specify --metadata or --sourcepath. Type: filepath

To deploy all components listed in a manifest: $ sfdx force:source:deploy -x path/to/package.xml

Based on that, think that our developers are able to believe that when we provide the manifest file on deploy command, only changes inside it will be considered on deploy.

cavery88 commented 4 years ago

I noticed this behavior recently as well and hope that it is fixed soon.

Until then, if you only need to deploy a few fields, one small work around is to right-click the individual field (or other object component) in the Explorer bar and select: SFDX: Deploy Source to Org (This is the same as sfdx force:source:deploy -p [path to item])

Both of these will deploy just the field (or item) selected and not the entire object.

I also noticed that when retrieving Custom Fields with the manifest from my dev sandbox, that CLI added a 'shell' metadata file for the parent object. Subsequently attempting to deploy this same manifest to our release sandbox resulted in an error because the shell metadata file for the parent object was incomplete. Manually deleting the shell file(s) allowed the custom fields to be deployed successfully using the manifest

ebtalley commented 4 years ago

I also noticed that when retrieving Custom Fields with the manifest from my dev sandbox, that CLI added a 'shell' metadata file for the parent object. Subsequently attempting to deploy this same manifest to our release sandbox resulted in an error because the shell metadata file for the parent object was incomplete. Manually deleting the shell file(s) allowed the custom fields to be deployed successfully using the manifest

We went this direction as well. the issue I run still is that sfdx requires the object definition still, if its incomplete or a standard object, you end up in a situation where you have to generate a fake object definition or try to grab a full source from somewhere. There seems to be a separate bug where retrieving an object will pull an incomplete object definition (missing label, name elements, etc).

Overall the need is about being able to deploy sub definitions (fields, validation rules) without needing any additional metadata as well as not deploying the whole object. The current workarounds have a number of pitfalls.

brandonstauber commented 4 years ago

I am experiencing the same issue using VSC/Bitbucket (with Pipelines). Of the solutions above, has anyone been able to effectively isolate only changes that have been explicitly listed in the package.xml? We do not want to deploy the entire object if only one field was updated.

Any help would be greatly appreciated!

RCMoonpie commented 4 years ago

I am sure everyone is aware, but I hate assumptions, so...

The same happens using the -m or --metadata option.

For example, I only had 7 metadata files in my local ...\objects\Case\ object subfolders, and when I ran this command,

sfdx force:source:deploy -m "WebLink:Case.Work_Complete" -u OrgAlias

it deployed my webLink, and it also deployed the other 6 metadata items (1 businessProcess, 2 fields, 1 recordType and 2 validationRules).

That complicated matters when I was trying to do a specific, targeted change in a sandbox, because I did not want those validation rules deployed. I had to then deactivate them.

No huge deal in this case (pun intended), but if I had a lot more metadata in my folders it would have been a big headache - either to deactivate or remove all that got accidentally deployed, or to have to create a new sandbox and re-do work there because this one got too kludgey.

rahulkapoor83 commented 3 years ago

ForceCode

Can you please provide details on how to use Forcecode to deploy package.xml

dmagyar-veeva commented 3 years ago

ForceCode

Can you please provide details on how to use Forcecode to deploy package.xml

Hey Rahul, We're using ForceCode only for packaging purposes, although I think it has deploy function: image from the ForceCode Menu: image

Otherwise we're using ANT Migration Toolkit to move stuff around, automated with Jenkins but there are many options.

dmgerow commented 3 years ago

@amphro this is still not completely fixed as noted in #654 since only the first field is being pushed

ravishankar-peri commented 3 years ago

I have a similar issue while deploying workflow rules/field updates/alerts.

qwikag commented 3 years ago

I encountered this error today and fixed by wrapping my manifest file path in double quotes. But I am using Git Bash as my terminal, so that is probably the spanner in the works.

@oclif/plugin-autocomplete 0.3.0 (core) @oclif/plugin-commands 1.3.0 (core) @oclif/plugin-help 3.2.2 (core) @oclif/plugin-not-found 1.2.4 (core) @oclif/plugin-plugins 1.10.0 (core) @oclif/plugin-update 1.4.0-2 (core) @oclif/plugin-warn-if-update-available 1.7.0 (core) @oclif/plugin-which 1.0.3 (core) @salesforce/sfdx-trust 3.6.0 (core) alias 1.1.8 (core) auth 1.4.10 (core) config 1.2.6 (core) generator 1.1.5 (core) salesforcedx 51.2.2 (core) ├─ limits 1.0.4 (core) ├─ schema 1.0.4 (core) ├─ user 1.1.2 (core) ├─ apex 0.1.4 (core) ├─ templates 51.3.0 (core) ├─ custom-metadata 1.0.11 (core) ├─ @salesforce/sfdx-plugin-lwc-test 0.1.7 (core) └─ salesforce-alm 51.2.1 (core) sfdx-cli 7.90.2 (core) telemetry 1.1.1 (core)

nvuillam commented 2 years ago

Still same problem here... I want to NOT deploy ListViews, and whereas is empty in my package.xml, they are all deployed with their parent object...

Package XML sample:

    <types>
        <members>Account</members>
        <name>CustomObject</name>
    </types>
    <types>
        <name>ListView</name>
    </types>

Sample of force:source:deploy result log

Account.ComptesFelix                                                         ListView                  force-app\main\default\objects\Account\listViews\ComptesFelix.listView-meta.xml
Account.Fournisseurs                                                         ListView                  force-app\main\default\objects\Account\listViews\Fournisseurs.listView-meta.xml
Account.MesComptes                                                           ListView                  force-app\main\default\objects\Account\listViews\MesComptes.listView-meta.xml
guiferbri commented 2 years ago

Hi @amphro , I have the same issue. I want to deploy only changes in Lead.object file (search layout changes) and changes in custom field in Lead object. When I execute deploy sfdx force:source:deploy -x "path/to/package.xml" all components in Lead object folder is deployed. I attach screenshot of package.xml file and deployment results:

image

This is a problem because when we deploy changes in next environment, we are modifying other components with older versions.

Could you help us? Thanks