解锁包

Salesforce提供不同类型的软件包,解锁的软件包尤其如此 适用于内部业务应用程序。除非您计划在 AppExchange 上分发应用程序,否则 解锁包是大多数用例的正确包类型。您可以使用解锁的软件包来 整理现有元数据、打包应用、扩展已购买的应用 AppExchange 或打包新元数据。

解锁的包遵循源代码驱动的开发模型。元数据的真实来源 包中包含的是您的版本控制系统,而不是组织中的内容。该模型带来 有了它,现代源代码驱动开发模式的所有好处。

注意

如果您是 AppExchange 合作伙伴,并计划通过以下方式将您的应用程序分发给客户 AppExchange,使用第二代托管打包。有关详细信息,请参阅第二代托管软件包 信息。

  • 什么是解锁套餐?
    如果你不熟悉打包,则可以将包视为填充元数据的容器。它包含一组相关功能、自定义项和架构。您可以使用包将元数据从一个 Salesforce 组织移动到另一个组织。
  • 基于包的开发模型 为了演示解锁包的强大功能,以下是打包在传统开发模型
    中的工作方式。对于大多数生产组织,元数据传统上包含在两个存储桶中:一组从 AppExchange 安装的托管软件包和未打包的元数据。
  • 在创建未锁定的包之前 使用未锁定的
    打包时,为确保正确设置它,请验证以下内容。
  • 了解您的组织 您使用
    解锁包装的一些组织具有独特的用途。
  • 创建与组织相关的未锁定包 与组织相关的未锁定包是未锁定包的变体,允许您在计划安装包的组织(安装组织)中创建依赖于未打包元数据的包
  • 解锁包
    的工作流 您可以直接从 Salesforce 命令行创建和安装解锁包。
  • 配置解锁的软件包 您可以在每个软件包的
    sfdx-project.json 文件中包含一个条目,以指定其别名、版本详细信息、依赖项、功能和组织设置。在命令行中,还可以设置或更改选项,例如指定安装密钥、更新软件包名称或添加说明。
  • 我们如何处理未锁定包
    中的配置文件设置 将配置文件打包到未锁定的或第二代托管包中时,生成系统会在包创建期间检查配置文件的内容,并仅保留与包中的元数据直接相关的配置文件设置。配置文件本身以及与包的元数据无关的任何配置文件设置都将从包中丢弃。
  • 开发未锁定的包 包是一个顶级容器,其中包含有关应用或包的重要详细信息:包
    名称、说明和关联的命名空间。
  • 推送未锁定软件包的软件包升级 通过推送升级,您可以升级订阅者组织中安装的软件包
    ,而无需要求客户自行安装升级。您可以选择哪些组织接收推送升级、将软件包升级到哪个版本以及何时进行升级。推送升级特别有用:如果您需要推送更改以修复热错误。
  • 安装未锁定的软件包
    使用 CLI 或浏览器安装未锁定的软件包。您可以在临时组织、沙盒组织、DE 组织或生产组织中安装软件包版本。
  • 从未锁定的包中迁移已弃用的元数据 您可以弃用未锁定包中的元数据,将该元数据移动到新包,然后在生产组织中安装新包
  • 卸载未锁定的软件包
    您可以使用 Salesforce CLI 或从设置 UI 从组织中卸载软件包。卸载未锁定的软件包时,软件包中的所有组件都将从组织中删除。
  • 将解锁的包转移到其他开发人员中心 可以将已解锁包的所有权从一个开发人员中心组织转移到另一个开发人员中心
    组织。

什么是解锁套餐?

如果您不熟悉包装,则可以将包装视为您填充的容器 替换为元数据。它包含一组相关功能、自定义项和架构。您使用软件包 将元数据从一个 Salesforce 组织移动到另一个组织。

每个解锁的包都有不同的生命周期。将元数据添加到包中,然后创建一个 新的包版本。虽然包在不断发展,但每个包版本都是一个 不可变的工件。

包版本包含与包关联的特定元数据和功能 版本,在创建时。在循环访问包以及添加、删除或更改包时 打包的元数据,您可以创建多个包版本。

您可以在临时版、沙盒版、试用版、开发人员版或 生产组织。安装包版本与部署元数据类似。每个包装 version 有一个版本号,订阅者可以将新的软件包版本安装到他们的组织中 通过软件包升级。

注意

由于包版本是不可变的,因此它们也可以用作连续的工件 集成 (CI) 和持续交付 (CD) 流程。

您可以多次重复包开发周期。您可以更改元数据, 创建包版本,测试包版本,最后将包部署或安装到 生产组织。通过这种独特的应用开发生命周期,您可以准确控制内容、时间和内容 元数据的推出方式。在已安装的组织中,您可以检查来自哪些元数据 哪个包以及与特定包关联的所有元数据集。

基于包的开发模型

为了演示解锁包的强大功能,以下是打包在 传统发展模式。对于大多数生产组织来说,元数据传统上包含在 两个存储桶:一组从 AppExchange 安装的托管软件包,以及未打包的 元数据。

客户经常投资 Salesforce 自定义以支持业务流程和扩展 Salesforce 平台的强大功能。在开发模型中,您的 Salesforce 组织的单体 未打包的元数据包含属于自定义应用或扩展程序的所有元数据。因为 元数据不是孤立的或有组织的,可能难以理解、升级和 保持。

在包开发模型中,可以在生产中组织未打包的元数据 组织到定义良好的包中。您可以使用 Salesforce DX 项目来组织您的源 放入包目录中,所有内容都在您选择的版本控制系统中进行管理。你 最终目标是使用那些可版本控制、易于维护的目录创建包。 更新、安装和升级。

解锁的包允许您在一个或多个托管和 解锁的包,使您的包保持小巧和模块化。您可以使用命令行执行以下操作 执行未锁定的打包操作,或者您可以包含特定于打包的 Salesforce CLI 脚本中的命令,并自动执行包开发。

创建解锁包之前

使用解锁的包装时,为确保设置正确,请验证 以后。

你?

  • 在组织中启用 Dev Hub
  • 启用第二代托管打包
  • 安装 Salesforce CLI

注意

解锁的包装可通过以下许可证获得:Salesforce 或 Salesforce Limited 访问 – 免费(仅限合作伙伴)。

使用解锁包的开发人员需要在开发人员中心设置正确的权限 组织。开发人员需要系统管理员配置文件或创建和更新 第二代包权限。有关更多信息,请参阅添加 Salesforce DX 用户。

可以从开发人员中心创建的最大解锁包版本数 Day 与您的每日 Scratch 组织分配相同。要请求提高限制, 请联系 Salesforce 客户支持。临时组织和包是分开计算的,因此创建解锁的包不计算在内 违反您的每日临时组织限制。要查看临时组织限制,请使用 CLI:

sf limits api display

欲了解更多信息 临时组织限制,请参阅临时组织。

了解您的组织

您使用解锁包装的某些组织具有独特的 目的。

选择你的 Dev Hub 组织

将 Dev Hub 组织用于这些目的。

当您使用 Salesforce CLI 创建未锁定的软件包时,您将关联该软件包 具有特定的 Dev Hub 组织。当您准备好定义和创建包时 生产使用,请务必在 生产组织。

  • 作为所有已解锁软件包的所有者
  • 如果要创建命名空间的未锁定包,请链接命名空间
  • 授权并运行命令sf package

命名空间 Org

如果使用的是命名空间,则需要命名空间组织来获取包 命名空间。如果要严格使用命名空间进行测试,请选择 Disposable 命名空间。

创建命名空间组织并在其中指定命名空间后,打开 Dev Hub 组织,并将命名空间组织链接到 Dev Hub 组织。

其他组织

使用包时,还可以使用以下组织:

  • 您可以即时创建临时组织,以便在测试软件包时使用。
  • 目标组织或安装组织是安装包的位置。

创建与组织相关的未锁定包

依赖于组织的解锁包是解锁包的变体,允许您 在计划安装 软件包(安装组织)。

所需的用户权限
要创建包,请执行以下操作:创建和更新第二代程序包

解开生产组织元数据可能是一个艰巨的项目。但现在你有了一个解决方案 这使您能够在不完全考虑所有元数据依赖项的情况下打包元数据: 依赖于组织的解锁包。使用与组织相关的解锁包时,元数据 验证在包安装期间进行,而不是在包版本创建期间进行。

长期和大型生产组织通常会积累大量元数据,这些元数据是 采用基于包的应用程序生命周期管理 (ALM) 时难以模块化 方法。相反,您可以将依赖于未打包元数据的元数据打包到 安装组织。

注意

依赖于组织的解锁包是解锁包的变体,而不是单独的 封装类型。它们遵循相同的软件包开发步骤,并使用 支持的元数据类型与解锁相同 包。要创建依赖于组织的解锁软件包,请指定依赖于组织的 CLI 参数 命令。

sf package create

sf package create -t Unlocked -r force-app -n MyPackage --org-dependent
场景解锁套餐Org Dependent Unlocked 软件包
一次构建,随处安装是的不。这些软件包专为特定的生产和沙盒组织而设计。您可以 仅将它们安装在包含包所依赖的元数据的组织中。
依赖项验证在包版本创建期间发生在软件包安装过程中发生
可以依赖其他软件包是的
需要解析依赖项才能创建包是的
支持的元数据类型请参阅元数据覆盖率报告的已解锁打包通道。请参阅元数据覆盖率报告的已解锁打包通道。
推荐的开发和测试环境使用 scratch 组织来开发和测试未锁定的软件包。使用包含依赖元数据的沙盒。请考虑在沙盒中启用源跟踪,以便 开发与组织相关的解锁包。然后,在沙盒组织中测试包 将其安装在您的生产组织中。
代码覆盖率要求在升级和发布未锁定的软件包之前,Apex 代码必须满足 最低 75% 的代码覆盖率要求。我们不计算代码覆盖率,但我们建议您确保 Apex 代码 您的包裹经过了良好的测试。

要查看哪些软件包是与组织相关的解锁软件包,请使用 .sf package list –verbose

解锁包的工作流

您可以直接从 Salesforce 命令创建和安装未锁定的软件包 线。

在开始之前,请查看并完成创建解锁包之前中的步骤 此工作流。

基本工作流包括以下步骤。有关每个主题的详细信息,请参阅特定主题 步。

  1. 创建 DX 项目。sf project generate --output-dir expense-manager-workspace --name expenser-app
  2. 授权 Dev Hub 组织,并创建临时 组织。sf org login web --set-default-dev-hub什么时候 执行此步骤时,请包含该选项。然后,可以省略 Dev Hub username(在运行后续 Salesforce CLI 命令时)。—set-default-dev-hub提示如果您为与您合作的每个组织定义一个别名,则很容易在两者之间切换 来自命令行的不同组织。您可以授权不同的组织 循环访问包开发周期。
  3. 创建一个临时组织并开发软件包。可以使用 VS Code 和安装程序 UI 在 Scratch 组织中构建和检索要包含在 包。导航到 expenser-app 目录,然后运行此 命令。sf org create scratch --definition-file config/project-scratch-def.json --target-org MyScratchOrg1
  4. 验证所有包组件是否都位于要删除的项目目录中 创建包。
  5. 从 Salesforce DX 项目目录中,创建包。sf package create --name "Expense Manager" --path force-app --package-type Unlocked
  6. 查看 sfdx-project.json 文件。CLI 自动 更新项目文件以包含包目录,并创建基于 在包名称上。{ "packageDirectories": [ { "path": "force-app", "default": true, "package": "Expense Manager", "versionName": "ver 0.1", "versionNumber": "0.1.0.NEXT" } ], "namespace": "", "sfdcLoginUrl": "https://login.salesforce.com", "sourceApiVersion": "51.0", "packageAliases": { "Expense Manager": "0Hoxxx" } }请注意 和 的占位符值。versionNameversionNumber指定所需的功能和组织设置 对于使用外部的包中的元数据 .JSON 文件,例如临时组织定义文件。您可以在命令中指定使用标志,或列出 sfdx-project.json 文件中的定义文件。请参见: 已解锁包的项目配置文件–definition-filesf package version create
  7. 创建包版本。此示例假定包元数据位于 force-app 目录中。sf package version create --package "Expense Manager" --installation-key test1234 --wait 10
  8. 在临时组织中安装并测试软件包版本。使用不同的临时组织 从您在步骤中使用的那个 三。sf package install --package "Expense Manager@0.1.0-1" --target-org MyTestOrg1 --installation-key test1234 --wait 10 --publish-wait 10
  9. 安装软件包后,打开 scratch 组织以查看 包。sf org open --target-org MyTestOrg1

程序包版本是 beta 版,直到将其提升为托管发布状态。请参阅:释放已解锁的软件包。

配置未锁定的软件包

在 sfdx-project.json 文件中为每个 package 来指定其别名、版本详细信息、依赖项、功能和组织设置。 在命令行中,您还可以设置或更改选项,例如指定 安装密钥、更新软件包名称或添加说明。

  • 已解锁包
    的项目配置文件 项目配置文件是项目的蓝图。文件中的设置将创建包的轮廓,并确定包属性和包内容。
  • 解锁的打包关键字 关键字
    是一个变量,可用于指定包版本号。
  • 包安装密钥 若要确保包中元数据的安全性,必须在创建包版本时指定安装密钥
    。包创建者向授权订阅者提供密钥,以便他们可以安装包。软件包安装程序在安装过程中提供密钥,无论是从 CLI 还是从浏览器安装软件包。安装密钥是安装过程中的第一步。该密钥可确保在提供正确的安装密钥之前不会泄露任何软件包信息,例如名称或组件。
  • 从未锁定的包
    中提取依赖项信息 对于已安装的未锁定包,现在可以运行简单的 SOQL 查询来提取其依赖项信息。您还可以创建一个脚本来自动安装具有依赖项的未锁定包。
  • 了解命名空间 命名空间
    是一个 1-15 个字符的字母数字标识符,用于将包及其内容与组织中的其他包区分开来。
  • 共享发行说明和安装后说明
    与用户共享有关已发布的解锁包中的新增功能和更改的详细信息。
  • 为 Apex 测试指定未打包的元数据或 Apex 访问权限(未锁定的包)
  • 解锁包的最佳实践 我们建议您在使用解锁包
    时遵循这些最佳实践。
  • 已解锁包的包
    ID 和别名 在包生命周期中,包和包版本由 ID 或包别名标识。当您创建软件包或软件包版本时,Salesforce CLI 会根据软件包名称创建软件包别名,并将该名称存储在 sfdx-project.json 文件中。运行 CLI 命令或编写脚本以自动执行打包工作流时,通常更容易引用包别名,而不是包 ID 或包版本 ID。
  • 常用的解锁打包操作

解锁包的项目配置文件

项目配置文件是项目的蓝图。中的设置 文件创建包的大纲并确定包属性和包 内容。

以下是可以在项目配置文件中指定的参数。

名字必填?如果未指定,则为默认值
apexTestAccess没有。在上下文中向用户分配权限集和权限集许可证 当您的 Apex 测试在软件包版本上运行时 创造。"apexTestAccess": { "permissionSets": [ "Permission_Set_1", "Permission_Set_2" ], "permissionSetLicenses": [ "SalesConsoleUser" ] }请参阅为 Apex 测试指定未打包的元数据或 Apex 访问权限(未锁定的包)
分支没有。如果你的包有一个关联的分支,但你的包依赖项是 与其他分支关联,请使用此格式。"dependencies": [ { "package": "pkgB", "versionNumber": "1.3.0.LATEST", "branch": "featureC" } ]如果您的软件包具有关联的分支,但您的 包依赖项没有关联的分支,请使用此 格式。"dependencies": [ { "package": "pkgB", "versionNumber": "1.3.0.LATEST", "branch": "" } ]请参阅在解锁的包装中使用分支
违约是,如果指定了多个包目录真指示默认包目录。使用命令从中复制元数据 您的 Scratch 组织复制到您的默认软件包目录。sf project retrieve只能有一个 package 目录,其中默认值设置为 true。
definitionFile没有。对用于指定 包元数据所需的功能和组织设置,例如 Scratch 组织 定义。例:"definitionFile": "config/project-scratch-def.json",
依赖没有。指定对其他包的依赖关系。指定依赖关系 同一 Dev Hub 中的未锁定包,请使用包版本别名或 包名称和版本的组合 数。"dependencies": [ { "package": "MyPackageName@0.1.0.1" } ]"dependencies": [ { "package": "MyPackageName", "versionNumber": "0.1.0.LATEST" } ]指定 Dev 外部解锁包的依赖项 集线器使用:"dependencies": [ { "package": "OtherOrgPackage@1.2.0" } ]注意您可以使用 LATEST 关键字来设置版本号 依赖项。使用包 ID 而不是包来表示依赖项 别名,使用:如果指定包 ID,则为 ID 以及版本号0Ho如果仅指定 包版本 ID04t如果包具有多个依赖项,请提供逗号分隔 按安装顺序排列的软件包列表。例如,如果一个包依赖于 软件包 Expense Manager – Util,这又取决于软件包 External Apex 库,包依赖项为:"dependencies": [ { "package" : "External Apex Library - 1.0.0.4" }, { "package": "Expense Manager - Util", "versionNumber": "4.7.0.LATEST" } ]请参见: 从解锁的包中提取依赖项信息
includeProfileUserLicenses假。设置此参数可确保保留与未锁定软件包中的配置文件关联的用户许可证 在包版本创建期间。默认情况下,解锁的软件包会删除配置文件 与打包的元数据无关的信息。true"packageDirectories": [ { "package": "PackageA", "path": "common", "versionName": "ver 0.1", "versionNumber": "0.1.0.NEXT", "default": false, "includeProfileUserLicenses": true } ]
命名空间没有。一个 1-15 个字符的字母数字标识符,用于区分您的包 及其内容来自其他开发人员的软件包。
是的项目 json 文件中指定的包名称。
package别名是的Salesforce CLI 在您创建包时使用别名更新项目文件,或者 包版本。您还可以手动更新现有包的此部分,或者 包版本。运行时,可以使用别名而不是神秘的包 ID CLI 命令。sf package
路径是的如果您未指定路径,Salesforce CLI 会在您创建 包。
postInstallUrl没有。订阅者安装后说明的 URL。
releaseNotesUrl没有。发行说明的 URL。
seed元数据没有。指定 seedMetadata 目录的路径。种子元数据仅适用于标准值集。如果您的包裹依赖于 标准值集,您可以指定包含 值集。例:"packageDirectories": [ { "seedMetadata": { "path": "my-unpackaged-seed-directory" } }, ]
unpackaged元数据没有。请参阅为 Apex 测试指定未打包的元数据或 Apex 访问权限(未锁定的包)
版本说明没有。
版本名称如果未指定,CLI 将使用 versionNumber 作为版本 名字。
版本编号是的没有。版本号的格式为 major.minor.patch.build。例如 1.2.1.8.自动将内部版本号递增到下一个可用内部版本 对于软件包,请使用关键字 NEXT (1.2.1.NEXT)。

当您使用 Salesforce CLI 指定参数时,它会覆盖该值 在项目定义文件中列出。

Salesforce DX 项目定义文件是位于 您的项目。使用 CLI 命令可以 生成可基于此进行构建的项目文件。以下是参数的显示方式。sf project generatepackageDirectories

{
   "namespace": "",
   "sfdcLoginUrl": "https://login.salesforce.com",
   "sourceApiVersion": "47.0",
   "packageDirectories": [
      {
         "path": "util",
         "default": true,
         "package": "Expense Manager - Util",
         "versionName": "Winter ‘20",
         "versionDescription": "Welcome to Winter 2020 Release of Expense Manager Util Package",
         "versionNumber": "4.7.0.NEXT",
         "definitionFile": "config/scratch-org-def.json"
      },
      {
         "path": "exp-core",
         "default": false,
         "package": "Expense Manager",
         "versionName": "v 3.2",
         "versionDescription": "Winter 2020 Release",
         "versionNumber": "3.2.0.NEXT", 
         "postInstallUrl": "https://expenser.com/post-install-instructions.html",
         "releaseNotesUrl": "https://expenser.com/winter-2020-release-notes.html",
         "definitionFile": "config/scratch-org-def.json",
         "dependencies": [
            {
               "package": "Expense Manager - Util",
               "versionNumber": "4.7.0.LATEST"

            },
            {
               "package" : "External Apex Library - 1.0.0.4"
            }
         ]
      }
   ],
   "packageAliases": {
      "Expense Manager - Util": "0HoB00000004CFpKAM",
      "External Apex Library@1.0.0.4": "04tB0000000IB1EIAW",
      "Expense Manager": "0HoB00000004CFuKAM"}
}

如果我不想自动更新我的 Salesforce DX 项目怎么办?

在某些情况下,您不希望自动更新 sfdx-project.json 文件。当您需要更多控制时,请使用这些 环境变量,用于禁止对项目文件进行自动更新。

对于此命令将此环境变量设置为 true
SF 包创建SFDX_PROJECT_AUTOUPDATE_DISABLE_FOR_PACKAGE_CREATE
SF 包版本创建SFDX_PROJECT_AUTOUPDATE_DISABLE_FOR_PACKAGE_VERSION_CREATE

解锁的包装关键字

关键字是可用于指定包版本的变量 数。

您可以使用关键字自动递增软件包内部版本号的值, 祖先版本号,将包依赖项设置为最新版本或最新 发布和推广版本。

使用关键字
LATEST 在创建 包版本。"dependencies": [ { "package": "MyPackageName", "versionNumber": "0.1.0.LATEST" } ]
NEXT 将内部版本号递增到下一个可用于包版本的版本号。如果 您不使用 NEXT,并且您也忘记更新版本号 在 sfdx-project.json 文件中,新的包版本使用相同的 number 作为以前的包版本。虽然我们不强制要求包的唯一性 版本号,每个包版本都分配有唯一的订阅者包版本 ID (以 04t 开头)。"versionNumber": "1.2.0.NEXT"
RELEASED 指定包依赖项的最新提升和发布版本 创建包版本时。"dependencies": [ { "package": "pkgB", "versionNumber": "2.1.0.RELEASED" } ]
HIGHEST 自动将包祖先设置为最高提升和发布 软件包版本号。仅与祖先版本或祖先 ID 一起使用。"packageDirectories": [ { "path": "util", "package": "Expense Manager - Util", "versionNumber": "4.7.0.NEXT", "ancestorVersion": HIGHEST },
上级版本或上级 ID 字段中为 NONE。Ancestry定义软件包升级 路径。如果包祖先设置为 NONE,则现有客户无法升级到该祖先 包版本。"packageDirectories": [ { "path": "util", "package": "Expense Manager - Util", "versionNumber": "4.7.0.NEXT", "ancestorVersion": NONE },

软件包安装密钥

若要确保包中元数据的安全性,必须指定 创建软件包版本时的安装密钥。包创建者向授权提供密钥 订阅者,以便他们可以安装包。软件包安装程序在以下期间提供密钥 安装,无论是从 CLI 还是从浏览器安装包。安装密钥 是安装过程中的第一步。该密钥确保没有包信息,例如 名称或组件,在提供正确的安装密钥之前会泄露。若要设置安装密钥,请在创建软件包版本时将参数添加到命令中。此命令创建包 并通过安装来保护它 钥匙。

–installation-key

sf package version create --package "Expense Manager" --installation-key "JSB7s8vXU93fI"

在目标组织中安装软件包版本时提供安装密钥。

sf package install --package "Expense Manager" --installation-key "JSB7s8vXU93fI”

更改现有软件包版本的安装密钥

您可以使用以下命令更改现有软件包版本的安装密钥。sf package version update

sfd package version update --package "Expense Manager@1.2.0-4" --installation-key “HIF83kS8kS7C”

创建不带安装密钥的包版本

如果不需要安全措施来保护包元数据,则可以创建一个 没有安装密钥的软件包版本。

sf package version create --package "Expense Manager" --directory common \
--tag 'Release 1.0.0' --installation-key-bypass

检查包版本是否需要安装密钥

要确定软件包版本是否需要安装密钥,请使用 或 CLI 命令。sf package version listsf package version report

从解锁的包中提取依赖项信息

对于已安装的未锁定包,您现在可以运行简单的 SOQL 查询来提取其 依赖项信息。您还可以创建一个脚本来自动安装 具有依赖项的解锁包。

SubscriberPackageVersion 工具 API 对象现在提供依赖项信息。 使用 SubscriberPackageVersion 上的 SOQL 查询,可以标识 解锁的包有一个依赖项。您可以获取 (04t) ID 和正确的 这些软件包的安装顺序。

包 B 依赖于包 A,包 D 依赖于包 B 和 C。 下面是你指定的示例 sfdx-project.json 创建包版本时。包 D 依赖项标记为包 A、B 和 C.

{
    "packageDirectories": [
        {
            "path": "pkg-a-workspace",
            "package": "pkgA",
            "versionName": "ver 4.9",
            "versionNumber": "4.9.0.NEXT",
            "default": true
        },
        {
            "path": "pkg-b-workspace",
            "package": "pkgB",
            "versionName": "ver 3.17",
            "versionNumber": "3.17.0.NEXT",
            "default": false,
            "dependencies": [
                {
                    "package": "pkgA",
                    "versionNumber": "3.3.0.LATEST"
                }
            ]
        },
        {
            "path": "pkg-c-workspace",
            "package": "pkgC",
            "versionName": "ver 2.1",
            "versionNumber": "2.1.0.NEXT",
            "default": false
        },
        {
            "path": "pkg-d-workspace",
            "package": "pkgD",
            "versionName": "ver 1.1",
            "versionNumber": "1.1.0.NEXT",
            "default": false,
            "dependencies": [
                {
                    "package": "pkgA",
                    "versionNumber": "3.3.0.LATEST"
                },
                {
                    "package": "pkgB",
                    "versionNumber": "3.12.0.LATEST"
                },
                {
                    "package": "pkgC",
                    "versionNumber": "2.1.0.LATEST"
                }
            ]
        }
    ],
    "namespace": "",
    "sfdcLoginUrl": "https://login.salesforce.com",
    "sourceApiVersion": "44.0",
    "packageAliases": {
        "pkgA": "0HoB00000008Oq6KAE",
        "pkgB": "0HoB00000008OqBKAU",
        "pkgC": "0HoB00000008OqGKAU",
        "pkgD": "0HoB00000008OqGKAQ"
    }
}

在安装 pkgD(ID = 04txx000000082hAAA)之前,请使用此 SOQL 查询 确定其依赖关系。用户名通常是目标订阅者组织,其中 解锁的包裹是 安装。

sf data query -u {USERNAME} -t 
   -q "SELECT Dependencies FROM SubscriberPackageVersion 
       WHERE Id='04txx000000082hAAA'" --json

运行时会看到此输出 查询,其中 pkgA、pkgB 和 pkgC 的 (04t) ID 次序。

"Dependencies":{"Ids":[
   {"subscriberPackageVersionId":"04txx000000080vAAA"},
   {"subscriberPackageVersionId":"04txx000000082XAAQ"},
   {"subscriberPackageVersionId":"04txx0000000AiGAAU"}]}

了解命名空间

命名空间是一个 1-15 个字符的字母数字标识符,用于区分包 以及组织中其他包中的内容。

指定包命名空间时,添加到包中的每个组件都具有该命名空间 作为组件 API 名称的前缀。假设您有一个名为 Insurance_Agent 的自定义对象 替换为 API 名称。如果添加此 组件添加到与 Acme 命名空间关联的包中,则 API 名称将变为 . Insurance_Agent__cAcme__Insurance_Agent__c

您可以选择创建具有或不具有特定命名空间的解锁包。命名空间 在创建包时分配给包,并且无法更改。

在以下情况下使用无命名空间包在以下情况下使用命名空间包
您希望将元数据从组织的未打包元数据整体迁移到 解锁的包裹。通过创建无命名空间包,可以更好地控制 组织和分发应用程序的各个部分。您不熟悉包装,并且分几个阶段采用包装。使用 命名空间前缀(如 Acme__)可以帮助您识别已打包的内容和仍保留的内容 生产组织中未打包的元数据
您希望保留以前未打包的元数据的 API 名称 元素。您有多个开发团队。命名空间可以确保 API 名称 不要与其他团队发生冲突。通常,使用单个命名空间是 更简单,您可以轻松地在共享 命名空间。

重要

创建命名空间时,请使用有用且信息丰富的内容 用户。但是,不要以人的名字命名命名空间(例如,通过使用人名, 昵称或私人信息)。

使用命名空间时,请牢记以下注意事项。

  • 您可以使用相同的命名空间开发多个解锁包,但您可以 仅将每个包与单个命名空间相关联。
  • 如果您使用多个命名空间,我们建议您为 每个命名空间。
  • 创建并注册命名空间
    使用解锁的包,您可以与多个包共享单个命名空间。由于如果包共享相同的命名空间,则代码共享要容易得多,因此,如果使用 namepaces,建议对命名空间已解锁的包使用单个命名空间。
  • 避免命名空间冲突
    命名空间会影响您可以在组织中安装的软件包类型的组合。
  • 未锁定包
    中 Apex 类的基于命名空间的可见性 使包中的公共 Apex 可供使用相同命名空间的其他包使用。如果没有此注释,则解锁包中定义的 Apex 类、方法、接口和属性将无法被与其共享命名空间的其他包访问。声明为全局的 Apex 在所有命名空间中始终可用,并且不需要注释。@namespaceAccessible

创建并注册命名空间

使用解锁的包,您可以与多个包共享单个命名空间。因为 如果包共享相同的命名空间,则代码共享会容易得多,我们建议在 使用 Namepaces,您可以对命名空间的未锁定包使用单个命名空间。要创建命名空间,请执行以下操作:

  1. 注册新的 Developer Edition 组织。
  2. 在“设置”中,输入“快速查找”框,然后选择“包管理器”。Package Manager
  3. 在“命名空间设置”中,单击“编辑”。
  4. 输入命名空间,然后选择“检查可用性”。
  5. (可选)选择要与此命名空间关联的包,或选择“无”,然后单击“查看”。
  6. 查看您的选择,然后单击“保存”。

要注册命名空间,请执行以下操作:

  1. 若要将创建的命名空间与开发人员中心链接,请使用命名空间注册表。请参阅链接 a 命名空间添加到 Dev Hub 中了解详细信息。
  2. 在 sfdx-project.json 文件中,使用 namespace 属性。当您创建新的未锁定包时,该包是关联的 替换为 sfdx-project.json 文件中指定的命名空间。

避免命名空间冲突

命名空间会影响可以在 组织。

若要了解命名空间如何影响包的类型,可以在命名空间或 no-namespace org,请查看此表。

安装组织无命名空间解锁包命名空间解锁包第二代托管软件包 (2GP)第一代托管软件包 (1GP)
具有命名空间的组织例如,1GP 打包组织、1GP 补丁组织、 具有命名空间的 Developer Edition 组织,或具有命名空间的临时组织失败。您无法在具有 命名空间。通过。如果解锁包的命名空间与 org,您可以安装一个或多个软件包。通过。如果 2GP 的命名空间与组织的命名空间不同,则可以 安装一个或多个软件包。通过。如果 1GP 的命名空间与组织的命名空间不同,则可以 安装一个或多个软件包。失败。如果 1GP 的命名空间与 组织的命名空间,则无法将 1GP 安装到组织中。
没有命名空间的组织通过。可以安装一个或多个无命名空间解锁的包。通过。可以安装一个或多个命名空间的未锁定包。通过。可以安装一个或多个 2GP 软件包。通过。可以安装一个或多个 1GP 软件包。

了解命名空间如何影响可安装到一个包中的组合 org,请查看此表。

命名空间和包类型命名空间为 Y 的解锁包命名空间为 Y 的第二代托管包 (2GP)具有命名空间 Y 的第一代托管包 (1GP)
命名空间为 X 的第一代托管包 (1GP)通过。如果 1GP 和解锁包使用唯一的命名空间,则可以将它们安装在 同一个组织。通过。如果 1GP 和 2GP 使用唯一的命名空间,则可以将它们安装在同一个命名空间中 组织。通过。如果每个 1GP 都使用唯一的命名空间,则可以在 同一个组织。
命名空间为 Y 的第一代托管包 (1GP)失败。如果 1GP 和解锁包共享命名空间,则无法将它们安装在 同一个组织。失败。如果 1GP 和 2GP 共享一个命名空间,则不能将它们安装在同一个命名空间中 组织。失败。如果 1GP 包共享一个命名空间,则不能将它们安装在同一个命名空间中 组织。
命名空间为 X 的第二代托管包 (2GP)通过。您可以在同一组织中安装 2GP 和命名空间的解锁包。这 包可以共享命名空间或使用唯一的命名空间。通过。您可以安装多个具有唯一命名空间的 2GP 包,也可以安装相同的 命名空间。通过。如果 1GP 包使用唯一的命名空间,则可以安装多个 1GP 同一组织中的包。
命名空间为 Y 的第二代托管包 (2GP)通过。您可以在同一组织中安装 2GP 和命名空间的解锁包。这 包可以共享命名空间或使用唯一的命名空间。通过。您可以在同一个 组织。失败。如果 1GP 和 2GP 共享一个命名空间,则不能将它们安装在同一个命名空间中 组织。

解锁包中 Apex 类的基于命名空间的可见性

在 包可用于使用相同命名空间的其他包。如果没有此注解,Apex 无法访问未锁定包中定义的类、方法、接口和属性 与它们共享命名空间的其他包。声明为全局的 Apex 始终是 适用于所有命名空间,无需注释。

@namespaceAccessible

跨软件包的 Apex 可访问性的注意事项

  • 软件包外部的 Lightning 组件可以访问已安装的公共 Apex 方法 来自无命名空间解锁的包。该组件可以从另一个组件安装 包或在组织中创建。为了访问 Apex 方法,解锁了无命名空间 包的处理方式与非托管包相同。
  • 不能将注释用于 Apex 方法。@namespaceAccessible@AuraEnabled
  • 您可以随时添加或删除注释,即使在托管和发布的 Apex 代码上也是如此。确保你没有 在添加或 删除它。@namespaceAccessible
  • 在软件包中添加或删除 Apex 时,请考虑对安装了其他版本的用户的影响 引用此包注释的包。在推送软件包升级之前, 确保没有用户正在运行无法完全编译的包版本,当 已推送升级。@namespaceAccessible

此示例显示一个标有批注的 Apex 类。该类是可访问的 添加到同一命名空间中的其他包。第一个构造函数在 命名空间,但第二个构造函数不是。

@namespaceAccessible

// A namespace-visible Apex class
@namespaceAccessible
public class MyClass {
    private Boolean bypassFLS;

    // A namespace-visible constructor that only allows secure use
    @namespaceAccessible
    public MyClass() {
        bypassFLS = false;
    }

    // A package private constructor that allows use in trusted contexts,
    // but only internal to the package
    public MyClass (Boolean bypassFLS) {
        this.bypassFLS = bypassFLS;
    }
    @namespaceAccessible
    protected Boolean getBypassFLS() {
       return bypassFLS;
    }
}

共享发行说明和安装后说明

与您的共享有关已发布的解锁包中的新增功能和更改的详细信息 用户。

与用户共享有关已解锁包中的新增功能和更改的详细信息。您可以 指定要在用户组织的软件包详细信息页面上显示的发行说明 URL。还有你 可以通过指定安装后 URL 来共享有关使用包的说明。发布 注释和安装后 URL 显示在安装程序的“已安装的软件包”页上,之后 软件包安装成功。对于使用安装 URL 安装软件包的用户, “包安装程序”页显示指向发行说明的链接。用户被重定向到您的帖子 在成功安装或升级软件包后安装 URL。在 和 部分中指定 和 属性 包。

postInstallUrlreleaseNotesUrlpackageDirectories

"packageDirectories": [
      {
         "path": "expenser-schema",
         "default": true,
         "package": "Expense Schema",
         "versionName": ""ver 0.3.2"",
         "versionNumber": "0.3.2.NEXT",
         "postInstallUrl": "https://expenser.com/post-install-instructions.html",
         "releaseNotesUrl": "https://expenser.com/winter-2020-release-notes.html"
        },
        ],
       {
         "namespace": "",
         "sfdcLoginUrl": "https://login.salesforce.com",
         "sourceApiVersion": "47.0",
         "packageAliases": {
             "Expenser Schema": "0HoB00000004CzHKAU",
             "Expenser Schema@0.1.0-1": "04tB0000000719qIAA"
      }
}

您还可以将 和 Salesforce CLI 参数与命令一起使用。CLI 参数覆盖 sfdx-project.json 文件中指定的 URL。–post-install-url–release-notes-urlsf package version create

为 Apex 测试指定未打包的元数据或 Apex 访问权限(未锁定的包)

为包版本创建测试指定未打包的元数据

指定 sfdx-project.json 文件中未打包元数据的路径。

在此示例中,my-unpackaged-directory 中的元数据可用于 测试在TV_unl包的包版本创建期间运行。

"packageDirectories": [
    {
        "path": "force-app",
        "package": "TV_unl", 
        "versionName": "ver 0.1",
        "versionNumber": "0.1.0.NEXT",
        "default": true, 
        "unpackagedMetadata": {
            "path": "my-unpackaged-directory"
        }
    }, 
]

该属性用于元数据 那不是你包裹的一部分。不能在两个未打包的元数据中包含相同的元数据 目录和打包的目录。unpackagedMetadata

管理包版本创建测试的 Apex 访问权限

有时,您编写的 Apex 测试要求用户具有某些权限集或 权限集许可证。使用该设置可以 将权限集和权限集许可证分配给 Apex 在其上下文中测试的用户 Get 在创建包版本时运行。apexTestAccess

"packageDirectories": [
    {
        "path": "force-app",
        "package": "TV_unl", 
        "versionName": "ver 0.1",
        "versionNumber": "0.1.0.NEXT",
        "default": true, 
        "unpackagedMetadata": {
            "path": "my-unpackaged-directory"
        },
        "apexTestAccess": {
               "permissionSets": [
                   "Permission_Set_1",
                   "Permission_Set_2"
               ],
               "permissionSetLicenses": [
                   "SalesConsoleUser"
               ]
           }

    }, 
]

注意

若要分配用户许可证,请使用 runAs 方法。用户 无法在 sfdx-project.json 文件中分配许可证。

解锁包的最佳实践

我们建议您在使用解锁的软件包时遵循这些最佳实践。

  • 建议仅使用一个开发人员中心,并在生产中启用开发人员中心 组织。
  • 运行命令的开发人员中心组织将成为包的所有者。如果 Dev Hub 组织与 包过期或被删除,其包将不再起作用。sf package create
  • 在决定如何利用命名空间时要小心。对于大多数客户,我们建议工作 没有命名空间或单个命名空间,以避免管理组件时不必要的复杂性。 如果要测试未锁定的包,请使用测试命名空间。仅在以下情况下使用实际命名空间 您已准备好踏上在生产环境中发布的开发道路 组织。注意您无法将无命名空间、未锁定的软件包安装到任何具有命名空间的组织中 (例如,具有命名空间的临时组织)。
  • 在使用 和 命令时包括该选项。此选项可帮助您保持版本控制 系统标记与特定软件包版本同步。–tagsf package version createsf package version update
  • 为打包 ID 创建用户友好的别名,并将这些别名包含在 Salesforce 中 DX 项目文件和运行 CLI 打包命令时。请参阅:已解锁包的包 ID 和别名。

已解锁包的包 ID 和别名

在包生命周期中,包和包版本由 ID 或 软件包别名。当您创建包或包版本时,Salesforce CLI 会创建一个包 别名,并将该名称存储在 sfdx-project.json 文件中。当您运行 CLI 命令或编写脚本时 自动化打包工作流,通常更容易引用包别名,而不是 程序包 ID 或程序包版本 ID。

包别名以名称-值的形式存储在 sfdx-project.json 文件中 对,其中名称是别名,值是 ID。您可以修改软件包别名 对于项目文件中的现有包和包版本。

在命令行中,您还可以看到包成员(一个组件 package)和请求(类似于请求)。sf package version create

注意

作为快捷方式,文档有时会通过其三个字符的前缀来引用 ID。 例如,软件包版本 ID 始终以 开头。04t

以下是最常用的 ID。

ID 示例短 ID 名称描述
033J0000dAb27uxVRE订阅者程序包 ID联系 Salesforce 以获得打包或安全审查支持时,请使用此 ID。自 找到包的此 ID,针对拥有该包的开发人员中心运行。sf package list –verbose
04t6A0000004eytQAA订阅者包版本 ID使用此 ID 安装包版本。返回者 。sf package version create
0Hoxx00000000CqCAI程序包 ID在命令行上使用此 ID 创建包版本。或者将其输入到 sfdx-project.json 文件中并使用目录名称。生成者 。sf package create
08cxx00000000BEAAY版本创建请求 ID使用此 ID 可查看状态并监视特定请求的进度,以创建 软件包版本,例如sf package version create report

常用的解锁打包操作

有关 Salesforce CLI 打包命令的完整列表,请参阅: Salesforce 命令 线路参考指南。

Salesforce CLI 命令功效
sf package create创建包。创建包时,请指定其包类型和 名称等。
sf package version create创建包版本。
sf package install在临时组织、沙盒组织或生产组织中安装软件包版本。
sf package uninstall删除已安装在组织中的软件包。此过程将删除 元数据和与包关联的数据。
sf package version promote将包版本的状态从 beta 更改为托管版本 州。
sf org create scratch创建临时组织。
sf org open在浏览器中打开组织。

我们如何处理解锁包中的配置文件设置

当您将配置文件打包到未锁定或第二代托管中时 package,构建系统会在创建包期间检查配置文件的内容,并且 仅保留与包中的元数据直接相关的配置文件设置。这 配置文件本身,以及与包元数据无关的任何配置文件设置都将从 包。

在软件包安装期间,保留的配置文件设置仅应用于现有 订阅者组织中的配置文件。配置文件本身未安装在订阅者组织中。

注意

不允许仅包含配置文件而不包含其他元数据的包,并且会失败 在包版本创建期间。

当您选择…打包的配置文件设置应用于…此安装选项可通过以下方式获得:
仅供管理员安装订阅者组织中的系统管理员配置文件。CRUD 访问自定义 对象将自动授予“系统管理”配置文件。软件包安装程序页面Salesforce CLI 命令sf package install基于 CLI 的软件包安装的默认行为是仅为管理员安装。
为所有用户安装系统管理员配置文件和订阅者组织中所有克隆的配置文件。克鲁德 对自定义对象的访问权将自动授予系统管理配置文件,并且 所有克隆的配置文件。标准配置文件不能是 改 性。软件包安装程序页面Salesforce CLI 命令sf package install要通过 CLI 为所有用户安装,请包括安全类型 参数。sf package install –security-type AllUsers
为特定配置文件安装订阅者组织中的特定配置文件。此选择允许安装人员 程序包确定如何将打包的配置文件设置映射到中的特定配置文件 他们的组织。软件包安装程序页面不适用于基于 CLI 的软件包安装。

要测试打包配置文件的行为,请在临时组织中安装包。

  1. 在“设置”中,输入“快速查找”框,然后找到 和 检查在软件包安装过程中选择的配置文件。Profile
  2. 检查您的配置文件设置是否已应用于该配置文件。重复此步骤 对于您希望包含配置文件设置的任何其他配置文件。不要查找个人资料 您创建的名称;我们将配置文件设置应用于订阅者中的现有配置文件 组织。

尽可能使用包权限集,而不是配置文件设置。订阅者 安装包可以轻松地将权限集分配给其用户。

注意

在推送升级期间,一些与 Apex 类和字段级相关的配置文件设置 安全性不会自动分配给系统管理员配置文件。与您的沟通 客户,以确保在推送升级后正确设置用户访问权限。确保你 推送升级后查看并更新您的配置文件设置。

在未锁定的软件包中保留许可证设置

默认情况下,配置文件中的许可证设置在包创建过程中会被删除。要保留这些 settings,指定参数 在 sfdx-project.json 文件中。在此方案中,许可证设置为 保留并应用于订阅者组织中在打包期间选择的配置文件 安装。includeProfileUserLicenses

"packageDirectories": [
    {
        "package": "PackageA",
        "path": "common",
       "versionName": "ver 0.1",
       "versionNumber": "0.1.0.NEXT",
       "default": false,
       includeProfileUserLicenses: true
    }
]