mcpField
E
experience-ui-bundle-deploy

experience-ui-bundle-deploy

github.com/forcedotcom云与 DevOps1.1k5.2k 次安装1 天前更新
代码仓库

关于 experience-ui-bundle-deploy

该 Skill 为 Salesforce UI Bundle 项目提供按序部署与组织配置流程,适合负责应用上线的开发者。它明确处理部署、权限分配和架构读取之间的依赖,并对自助注册和数据导入要求事先征求确认。

主要功能

  1. 01按依赖顺序部署元数据
  2. 02构建 UI Bundle
  3. 03配置权限与用户角色
  4. 04按配置启用自助注册和社交登录
  5. 05支持可选数据导入

适用场景

  1. 01将 UI Bundle 项目部署到 Salesforce 组织
  2. 02为架构读取准备权限集
  3. 03配置 Experience Cloud 站点登录
  4. 04按数据计划导入数据

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/forcedotcom/sf-skills --skill experience-ui-bundle-deploy

安装后在 Claude Code 中输入/experience-ui-bundle-deploy确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

assets/
Communities.settings-meta.xml
data-delete.apex
data-import.apex
network-selfreg-xml-recipe.md
network-selfreg.apex
org-setup.config.template.json
prepare-import-unique-fields.js
social-login-auth-providers.apex
references/
config-scaffold.md
data-import.md
dev-preview.md
graphql.md
license-checks.md
logout-url.md
role-assignment.md
self-registration.md
social-login.md
scripts/
derive-site-name.sh
find-data-plan.sh
find-prep-script.sh
get-source-root.sh
set-logout-url.mjs

详细介绍

部署 UI Bundle 应用

部署顺序至关重要:某一步的输出是下一步的前置条件 (先部署再获取架构;先配置权限再获取架构;先配置角色/自注册, 再获取访客用户必须看到的架构)。这是规范的设置顺序, 移植自参考脚本 org-setup.mjs。references/ 中的 org-setup.mjs 行引用用于说明移植来源(解释每条规则的由来),指向 该外部参考脚本——它们不是此技能随附的文件,因此运行这些步骤时 无需打开。

按顺序运行每个步骤。所有可选步骤都由文件是否存在决定:如果其 约定文件不存在,则正常跳过并继续——不要伪造配置。对于两个具有破坏性或 开销较大的步骤(自注册、数据导入),运行前先询问用户。

事先收集输入

从项目中读取以下信息;仅在缺少信息时询问用户:

  • 目标 org — --target-org 的别名/用户名。如果不明显,请询问。
  • 源根目录 — 运行 scripts/get-source-root.sh,根据 sfdx-project.json(packageDirectories[0].path + /main/default)解析元数据 源目录。如果项目文件缺失或格式错误,该脚本会以非零状态退出。绝不要硬编码 force-app/main/default。
  • org-setup.config.json(可选)— 用于驱动权限集分配、角色、 自注册和社交登录。缺失的键表示“跳过该步骤”。 **例外:**如果文件缺失,但 permissionsets/ 中有需要分配的权限集, 不要静默跳过——应搭建配置文件,或收集等效输入(见步骤 4)。
  • data-plan.json(可选,位于项目的 data/ 目录中)— 文件存在时启用数据步骤。

步骤 1 — Org 身份验证(始终执行)

无条件前置条件;不能跳过。如果 org 已连接 (sf org display --target-org <org> --json 成功),则无需操作。否则:

sf org login web --alias <org>

登录失败会在部署前中止整个设置流程。

步骤 2 — 预部署 UI Bundle 构建

构建所有 UI Bundle,确保在部署元数据之前 dist/ 已存在(UI Bundle 实体部署的是构建后的输出)。对于 uiBundles/ 下的每个 Bundle 目录:

npm install
npm run build

在部署 UI Bundle 且 dist/ 缺失或源代码发生变化时运行。

步骤 3 — 部署元数据

如果已配置自注册:

  1. 先部署许可证预检查(见 references/license-checks.md)——它会以清晰且 指明许可证的消息阻止部署,而不是给出晦涩的失败信息。
  2. 将自注册配置文件添加到本地源的 networkMemberGroups 中 — 应用 assets/network-selfreg-xml-recipe.md 中的 Edit A。必须在此部署 之前完成,以便该配置文件作为已识别的站点成员一同部署;此处不要单独 部署网络文件(本次部署会一并发布)。尽力执行且保持幂等——如果已是成员, 则跳过。

然后,将 --source-dir 指向已解析的源根目录,以部署整个项目(所有元数据):

sf project deploy start --source-dir <sourceRoot> --target-org <org>

<sourceRoot> 是 scripts/get-source-root.sh 返回的值(例如 force-app/main/default)。始终传入 --source-dir。不要在没有路径的情况下直接运行 sf project deploy start:该命令依赖源跟踪来决定要部署的内容,而在未启用源跟踪的 org (大多数非 scratch org)中,它会中止并提示 "This org does not have source-tracking enabled … specify the files or a manifest to deploy."。传入 --source-dir 后,无论 org 是否启用了源跟踪, 都会部署同一套完整内容,也不会出现该提示。如果部署在启用了源跟踪的 org 上报告冲突, 则使用 --ignore-conflicts 重新运行——不要回滚或缩减部署范围。

不要手动构建 package.xml、组装 --metadata-dir mdapi zip,也不要以其他方式转换为 metadata-format——这些操作都不需要,也不属于此流程。

超时时间为 180s。必须在分配权限和获取架构之前完成部署——对象、字段和权限集 只有在部署后才会出现在 org 中。

步骤 3b — 设置站点注销 URL(由配置控制)

仅当 org-setup.config.json 顶层包含 logoutUrl 时运行。如果不存在,则干净地跳过并说明原因。非破坏性且幂等——无需询问。

在这里、部署之后运行(不要合并到部署中),因为平台会拒绝相对注销 URL(“The logout page URL must be an absolute URL.”),而已交付的站点相对路径(例如 /propertyrentalapp/)会以站点的 Experience Cloud 源为基准解析为绝对 URL——该源只有在站点部署后才存在。

重要性:如果站点没有 <logoutUrl>,正在注销的成员会被送到组织默认站点的登录页面——在多站点组织中,那是另一个社区,因此“退出”会跳到错误站点的登录页面。设置此项可将注销引回此站点(以访客身份重新加载)。

步骤:

  1. 读取配置中的 logoutUrl;不存在 → 跳过。

  2. 推导站点——运行 scripts/derive-site-name.sh(单个 *.network-meta.xml;若为零个或存在歧义则跳过)。

  3. 解析、设置并部署——使用一条命令。 调用辅助程序,它会将值解析为绝对 URL(站点相对路径 → 与社区 siteUrl 路径匹配,绝不猜测),在规范位置幂等地写入 <logoutUrl>,并且只部署该文件:

    node scripts/set-logout-url.mjs \
      --logout-url "<logoutUrl from config>" \
      --network-file <sourceRoot>/networks/<site>.network-meta.xml \
      --target-org <org> --site <site> --deploy
    

尽力而为:辅助程序成功或已设置时退出码为 0,遇到可恢复的跳过情形(网络文件缺失、无法解析源、XML 特殊字符或部署失败)时退出码为 3。将退出码 3 视为需要明确说明的跳过,而非设置失败——继续其余设置,并告知用户在站点的“管理”设置中手动设置注销 URL。用法、退出码约定和端口来源:references/logout-url.md。

步骤 4 — 分配权限集

在 <packageDir>/main/default/permissionsets/ 下查找权限集。如果没有权限集,且未显式传入任何权限集,则跳过。

如果存在权限集,但缺少 org-setup.config.json,请勿默默跳过。 缺少配置会使每个查找到的权限集都解析为 skip,因此不会分配任何权限集,后续的 GraphQL 架构也会不完整(调用方缺少 FLS)。请改为协助用户提供分配信息——可以从 assets/org-setup.config.template.json 生成 org-setup.config.json,也可以收集每个权限集的受分配者输入,以便一次性运行。完整的架构与生成配置流程:references/config-scaffold.md。写入文件或执行分配前,请先确认用户意图——不要捏造受分配者。

否则,根据配置中的受分配者(org-setup.config.json → permsetAssignments)逐个分配,每个受分配者为 currentUser、guestUser 或 skip 之一(默认值为 skip):

sf org assign permset --name <permset> --target-org <org> [--on-behalf-of <guestUsername>]
  • currentUser — 不传入 --on-behalf-of。
  • guestUser — 先解析站点的访客用户名(参见 references/self-registration.md 中的访客用户部分)。如果无法推导站点或无法解析出访客用户,跳过该权限集并记录原因——不要中止其他权限集的处理。
  • 将“Duplicate … PermissionSet”和“not found … target org”视为跳过,而非失败。

这是 GraphQL 内省返回正确架构所必需的(调用方需要自定义字段上的 FLS)。

步骤 5 — 分配角色(由配置控制)

仅当 org-setup.config.json 包含 role: { assignee: "currentUser", roleName: "<UserRole>" } 时运行。为当前用户分配角色是 Experience Cloud 自助注册正常运行的必要条件。此操作幂等——如果用户已有角色,则跳过。详情和准确查询:references/role-assignment.md。

步骤 6 — 启用自行注册(由配置控制)— 请先询问

仅当 org-setup.config.json 包含 selfRegistration: { selfRegProfile, accountName } 时运行。运行前先询问用户。 流程(完整详情见 references/self-registration.md):

  1. 许可证预检查(软性跳过)— 如果组织在该配置文件的许可证下没有席位,请发出警告并跳过;这不算失败。请参阅 references/license-checks.md。
  2. 推导站点名称 — 运行 scripts/derive-site-name.sh;它会输出站点名称(唯一一个 *.network-meta.xml 的基础名称),如果文件数量为零或多于一个,则以非零状态退出(存在歧义 — 停止)。
  3. 启用自行注册并重新部署网络文件 — 应用 assets/network-selfreg-xml-recipe.md 中的 Edit B(设置 selfRegistration=true,注入 <selfRegProfile>),然后仅重新部署这一个文件。此操作具备幂等性 — 如果已启用,则跳过两步。(Edit A,即添加成员组,已在步骤 3 中完成。)
  4. 创建 Account 和 NetworkSelfRegistration — 应用 assets/network-selfreg.apex(具备幂等性;两者都采用先查询再创建的方式;将 4a 和 4b 分别作为两次独立的 sf apex run 调用运行)。

第 6b 步 — 启用社交登录(受配置控制)

仅当 org-setup.config.json 中存在 socialLogin 块时运行。如果该块 不存在,loadSocialLoginConfig 会返回 null,并隐藏此步骤——应正常地不执行任何操作, 并明确说明这一点。此步骤不会造成破坏且具有幂等性(只会添加缺少的 链接/成员),因此——与自助注册和数据导入不同——无需事先询问。

此步骤会将站点配置的身份验证提供方(OAuth)和 SAML SSO 配置关联到站点,以便内置的社交登录组件在 React 登录页面上呈现相应按钮。在 React(Site Container)站点上,SSO 管理 UI 处于隐藏状态,因此需要通过 AuthConfig / AuthConfigProviders 记录以编程方式完成关联——无法通过点击 Setup 来完成。 完整详情、子步骤和端口来源信息:references/social-login.md。

配置结构(完整架构参见 references/config-scaffold.md):

{ "socialLogin": {
    "communityMemberProfile": "Customer Community User",
    "authProviderNames": ["Google", "My_SAML_Provider"],
    "communityUserPermset": "myapp_Guest_User_Api_Access"
} }

执行顺序(与参考文件 org-setup.mjs 的 main() 社交登录步骤一致;该步骤在自助注册之后、数据/GraphQL 步骤之前运行):

原样应用 assets/ 模板(与自助注册/数据步骤相同)——各子步骤的完整可执行命令见 references/social-login.md:

  1. 推导站点 — 运行 scripts/derive-site-name.sh(单个 *.network-meta.xml;数量为零或存在歧义时停止)。社交登录需要站点来解析其 AuthConfig。
  2. 启用“Allow standard external profiles” — 通过 Metadata API 部署 assets/Communities.settings-meta.xml(使用临时的最小项目;参见参考文档)。此项为必需设置,这样 SSO 注册处理程序才能在标准社区配置文件上创建用户;否则身份验证提供方会因用户插入失败并返回 FIELD_INTEGRITY_EXCEPTION。出现“already active”警告时可跳过,不视为失败。
  3. 将身份验证提供方关联到站点的 AuthConfig — 原样运行 assets/social-login-auth-providers.apex(替换 <siteName>、 <ProviderNamesList>、<ApiVersion>),以创建缺少的 AuthConfigProviders 关联记录,然后读取其 |DEBUG| 行(表格见参考文档)。此操作要么全部成功,要么全部不执行:如果任何已配置的 authProviderNames 条目都没有匹配的 AuthProvider(OAuth)或 SamlSsoConfig(SAML)记录,脚本会输出 MISSING_PROVIDERS,且不关联任何提供方——请先在 Setup 中创建/修复这些记录。 已关联的提供方会跳过(具有幂等性)。
  4. 将社区成员配置文件添加到 NetworkMemberGroup — 解析 Network 和 Profile Id,并在不存在时创建成员关系(命令见参考文档中的 sf data)。缺少此步骤时,通过 SSO 注册的用户会遇到 NO_ACCESS: User was not authorized for the community。
  5. (可选)为社区用户分配 communityUserPermset — 仅在已配置时执行。授予 ApiEnabled,使 SSO 创建的用户能够调用 getCurrentUser()(/chatter/users/me)。

重要: 存在 socialLogin 块但跳过了此步骤,会导致难以察觉的失败——应用部署正常,但登录页面始终不会显示社交登录按钮,也没有任何错误说明原因。切勿静默跳过:存在此配置块时就运行此步骤;若不存在,则明确说明。

步骤 7 — 数据导入(由数据是否存在驱动)— 先询问

先运行 scripts/find-data-plan.sh。如果它以非零状态退出,跳过此步骤 — 不要提示,也不要报错;直接继续步骤 8(可以简短说明“没有数据计划, 跳过数据导入”)。没有计划就没有可导入的数据。 成功时,它会打印计划文件的路径(它会递归搜索,因此项目根目录下的 data/ 和 <packageDir>/main/default/data/ 两种布局都能找到)。

计划存在时:导入或清理数据前务必先询问用户 — 因为它会先删除现有记录。 请原样应用模板;不要自行编写 Apex:

  1. 运行 scripts/find-prep-script.sh。如果成功,它会打印随应用附带的 prepare-import-unique-fields.js 的路径 — 先运行该脚本;它会在记录文件上 写入稳定的唯一键,以便对重复运行进行去重。按该副本预期的方式调用它(其接口 可能有所不同 — 参见 references/data-import.md)。如果它以非零状态退出, 则没有准备脚本 — 跳至清理步骤。
  2. 按计划的逆序执行清理(先子项,后父项),使用 assets/data-delete.apex。
  3. 按计划的顺序执行导入,使用 assets/data-import.apex,解析 @referenceId 引用并按测得的大小分批处理。

协议、@referenceId 解析、测量分批,以及 SETUP_RESULT_JSON 的解析并在失败时 立即报错规则:参见 references/data-import.md。

步骤 8 — 获取 GraphQL 架构 + 代码生成

在 UI 包目录中运行,部署并分配权限之后(架构反映组织状态和调用者的 FLS):

npm install
SF_TARGET_ORG=<org> npm run graphql:schema
npm run graphql:codegen
npm run build

详情:references/graphql.md。每次部署更改对象、字段或权限后,都要重新获取架构并 运行代码生成。

完成

设置到此结束 — 上述步骤(包括由配置控制的 6b 社交登录)就是完整流程。本地 开发预览(npm run dev:preview)是单独的开发者操作,不属于设置流程;如果用户 要求预览网站,请参见 references/dev-preview.md。

关键规则

  • 先部署元数据,再获取架构 — 自定义对象/字段只有在部署后才会出现。
  • 先分配权限,再获取架构 — 否则调用者可能缺少 FLS。
  • 每次部署更改对象、字段或权限的元数据后,都要重新获取架构并运行代码生成。
  • 绝不要默默跳过权限分配、自助注册、社交登录或数据导入 — 要么存在约定文件/配置块 (执行它;对于具有破坏性的操作要先询问),要么不存在(妥善跳过并说明)。如果 socialLogin 配置块存在但被跳过,就不会显示登录按钮,且没有错误提示来解释原因。
  • 从 sfdx-project.json 中发现源路径;绝不要硬编码 force-app/main/default。
  • 原样应用 assets/ 中的 Apex 和 XML 模板 — 它们包含绕过重复规则、 allOrNone=false 删除、幂等性、SOQL 安全性,以及(对于社交登录)全有或全无的 提供方预检查和针对 AuthConfigProviders 的禁止 DML 操作的 REST 调用插入 — 这些 都很容易在手动操作时出错。

交互顺序(摘要)

  1. 验证组织身份
  2. 构建 UI 包(部署前)
  3. 部署元数据(如果配置了自助注册,则启用部署许可证门控) 3b. 设置站点注销 URL(如果配置了 logoutUrl — 部署后执行、幂等、尽力而为)
  4. 分配权限集(由配置驱动的受分配者)
  5. 分配角色(如果已配置)
  6. 启用自助注册(如果已配置 — 先询问) 6b. 启用社交登录(如果配置了 socialLogin — 幂等,无需询问)
  7. 导入数据(如果存在数据计划 — 先询问)
  8. 获取 GraphQL 架构 + 代码生成 + 最终构建

评论

支持 Markdown