使用SFDX-Deploy-Tool删除Metadata

本文已参与「新人创作礼」活动,一起开启掘金创作之路。
背景】:在探索Data Sharing & Visibility Designer模块时,想基于复杂的Role Hierarchy来做POC(比如Business Unit底下增加Territory地域维度,并将Partner Community和Salesforce不同类型User Type的Role Hierarchy衔接在一起),以深入理解这方面的知识。我们知道一个DE Org最多有2个Salesforce License和5个Partner Community User License,在尝试使用两套不同Role Hierarchy并用Deactivate User的方式来实现不同Role Hierarchy的切换后,依然无法满足对更复杂的Data Sharing POC的要求,思索几天后还是决定刷一个Sandbox Pro来解决License不够的问题。为了打造一个纯净的环境,清除不必要的Metadata(比如Installed Packages, Inactive的Flow,多余的Apex Class,VFP,Page Layout, Business Process, Object等)就显得尤为重要。

选用工具】:SFDX-Deploy-Tool
基本介绍:我们在设定好source org, destination org等相关配置信息后(包括package的构建),只需要输入相应的数字1-7,就能实现元数据部署相关的操作。

由于系统高度自定义,admin和developer产生了很多自定义的信息,所以下面不过多累述如何将环境清理干净的过程,而是专注于几个核心模块,介绍该工具如何帮助提升元数据清除工作的效率。

模块一:如何清除系统中Process Builder和Flow? 】:Deleting Lots of Old Flows / Process Builders
步骤:

  1. 构建package元素Flow(Process Builder包含在Flow里面)

a. 使用下面SOQL查询Draft和Obsolete状态的Flow (该方法只能删除Inactive的Flow / PB),查询时需勾选"Use Tooling API?"

SELECT Id, Definition.DeveloperName, VersionNumber, Status FROM Flow WHERE Status IN ('Draft', 'Obsolete') ORDER BY Status, Definition.DeveloperName
复制代码

b. 查询出来后需要使用Excel构建xml所需member节点 (DevName-vNo),如下:

c. 构建destructiveChanges.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>CZ_2019_AWAKEN_PROFILE_UPDATE_Reward_Code_Email_Alert-1</members>
        <members>CZ_2019_AWAKEN_Reward_Code_Email_Alert-2</members>
        <members>CZ_2019_WELCOME_Reward_Code_Email_Alert-1</members>
        <members>Email_Activity_History-1</members>
        <members>Email_Reminder_on_Task_for_CCC-1</members>
        <members>Lead_and_Case-1</members>
        <members>Marketing_Material_Opt_Out_and_Email_Opt_Out-6</members>
        <members>Survey_A-5</members>
        <members>Update_the_Inactive_Consultant_s_Client-2</members>
        <name>Flow</name>
    </types>
    <version>48.0</version>
</Package>
复制代码
  1. 删除Inactive的Flow打开bat文件后,输入7,静待删成即可!

  1. 最终效果:

幕后花絮 —— Q&A:
Q1. 遇到的最大挑战是什么?
A1. 我们知道可以在pb里面call flow,也就是说flow间是存在依赖的,所以如果笼统的将flow members放在一起的简单粗暴模式显然走不通 (见下图);另外即使没依赖,更不能想当然不检索有哪些definition而直接用*通配符代表所有。

Q2. 上文提到不能删Active的Flow,难不成最终是手动挨个点Deactivate,然后再用工具删的?
A2. 最终通过检索Flow和FlowDefinition元数据,并修改FlowDefinition的activeVersionNumber (0表示Inactive),再通过vs code部署元数据到sandbox,实现禁用操作。
模板:Deactivate a process or flow using workbench
Temp01 - package.xml

<?xml version ="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>*</members>
        <name>Flow</name>
    </types>
	<types>
		<members>*</members>
        <name>FlowDefinition</name>
	</types>
    <version>48.0</version>
</Package>
复制代码

优化:鉴于以上过程过于复杂,如感兴趣,不妨试下这款工具ForceFlow,有机会详细介绍下如何使用脚本自动化一些重复性的任务。

Q3. 如何使用Ant Hard Delete自定义对象和字段?Hard-Delete Objects Using the Force.com Migration tool

A3. 在build.xml中指定purgeOnDelete="true":

<target name="undeployCode_am_dev1">
    <sf:deploy username="${sf.username_am_dev1}" password="${sf.password_am_dev1}" sessionId="${sf.sessionId}" serverurl="${sf.sandbox_url}" maxPoll="${sf.maxPoll}" deployRoot="AM_DEV" purgeOnDelete="true"/>
</target>
复制代码

purgeOnDelete. If true, the deleted components in the destructiveChanges.xml manifest file aren't stored in the Recycle Bin. Instead, they become immediately eligible for deletion. This field is available in API version 22.0 and later. This option only works in Developer Edition or sandbox organizations; it doesn't work in production organizations. Extending Salesforce Migration Tool to Support PurgeOnDelete.. For some reason this excellent feature has still not been exposed by the Salesforce Migration Tools via the sf:deploy Ant Task. However with a bit of Java skills you can create a new deploy Ant Task by extending the current one, to expose the attribute to your Ant build scripts, for example...

尝试删除prod中的customobject,报错验证了结论:

思考:如果soft-delete objects, fields, 导致删除global picklist sets时因依赖失败,如何快速erase这些存在recycle bin的deleted fields呢?
提示1:参考如何批量删除Salesforce中Picklist值
提示2:点击按钮触发erase本质上是发请求通知sf服务,我们是否可以通过Python查出id list后发送post请求到对应的服务来绕过前端的popup window这类繁琐操作呢?- 210708 亲测用Python这样干还不是和说的那么简单,其中_CONFIRMATIONTOKEN就需要动态获取

https://alias.salesforce.com/setup/own/deleteredirect.jsp?setupid=CustomObjects&delID=01I7F000002JNyD&deleteType=HARD_DELETE&_CONFIRMATIONTOKEN=VmpFPSxNakF5TVMwd055MHhNRlF3TXpvd016bzFNQzQxT0RKYSxCcElGWTVoLUN0U3pEbTVWNWVxV3Z3LFlqa3dNVFJt
复制代码

Q4. 如何删除Private Folders中的Reports和Dashboards?
A4. 首先使用Ant元数据是获取不到Private Folders的,这个官方也承认过,见Ideas,当然也没必要手动删除,可以用soql查,再用dml删除,就像删除记录一样。

使用下面代码可以帮助我们找到所有Private Folders中的Reports和Dashboards:

List<Report> repList = [SELECT Id, Foldername, DeveloperName FROM Report USING SCOPE allPrivate];
List<Dashboard> dbList = [SELECT Id, Foldername, DeveloperName FROM Dashboard USING SCOPE allPrivate];
复制代码

那么和Reports,Dashboards形成依赖的ReportTyps倒需要使用Ant来删除。

猜你喜欢

转载自juejin.im/post/7108611792447750152