Q. What are Unlocked Packages?
Q. What are the benefits of packaging over Change Sets and ANT Migration Tool?
Q. What is a “package” and what is a “package version”?
Q. What is “unpackaged metadata”?
Q. What are the different types of packages and which one should I use?
Q. If I am an ISV, what type of packaging should I use?
Q. How can I organize my unpackaged metadata using unlocked packages?
Q. What are some of the common packaging operations?
Q. What are package aliases and how do they work?
Q. How can I use Salesforce CLI to perform package-related operations?
Q. How can I specify attributes in the sfdx-project.json file for managing my packages?
Q. What can be packaged in Unlocked Packages? Will unlocked packages support ALL metadata in future?
Q. How and where can I install my unlocked packages?
Q. How can I find out about the set of packages installed / deployed in my org?
Q. How do I iterate on my package? What happens when I add, edit and delete package metadata?
Q. How do I work with Version Numbers?
Q. During a package upgrade, how are destructive changes handled?
Q. How can I remove metadata from my package?
Q. How can I refactor my package?
Q. Can I downgrade my package?
Q. How can I secure my packages?
Q. What is the difference between beta package versions and released package versions?
Q. Can my packages depend on one another?
Q. How can I specify dependencies among packages?
Q. When are package dependencies enforced?
Q. Can you give me an example of an sfdx-project.json file with many interdependent packages?
Q. How can I automatically install dependent packages?
Q. Who owns the unlocked packages?
Q. What is a namespace and should I use one with my unlocked package?
Q. How can I delete my package and package versions?
Q. What is the relationship between version control system and packages?
Q. What are Locked Packages? Can I use them?
Q. How can I get more info about Salesforce DX and Unlocked Packages?
As part of Salesforce DX, with the Winter ‘19 release, Unlocked Packages is Generally Available. Unlocked Packages is a new type of packaging solution that is being offered as part of Salesforce DX. It provides a package-based solution for metadata organization, deployment and distribution for enterprise customers building Apps on Salesforce Platform.
Salesforce enterprise customers have historically used org-based deployment approaches like Changesets and ANT deployment to deploy metadata to their orgs. With Unlocked Packages, there is a package-based deployment unit that offers an alternative to Changesets and metadata deploys.
Unlocked Packages offers certain distinct advantages over Change Sets and the ANT Migration Tool (See here for the benefits of unlocked packages over current technologies).
(Back to the Table of Contents)
The following are some key benefits of packaging:
(Back to the Table of Contents)
A package is a container for Salesforce metadata. It represents a distinct deployable unit of functionality that is iterated over time. You can add metadata to a package and take a snapshot of it, anytime. This snapshot is called a package version. You can create package versions any number of times. Each package version, once created, is immutable and is associated with a single package. You can install a package version in any Salesforce environment - scratch orgs, sandbox orgs, or production orgs. Installing a package version deploys the metadata that was specified when the package version was created.
(Back to the Table of Contents)
Broadly speaking, the metadata in your production org can be categorized into three buckets:
(Back to the Table of Contents)
If you are a customer or someone developing something for a specific customer, it is recommended that you use unlocked packages; if you are an ISV partner that wishes to distribute your App on AppExchange for a set of customers, managed packages is the recommended solution. For more details, read on…
You may have heard about many package-related terms - managed packages, Package 2, Developer-controlled packages, DCPs, unlocked packages, locked packages, unmanaged packages, Salesforce DX packages, second-generation packages… Let’s demystify these now.
First-Generation Packaging
Before Salesforce DX came along, we had two types of packages:
Second-Generation Packaging
With Salesforce DX, we are launching Unlocked Packages and Managed second-generation packages (aka managed 2GPs). We want packaging to work as well for customers as they do for partners.
Unlocked Packages are designed primarily to address the packaging needs of customers. Unlocked packages offer a super-set of features compared to unmanaged packages.
Managed 2GPs are geared towards ISVs who want to develop and list apps on AppExchange. While Managed 2GPs are beta, there are still certain key parity features (Push Upgrades, LMA, ability to list on AppExchange, patch versions, etc.) that are missing in them. So, if you are a Salesforce Partner, it is recommended that you continue with first-Generation Managed Packages until we build those feature parity items in managed 2GPs.
(Back to the Table of Contents)
If you are an ISV that develops and lists apps on AppExchange, here are our recommendations (See here for info about different types of packages):
(Back to the Table of Contents)
In less than 5-10 minutes, you can build and test your Hello World App to get a feel for unlocked packages. The only precondition is that you have a Salesforce DX environment set up with Salesforce CLI and that you have enabled Dev Hub and Unlocked Packages in your Dev Hub Org.
If you haven’t done it already, refer to this documentation for setting up the Dev Hub and Packaging.
Follow these simple steps and you have for yourself a package!
Set up a directory on your local machine and copy the sample repo. Let’s presume this is the app that your team is building for meeting a business need.
git clone https://github.com/dreamhouseapp/dreamhouse-sfdx.git
cd dreamhouse-sfdx/
Authenticate to your Dev Hub org.
sfdx force:auth:web:login --setdefaultdevhubusername
Create a new unlocked package.
sfdx force:package:create --name Dreamhouse-App --packagetype Unlocked --path force-app --nonamespace
Note how the sfdx-project.json is automatically updated with information about this package.
Create a package version. When you create a package version, you are associating metadata with your package. Over the course of time, you may create many package versions for a given package. Once created, a package version serves as an immutable artifact containing a specific set of metadata. This is the same metadata that you specify at the package version creation step.
sfdx force:package:version:create --package Dreamhouse-App --installationkey mypkgisnowsecure#%^ --wait 20
In this example, force-app is the directory in which your package metadata is located in Salesforce DX format. This was specified when the the force:package:create
command was run in step # 3. The other pieces of information needed for package version creation are stored in sfdx-project.json. The installation key offers a security mechanism for your package version - this key has to be speicified while installing the package for the installation to be successful.
Create a scratch org where you can install the package.
sfdx force:org:create --definitionfile config/project-scratch-def.json --setalias sub1 --setdefaultusername
Install the package in the scratch org.
sfdx force:package:install --package Dreamhouse-App@0.1.0-1 --publishwait 20 --installationkey mypkgisnowsecure#%^ --wait 10
If Dreamhouse-App@0.1.0-1
is not the alias for the package version created in step 4, update the value for the --package
flag with the correct alias. See here for more info about package aliases.
Open the scratch org in the browser.
sfdx force:org:open
In the scratch org, go to Setup -> Installed Packages, where you can see that the package has been installed.
Click the Package Name and the View Components button to validate that the components present in the project are now deployed as part of the package.
Congratulations! You have now created and installed your first unlocked package!
(Back to the Table of Contents)
See here for a quick overview of unpackaged metadata.
Step 1 - Extract a small set of unpackaged, self-contained metadata from your production org and convert it to Salesforce DX format.
How to identify this set of self-contained metadata is a bit of a science and a bit of an art. You can try and select metadata that represents an app, or customization to an AppExchange app, or customizations to Sales Cloud or an Account object, or some set of metadata that represents a functional unit (e.g.: a library of apex classes). We know this is a challenging task. We plan to produce material to help in this. See this blog series that talks about DX and unlocked packages.
Step 2 - Push this metadata to a scratch org using force:source:push
and validate that this is the metadata that you want to be part of a new package. If you are missing some metadata, go back to Step 1.
Step 3 - Create an unlocked package using this metadata (see here for how to create a package). Make sure this package has no namespace (supply the --nonamespace
flag to the force:package:create
command). See here for more info about namespaces and packages.
Step 4 - Test the package in CI and UAT environments. If you encounter issues, you may have to go back to Step 1 and validate that you have the right set of metadata. Once the package has passed all CI runs and UAT on sandboxes, install the package in the production org. This installation does not deploy new metadata as what’s contained in the package is already present in the production org. But what this does is migrate the metadata from the unpackaged set to the package so that it is now part of the package in the production org. From this point forward, you can iterate over this metadata set using the package.
These steps, along with the specification of dependencies among packages, can help in organizing the unpackaged metadata into a set of interdependent packages.
(Back to the Table of Contents)
Package Creation
A package is a container of metadata. When you create a package, you specify some characteristic info about the package: name, description, namespace associated with it, package type and so on.
Package Version Creation
As your development team is working on some functionality, you, as a release manager, may want to take periodic snapshots of the functionality when it is in a functional state. Such snapshots are package versions. When the package version creation operation is executed, a copy of the current state of the metadata in the project folder (the directory specified in force:package:create
command) is used to create the package version. You can create any number of package versions. Each version, once created, is immutable and can be installed in any Salesforce org.
Package Install
A package install is an operation whereby the metadata of a package is deployed to the target org. A package install is actually a package version install - it is the deployment of metadata contained in a specific package version of a package. A package is typically associated with 100s or even 1,000s of package versions. When you install a package, you specify which one of the many versions you intend to install. Install and deploy mean the same in this context.
Package Upgrade
Installing a version on top of a previously installed package version is a package upgrade. When you perform a package upgrade, the metadata of the new package version is deployed to the org. The package upgrade process can add new metadata to the org, modify existing metadata, and may even delete and deprecate some metadata depending on what’s there in the new version of the package.
Package Downgrade
See here for more info about package downgrades.
Package Uninstall
This is an operation where you are deleting the metadata and associated data related to an installed package.
See here for how you can perform these operations using the Salesforce CLI.
(Back to the Table of Contents)
In Summer ‘18 release, we made a set of improvements to enhance the usability of packaging commands in the Salesforce DX CLI. As part of that, we introduced the concept of aliases to packages. Package aliases were developed to reduce the usage of package ids as the latter is non-intuitive.
As most of you already know, aliases are used elsewhere in the CLI; for E.g.: alias for a scratch org.
With package aliases, the following changes were introduced, all aimed at improving the usability of packaging commands:
force:package:create
command runs successfully, a package alias is automatically created in the packageAliases section of sfdx-project.json. E.g: "revenue-optimizer": "0HoB00000004CWDKA2"
. Here, the alias name (revenue-optimizer) is the name of the package supplied in the --name
attribute of force:package:create
command and the 0Ho id is the package id that it maps to.force:package:version:create
command runs successfully within the --wait
time specified, a package version alias is automatically created in the packageAliases section of sfdx-project.json. E.g: "revenue-optimizer@0.1.0-4": "04tB00000006DewIAE"
. Here, the alias name (revenue-optimizer@0.1.0-4) is the name of the package supplied in the name
attribute of force:package:create
command and the version number appended in the major.minor.patch-build number format. The id is the package version id that it maps to.--package
and --packages
, there is an option to supply either the package alias or the appropriate ids. Using the aliases approach makes the sfdx-project.json file, commands and scripts much more intuitive and readable.(Back to the Table of Contents)
See here if you want to first understand what these operations are intended for.
Development-side Commands
Create a package - force:package:create
Add, modify and remove metadata from a package - Update the workspace files
Get a listing of all packages - force:package:list
Update info about a package - force:package:update
Create a package version - force:package:version:create
Obtain info about the status of a package version create request - force:package:version:create:report
Obtain info about the status of all package version create requests - force:package:version:create:list
Get detailed info about a single package version - force:package:version:report
Get a listing of all package versions - force:package:version:list
Update info about a package version - force:package:version:update
Install-side Commands
Install a package - force:package:install
Status of an install request - force:package:install:report
Info about all installed packages in an org - force:package:installed:list
Uninstall a package - force:package:uninstall
Status of an uninstall request - force:package:uninstall:report
(Back to the Table of Contents)
Some of the sfdx-project.json updates are done automatically for you. See here for more info.
See this example below for a section of sfdx-project.json file
(this deliberately avoids package dependencies to keep things simple. See here for a simple example of package dependencies and here for a more complex scenario)
{
"packageDirectories": [
{
"package": "revenue-app",
"path": "common",
"default": true,
"versionNumber": "0.1.0.NEXT",
"versionName": "Summer 2018",
"versionDescription": "Summer 2018 Release",
"definitionFile": "force-app"
},
{
"package": "revenue-app-utils",
…
}
],
"namespace": "",
"sfdcLoginUrl": "https://login.salesforce.com",
"sourceApiVersion": "44.0",
"packageAliases": {
"revenue-app": "0HoB00000008OoZKAU",
"revenue-app-utils": "0HoB00000008OoYMZD"
}
}
package (required field) - this is the package and everything in this sub-section contains info about that package. You can use aliasing and specify the package alias here or directly specify the 0Ho id of the package. This info is auto-populated in the sfdx-project.json when the force:package:create
command executes successfully.
path (required field) - root folder where the source metadata of the package is stored in the local workspace in Salesforce DX format. The metadata in this folder is used to create the package version when the force:package:version:create
command is run. This info is auto-populated in the sfdx-project.json when the force:package:create
command executes successfully.
versionName (required field) and versionNumber (required field) - name and version number. The latter is in major.minor.patch.build format where each one of these is a whole number. See here for more info about package version numbers. This info is auto-populated in the sfdx-project.json when the force:package:create
command executes successfully.
versionDescription (optional field) - description of the package version that you’re creating.
definitionFile (optional field) - this is a json file similar to the scratch org definition file that you can use to specify features and org settings that need to be enabled for the successful deployment of your package metadata. For E.g.: if your package metadata requires multi-currency to be enabled in the target org before the metadata can be successfully deployed, this feature should be specified in the json file. In many scenarios, you may want to use the same json file for both package version creation and scratch org creation.
(Back to the Table of Contents)
The metadata coverage report (see here for more info) is the source of truth for metadata supported in unlocked packages. While the vision is to provide metadata API support for all Salesforce Metadata and enable everything to be packaged in an unlocked package, it is going to take a while to get there, and the metadata coverage report will track the progress. Having said this, singletons (things that have only one instance of them in an org) like org settings and preferences, and metadata without top-level ids (E.g.: Standard Value Sets) are NOT packageable in unlocked packages.
(Back to the Table of Contents)
An unlocked package can be installed in any Salesforce environment - scratch orgs, sandbox orgs, trial orgs, and production orgs (see here for a note on beta vs released state of a package version).
A package can be installed in two different ways:
Salesforce CLI command
force:package:install --package <package-alias or 04t id> --targetusername <org where the package should be installed>
Salesforce UI
By appending the following to the browser URL: packaging/installPackage.apexp?p0=<04t id>
The 04t is the package version ID. This represents the version of the package to install. The 04t ID is returned when the force:package:version:create
CLI command returns successfully. You can use force:package:version:list
command to get a list of package versions associated with a package.
See here if you want to know more about different packaging operations.
(Back to the Table of Contents)
In any given org, you can obtain information about installed packages in one of the following ways.
Salesforce CLI
force:package:installed:list
command
Salesforce UI
See here for how to install a package in an org.
(Back to the Table of Contents)
Unlocked Packages provide a very open framework for making metadata changes. Before we talk about these changes, make sure you understand the difference between a package and a package version. See here for more info. Also take a look at this for packaging operations.
Versioning is one of the core differentiating features of packaging. It is versioning that enables iterative development, where you can continually update an artifact (package) in a controlled and manageable way in response to business needs (feature requests and bug fixes).
When it comes to versioning and changes introduced in versions, it is helpful to look at them from two angles - development stage and deployment stage.
Development and Build Stages
When you create a new package version, you can introduce the following changes in relation to a previous package version:
The above-described changes can be applied in a variety of ways (Setup UI in scratch orgs, in VS Code, in Developer Console, etc.) and ultimately make it to the version control system for the project (See here for relationship between version control system and packages). The release manager then pulls in the right set of metadata to a local workspace and creates a new package version so that the package version captures these changes.
Deployment Stage
Let’s presume you are trying to install ver 2.0 of an unlocked package in an org where ver 1.0 is currently installed. During this package upgrade process, the following changes are applied:
(Back to the Table of Contents)
A package version is an immutable artifact that is a snapshot of a package with a specific set of metadata. A package version is created with a successful execution of the force:package:version:create
command. Every package version you create has a unique version number. The version number is in the major.minor.patch.build number format where major, minor, patch and build are integers grater than or equal to zero.
Here are some things to keep in mind with respect to version numbers:
versionNumber
field in sfdx-project.json. This is a required field.NEXT
keyword to simplify this. When you specify NEXT
as in 1.3.0.NEXT
, we auto-increment the build number for you. When you want to do the same with package dependencies, you can use LATEST
in the dependencies section of sfdx-project.json file. The NEXT
and LATEST
keywords currently work only with build numbers.(Back to the Table of Contents)
You have developed an unlocked package, taken it through all of the testing cycles - integration, user acceptance, etc. - and you are now ready to install it in your production org. One question that arises is, what happens if your admin has to make an emergency change to the metadata directly in the production org? For example, the admin might have noticed that some permission sets are granting too much access, a page layout is missing some critical fields, or a report is missing a key column. If this metadata is part of an unlocked package, should the admin contact the development team and take it through the full cycle of development, testing, UAT and then do the deployment? The answer is yes from a best practice of software development process perspective. But what if one or all of these changes need to be made right now!?
With unlocked packages, the admin has the flexibility to make these changes directly in production. The fact that these components belong to a package won’t restrict the flexibility that the admin has towards making changes. However, the admin has to ensure that the development team is informed of these changes. Once the development team is aware of these changes and incorporate them in the next version of the package, installing future versions of the package won’t undo the changes made by the admin in the production org. However, if the changes made directly in production are not applied to the metadata of the package by the development team, subsequent package upgrades will overwrite the changes made in production.
(Back to the Table of Contents)
See here for more info.
(Back to the Table of Contents)
There are some related scenarios here:
For scenarios 1 and 2, you delete the metadata from the DX project and build a new version of the package. When you install the new version in an org, the changes are applied. See here for more details. For scenario 3, you do the same if you determine that you want to permanently remove the metadata from the package.
See here for more information about scenario 2.
(Back to the Table of Contents)
Let’s suppose you have installed ver 1 of your unlocked package pkg1. As part of refactoring your App, you decide to move some metadata from pkg1 to a new package pkg2.
You will refactor the package by following these steps:
(Back to the Table of Contents)
In the context of packaging, a downgrade is installing a lower version of a package on top of a higher version. For E.g.: this is when you try to install ver 2.0 of your package in an org where ver 3.0 has been installed. When you downgrade a package, the following occurs:
You should consider any downgrade of a package carefully. Package downgrades can fail due to dependency scenarios. For E.g.: if ver 3.0 has an apex class that is referenced by another apex class in a different package, downgrading to ver 2.0 would fail with a user-friendly error message if that apex class is not present in ver 2.0 of the package.
(Back to the Table of Contents)
You can secure your packages by setting an installation key to your package versions. During the package installation process, you are challenged to supply the installation key and failing to provide it will abort the installation process.
You can set the installation key in two ways:
--installationkey
flag of the force:package:version:create
command. If you choose to skip this security feature, you have to supply the installationkeybypass
flag to the version create command. Not supplying either of these flags results in an error. This enforces a security-by-default mindset.--installationkey
flag of force:package:version:update
command.In future (safe harbor), we have plans to provide additional security mechanisms to enable enhanced security for your packages.
(Back to the Table of Contents)
When you create a package version using force:package:version:create
, we set the state of the package version to beta. Beta package versions are internal test candidates that are used in test cycles including CI. To prevent a beta package version from being inadvertently installed in production orgs, we prevent the installation of beta package versions in any org that is not a scratch org, sandbox org or Developer Edition org.
As part of your development process, you end up creating lots and lots of package versions that are all of beta state. When a package version passes all tests including UAT (User Acceptance Testing), you can promote that package version to be a release candidate by issuing the following CLI command:
force:package:version:promote --package expense-manager@1.3.12-26
force:package:version:promote --package 04tB0000000IB1EIAW
A package version promoted to released state can be installed in any org.
For a given major.minor.patch package version number (see here for more info about version numbers), there can be at most one package version in released state. Once you set a package version to released state, you cannot undo that operation. It is recommended that you increment major, minor and/or patch version number in your sfdx-project.json file once you promote a package version. We will try and automate this in future releases using constructs similar to npm version minor.
(Back to the Table of Contents)
Yes. One of the value propositions of packages is that you can develop and maintain a set of interdependent packages. By supporting dependencies, packages promote modular development with a dependency framework.
The following are some of the main use cases around dependencies:
Keep the following in mind when you think of package dependencies:
See here to see how you can express dependencies in sfdx-project.json
and see here for a more advanced example.
(Back to the Table of Contents)
See here to know more about package dependencies.
You express dependencies within the packageDirectories section of sfdx-project.json.
The following are the different types of supported dependencies
An unlocked package depending on another package in the same dev hub
"dependencies": [
{
"package": "utils-pkg",
"versionNumber": "2.5.0.LATEST"
}
]
This expresses that the current package depends on another package of version number 2.5 with package alias utils-pkg.. This package can be a managed second-generation package or another unlocked package. By using the keyword LATEST, you can iterate on the two packages simultaneously.
An unlocked package depending on another package developed in a different dev hub
There are two main use cases for this:
"dependencies": [
{
"package" : "apex-lib@1.7.4"
}
]
This expresses that the current package depends on another package with package alias apex-lib@1.7.4
. This is the way to specify dependencies if the package that the current package depends on, was developed in a different dev hub. You cannot use the LATEST
keyword in this scenario.
For a more complex scenario of package dependencies, please see here.
(Back to the Table of Contents)
Package dependencies are used during development time. E.g.: if you are developing packages and if your apex class in package pkg-y is invoking another apex class that is present in package pkg-x, you should express that pkg-y depends on pkg-x for the package version creation of pkg-y to succeed. (See here for how to express these dependencies)
Package dependencies are enforced at installation time. If pkg-y depends on pkg-x, you will have to install pkg-x before you can install pkg-y; otherwise the installation of pkg-y fails with an error message. Also, you have to ensure that the appropriate versions of the package are installed in the org. For E.g.: if pkg-y ver 4.0 has a Lightning Page that uses an apex controller from pkg-x ver 3.0, attempting to install pkg-y ver 4.0 fails in an org where pkg-x ver 2.0 is installed. See here for how you can automate the installation of dependent packages.
(Back to the Table of Contents)
See here to know more about package dependencies. See here for a simple example of package dependencies.
Let’s consider the following scenario:
Package Reimburse Me App depends on two packages - Expense Manager and Travel Booker. Expense Manager depends on an apex library built in-house as an unlocked package - Utils. Travel Booker is a package that extends a purchased AppExchange App Travel Anywhere!
packageDirectories section of sfdx-project.json file for Travel Booker unlocked package
(working on ver 3.2 of the Travel Booker package that depends on ver 4.5 of Travel Anywhere! AppExchange package installed in production org. The package version id of ver 4.5 of the AppExchange App is 04tB0000000IB1EIAW)
{
"path": "travel-booker-workspace",
"package": "travel-booker",
"versionName": "v 3.2",
"versionDescription": "Summer 2018 Release",
"versionNumber": "3.2.0.NEXT",
"dependencies": [
{
"package" : "travel-anywhere@4.5.0"
}
]
}
packageDirectories section of sfdx-project.json file for Expense Manager package
(working on ver 4.7 of the Expense Manager package that depends on ver 2.6 of Utils package whose package id is 0HoB00000004CFpKAL)
{
"path": "expense-manager-workspace",
"package": "expense-manager",
"versionName": "v 4.7",
"versionDescription": "Summer 2018 Release",
"versionNumber": "4.7.0.NEXT",
"dependencies": [
{
"package": "utils",
"versionNumber": "2.6.0.LATEST"
}
]
}
packageDirectories section of sfdx-project.json file for Reimburse Me package
(working on ver 3.8 of the Reimburse Me package that depends on ver 3.2 of Travel Booker package and ver 4.7 of Expense Manager package)
Note: you have to declare all of the transitive dependencies in the order in which these packages should be installed from a dependency stand-point.
{
"path": "reimburse-me-workspace",
"package": "reimburse-me",
"versionName": "v 3.8",
"versionDescription": "Summer 2018 Release",
"versionNumber": "3.8.0.NEXT",
"dependencies": [
{
"package" : "travel-anywhere@4.5.0"
},
{
"package": "travel-booker",
"versionNumber": "3.2.0.LATEST"
},
{
"package": "utils",
"versionNumber": "2.6.0.LATEST"
},
{
"package": "expense-manager",
"versionNumber": "4.7.0.LATEST"
}
]
}
A note on package aliases
See here to better understand package aliases. For the sfdx-project.json to look like what’s shown above, it is presumed that there is a packageAliases
section in the sfdx-project.json
that does the alias-to-id mapping.
"packageAliases": {
"travel-anywhere@4.5.0": "04tB0000000IB1EIAW",
"travel-booker": "0HoB00000004CFuKAM",
"utils": "0HoB00000004CFpKAL",
"expense-manager": "0HoB00000004CFuKAN",
"reimburse-me" : "0HoB00000004CFuKAP"
}
(Back to the Table of Contents)
Let’s presume your package pkgC depends on package pkgB which in turn depends on pkgA. In the target org, we require packages of appropriate versions to be installed in this order: pkgA, pkgB and pkgC.
In Winter ‘19, we have made the process of installing dependent packages easier by surfacing info about dependent packages including the minimum version required and dependency order. You can use force:data:soql:query
and run a statement like SELECT Dependencies FROM SubscriberPackageVersion WHERE Id='04tB0000000NmnHIAS
to get dependency information in correct order. In this example, 04tB0000000NmnHIAS
is the package version id of pkgC.
See this in the product guide for more info.
(Back to the Table of Contents)
The Dev Hub in which the package was developed is the owner of the package. The association between the dev hub and a package occurs when you execute the force:package:create
command. The Dev Hub org against which this command is run is the owner of the package.
Please keep in mind the following about Dev Hub and unlocked package:
force:package:create
command can be successfully executed.force:package:install
command.(Back to the Table of Contents)
A namespace is a unique identifier that is owned by your company when you register it with Salesforce. If you associate a namespace (like Acme) with a package (see here for how to associate namespaces with Dev Hub), the API names of all metadata added to the package will have the prefix Acme__. Hence, namespaces offer a mechanism to name and organize metadata in your org.
Keep the following in mind when you think of namespaces and packages:
force:package:create
) and cannot be changed, once associated.(Back to the Table of Contents)
It is currently not possible to delete package or package versions. In a future release, we will provide capabilities for the same. For now, you can rename them (using force:package:update
and force:package:version:update
Salesforce CLI commands) to denote that you are no longer using them.
Click here for more info about packaging operations.
(Back to the Table of Contents)
When it comes to unlocked packages, the source of truth is your version control system (vcs). Having said that, packages don’t explicitly link to a vcs. The step where you link the metadata that you want in a package to your package is in the force:package:create
step and that requires the directory name of your SFDX project, not a vcs repo. Here are some best practices you can follow to ensure your vcs tracks changes made to your packages:
--tag
field in the force:package:version:create
or force:package:version:update
commands to store any vcs related tagging information (E.g.: commit info).(Back to the Table of Contents)
Locked packages were in Pilot mode for a brief time and that pilot is no longer available. We may bring back Locked packages in future but that is uncertain with no set date. Unlocked Packages are Generally Available (GA) in Winter ‘19 and we recommend that you use unlocked packages.
(Back to the Table of Contents)
We have lots of additional information that goes into the details of how to work with Salesforce DX and packages. Following are some helpful resources:
Trailblazer Community for Salesforce DX
Trailhead Modules on Salesforce DX
Salesforce CLI Command Reference
Trailblazer Community for Packaging
Trailhead Module on Unlocked Packages