6

(Sorry, long post)

We have a team of 4 developers, each with their own DE org

We are struggling with propagating destructive changes between orgs. From our reading of the docs, we should be able to document the fields that are being destroyed in destructiveChanges.xml and that change should propagate to other orgs when the Ant deployment task is run. This works in the extremely limited use case of the thing you're destroying not being referenced by any other source files.

I have created a very bare bones hello-world example at:

https://github.com/daveespo/forcedotcom-destructivechanges

The scenario goes like this:

  • Developer 1 commits a new SObject along with a VF page that references a new field on that object 5d07044
  • Developer 2 updates his working copy, does an 'ant deploy' and now both Developer 1 and Developer 2's orgs are in sync. Great.
  • Developer 1 decides that one of the fields isn't necessary, or that the name is misleading so he wants to remove/change it. Developer 1 makes the changes in his org (adding the new field, destroying the old field, and fixing up the reference in the VF page). Additionally, he documents the destruction in destructiveChanges.xml 51ce0575
  • Developer 2 syncs up his working copy and tries to do an 'ant deploy'. Boom! dead in the water.

Output from build:

Buildfile: C:\Users\esposito\Documents\xx\workspace2\forcedotcom-destructivechanges\build.xml

deploy:
[sf:deploy] Request for a deploy submitted successfully.
[sf:deploy] Request Id for the current deploy task: 04si00000012BLSAA2
[sf:deploy] Waiting for server to finish processing the request...
[sf:deploy] Request Status: Completed

BUILD FAILED
C:\Users\esposito\Documents\xx\workspace2\forcedotcom-destructivechanges\build.xml:12: FAILURES:
Error: objects/Spatula__c.object(Spatula__c.Color__c):This custom field is referenced elsewhere in salesforce.com. : Visualforce Page - Spatula.


Total time: 11 seconds

It appears as though the application of the destructiveChanges.xml and the updated source file(s) called out in package.xml isn't an atomic operation.

How do other teams work through this problem? The simple examples I've seen of destructiveChanges.xml don't address the problem of source files referencing 'to be deleted' objects called out in destructiveChanges.xml

The non-workable workaround is to commit 3 times -- first, commit a change (breaking, of course) that dereferences the field to be destroyed, then commit a destructiveChanges.xml destroying the field, then commit the new field and restore all of the references to that new field. This requires the 'other team members' to very carefully sync up one commit at a time and apply them. Hardly friendly for devs that work on the project infrequently.

3
  • 2
    I would think you could do it in 2 commits: (1) dereference field to be deployed then (2) both destructiveChanges.xml and package.xml deployed. In terms of other teams working through this problem, keep developers in the same org if possible.
    – Phil Rymek
    Sep 16, 2013 at 19:56
  • Be warned having developers in the same DE org, will likely run into daily API limits (if your using Eclipse or other desktop tools). Sep 17, 2013 at 15:50
  • Back in the day, we used to have multiple devs in the same DE org but the number of accidental overwrites -- or the possibility of one dev breaking a core library call causing other devs to get stuck not knowing whether the bug was caused by them or someone else -- and lastly, when dealing with managed packages, it's super dangerous to have people coding directly in a packager DE org -- which is why we invested in scripted build and deployment. But we can't get past this really painful problem of propagating destructive changes.
    – daveespo
    Sep 17, 2013 at 16:16

2 Answers 2

3

Bottom line is cleaning DE orgs is problematic at best.

You do need to list all of your components in the destructiveChanges.xml file unfortunately. The platform will not implicitly delete references nor let you ignore them. There are also some bugs / features even if you do reference all the components.

The solution we have found is to develop a 'dynamic' solution around this process. Which as you say seeks out references and clears them via a deploy. We have shared this, based on a Dreamforce 2012 presentation here.

undeploy : used to remove all metadata from the org.

usage: ant undeploy

Note: This requires a customised ant-salesforce.jar, vote now to have Salesforce support this properly.

Note: Related is the fact that the current Salesforce Ant tool does not pass on the 'purgeOnDelete' setting the underlying Metadata API takes, to effectively clear your waste bin of metadata. This is critical if you want to redeploy a new build. See this idea here to have this supported, until then a custom ant-salesforce.jar is needed.

2
  • 1
    Ha! I attended the session at DF (and it inspired me to actually implement scripted build) and have tried to implement your 'undeploy'. But, due to some of those bugs that you reference, we actually can't undeploy out of an org. There's some reference that can't be resolved with our code. We've opened a case with Partner Portal that they worked on for 6 months! and ultimately concluded was a platform bug that was subsequently fixed in a hotfix but just peeled back another layer of the onion (i.e. still busted). Thanks for the ant task. We use it to nuke a new DE to blank state.
    – daveespo
    Sep 17, 2013 at 16:22
  • 1
    Nice! You might be interested in another session, which is aimed more at CI than clearing developers own DE orgs, but takes a different view on the challenge of cleaning orgs... 'Fire and Forget Build Orgs with Provisioning API and Org Expiry' Sep 17, 2013 at 17:14
1

Spring '15 (API v33) introduced the ability to specify the order of component deletion which should work around this problem:

http://releasenotes.docs.salesforce.com/en-us/spring15/release-notes/rn_deploy_delete.htm

To delete components after adding or updating other components, create a manifest file that’s named destructiveChangesPost.xml and include the components to delete.

The behavior of destructiveChanges.xml retains is current behavior:

When you’re using destructiveChanges.xml, deletions are processed first by default.

In summary: create destructiveChangesPost.xml to specify that components are deleted after the new code that no longer references them is deployed

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .