DX Packaging
Why use packaging?
Deploying Metadata using Packages to PROD org
How we deploy Metadata to PROD orgs today
- Ant Migration Tool
- SFDX force:mdapi
Source Based Development
Org-based development
Modular Development - developing towards module not towards org
DCP - Developer Controlled Packages - Modular Development to Package Development
$ sfdx force:mdapi -h
Usage: sfdx force:mdapi:COMMAND [command-specific-options]
retrieve and deploy metadata using Metadata API
sfdx force:mdapi commands: (get help with sfdx help force:mdapi:COMMAND)
force:mdapi:convert convert metadata from the Metadata API format into the Salesforce DX format
force:mdapi:deploy deploy metadata to an org using Metadata API
force:mdapi:deploy:report check the status of a metadata deployment
force:mdapi:retrieve retrieve metadata from an org using Metadata API
force:mdapi:retrieve:report check the status of a metadata retrieval
Changesets
- Sandbox based development
- Collect the set of metadata should be transported
- Deploy to PROD instances
Unmanaged Packages
- Build an app
- Put it into unmanaged package
Challenges with current methods
Absence of an Immutable Artifcat
- Starts with list of components to deployed from one env to another
- No easy way to aggregating and knowing set-of-metadata moving to diffrent stages
- Scratch org --> Deploy Metadata to Sanbox orgs --> UAT --> PROD
- Above methods do not offer this feature : Immutable Artifcat
Changes and Upgrades
- Change versioning all the way to the PROD
- No concept of versioning in Changesets , Unmanaged packages, Ant migration
- Once deployed -- it is happy soup of unpackaged set of metadata
- No concept of versioning in Changesets , Unmanaged packages, Ant migration
- Change versioning all the way to the PROD
- Organization in PROD org
- AppExchange Apps
- Unpackaged set of metadata - difficult to manage
- No concept of ownership in metadata
- who is responisble for the fields, validation rules,...
Organizing Metadata into Packages
Repeatble, Scriptable, Trackable
- DX packages we can create Immutable Artifcats on a repeatable manner
- Version the changes you are making - maintained in the VCS
Versioning is built into the packaging
- Checkout a version of the package - snapshot - package version
- Make changes - add/edit/remove components
Can be used across the environments - transporting
Helps to organize metadata in the org
ISV packaging
- Manageability rules - ensures that packages by ISV does not break customer orgs
- This model does not work for Enterprise customers
- DX Packaging meets Enterprise customers use cases
Developing and Deploying an App using DX and Packages
- Start with SFDX
- Set up VCS
- Biz Process
- Developer Spins up scratch org
- Get Product Designer / Admin to login to Scratch org
- Use UI to build biz process, workflows, page-layout
- Developer pull these UI based changes to the scratch org
- Developer or release manager creates the package using sfdx cli to get a immutable package
- Use the package in CI Runs
- Use the same set of packages across the enviroments - sandboxes including UAT
- Use sfdx cli to install same package into PROD
Maintaining and Enhancing an App using Packages
Organizing Unpackaged Metadata using Packages to the benefits of versioning, iterating with help of DX packaging
TO
TO
Guidelines and Criteria in Identifying metadata that can be migrated into a Package
Things to note
Org shape
- Features
- Preferences
- Settings
FAQ
- How to get list of packages installed in an org ```bash
Usage: sfdx force:package:installed:list [-u
list the org’s installed packages
Flags: -u, --targetusername TARGETUSERNAME username or alias for the target org; overrides default target org --json format output as json --loglevel LOGLEVEL logging level for this command invocation (error*,trace,debug,info,warn,fatal)
Examples: $ sfdx force:package:installed:list $ sfdx force:package:installed:list -u me@example.com
- How to install a package listed above into a target org
```bash
$ sfdx force:package:install -h
Usage: sfdx force:package:install [-i <id>] [-w <minutes>] [-k <string>] [-p <minutes>] [-r] [--package <string>] [-u <string>] [--json] [--loglevel <string>]
install a package in the target org
Flags:
-i, --id ID WARNING: The flag "id" has been
deprecated and will be removed in
v43.01.0 or later. Use "--package"
instead.
-k, --installationkey INSTALLATIONKEY installation key for key-protected
package (default: null)
-r, --noprompt allow Remote Site Settings and Content
Security Policy websites to send or
receive data without confirmation
-p, --publishwait PUBLISHWAIT number of minutes to wait for subscriber
package version ID to become available
in the target org WARNING: The short
name "-p" has been deprecated and will
be removed in v44.0 or later. Use
"--publishwait" instead.
-u, --targetusername TARGETUSERNAME username or alias for the target org;
overrides default target org
-w, --wait WAIT number of minutes to wait for
installation status
--json format output as json
--loglevel LOGLEVEL logging level for this command
invocation
(error*,trace,debug,info,warn,fatal)
--package PACKAGE ID (starts with 04t) or alias of the
package version to install
Supply the ID of the package version you want to install. The package installs in your default target org unless you supply the username for a different target org.
Examples:
$ sfdx force:package:install --package 04t... -u me@example.com
$ sfdx force:package:install --package awesome_package_alias
$ sfdx force:package:install --package "Awesome Package Alias"
Define the dependencies between packages declaratively
- Example: Expense package has dependency on Common-Util module
- In scratch org install - dependent package and packages it depends on
To use a Managed package in Scratch org, install that managed package in Scaratch org and DCP for the extensions and start the development process
Size of the DCP is determined by the limits of the metadata api
Difference between Package2 and DCP
- Package2 is a umberlla term covering different types of packaging (for partners and enterprise customers)
- DCP is customer oriented - enterprise customers doing modular development using packaging
App Hub - UI for SFDX
Convert metadata from the Metadata API format into the Salesforce DX format
$ sfdx force:mdapi:convert -h
Usage: sfdx force:mdapi:convert -r <directory> [-d <directory>] [--json] [--loglevel <string>]
convert metadata from the Metadata API format into the Salesforce DX format
Flags:
-d, --outputdir OUTPUTDIR the output directory to store the Salesforce
DX–formatted source
-r, --rootdir ROOTDIR (required) the root directory containing the
Metadata API–formatted metadata
--json format output as json
--loglevel LOGLEVEL logging level for this command invocation
(error*,trace,debug,info,warn,fatal)
To work with metadata that you retrieved via Metadata API using the Salesforce DX tools, convert the metadata to the Salesforce DX source format using"sfdx force:mdapi:convert".
To convert the source back to the Metadata API format, so that you can deploy it using "sfdx force:mdapi:deploy", run "sfdx force:source:convert".
Examples:
$ sfdx force:mdapi:convert -r <path to source>
$ sfdx force:mdapi:convert -r <path to source> -d <path to outputdir>
Create a second-generation package (package2)
$ sfdx force:package2:create -h
Usage: sfdx force:package2:create -n <string> [-o <string>] [-d <string>] [-e] [-v <string>] [--json] [--loglevel <string>]
WARNING: The command "create" has been deprecated and will be removed in v43.01.0 or later. Use "force:package:create" instead.
create a second-generation package
Flags:
-o, --containeroptions CONTAINEROPTIONS [*Managed | Unlocked]
container options for the
package2
(Managed=DeveloperManagedSubscriberManaged,
Unlocked=DeveloperControlledSubscriberEditable)
-d, --description DESCRIPTION package description
-n, --name NAME (required) package name
-e, --nonamespace creates the package with no
namespace; available only for
developer-controlled packages.
-v, --targetdevhubusername TARGETDEVHUBUSERNAME username or alias for the dev
hub org; overrides default dev
hub org
--json format output as json
--loglevel LOGLEVEL logging level for this command
invocation
(error*,trace,debug,info,warn,fatal)
First, use this command to create a second-generation package. Then create a package version.
Examples:
$ sfdx force:package2:create -n PackageName -d 'My New Package' -o Unlocked
Run 'sfdx force:package2:list' to list all second-generation packages in the Dev Hub org.
Example
$ sfdx force:package2:create --containeroptions Unlocked --name "Expense 2018.05.11 10:20"
Successfully created a second generation package (package2):
=== Ids
....
# Unlocked -- allows full editablity in the org for allowing emergency patches
# Managed (Locked) -- allows full no editablity in the org
With Package id:
Create a second-generation package version
$ sfdx force:package2:version:create -h
Usage: sfdx force:package2:version:create [-i <id>] [-d <directory>] [-b <string>] [-t <string>] [-k <string>] [-w <minutes>] [-v <string>] [--json] [--loglevel <string>]
WARNING: The command "version:create" has been deprecated and will be removed in v43.01.0 or later. Use "force:package:version:create" instead.
create a second-generation package version
Flags:
-b, --branch BRANCH the package version’s branch
-d, --directory DIRECTORY path to directory that
contains the contents of the
package version
-k, --installationkey INSTALLATIONKEY installation key for
key-protected package
(default: null)
-i, --package2id PACKAGE2ID ID of the parent package
(starts with 0Ho)
-t, --tag TAG the package version’s tag
-v, --targetdevhubusername TARGETDEVHUBUSERNAME username or alias for the dev
hub org; overrides default dev
hub org
-w, --wait WAIT minutes to wait for the
package version to be created
(default:0)
--json format output as json
--loglevel LOGLEVEL logging level for this command
invocation
(error*,trace,debug,info,warn,fatal)
The package version is based on the package contents in the specified directory.
To retrieve details about a package version create request, including status and package2 version ID (05i), run "sfdx force:package2:version:create:get -i 08c...".
To list package version creation requests in the org, run "sfdx force:package2:version:create:list".
Examples:
$ sfdx force:package2:version:create -d common
$ sfdx force:package2:version:create -i 0Ho... -d common
$ sfdx force:package2:version:create -d force-app
## This is async, will queue the request and provide the command to run to get the status
## The package is created from the source in the local folder in the file system
App
- Directory structure of DX workspace
# Retrive metadata
$ sfdx force:mdapi:retrieve -h
Usage: sfdx force:mdapi:retrieve -r <directory> [-a <number>] [-w <minutes>] [-k <filepath>] [-d <directory>] [-p <string>...] [-s] [-i <id>] [-u <string>] [--json] [--loglevel <string>] [--verbose]
retrieve metadata from an org using Metadata API
Flags:
-a, --apiversion APIVERSION target API version for the retrieve
(default 42.0)
-i, --jobid JOBID WARNING: The flag "jobid" has been
deprecated and will be removed in
v41.01.0 or later. Instead, use
"sfdx force:mdapi:retrieve:report -i
<jobId> -r <targetDir>".
-p, --packagenames PACKAGENAMES a comma-separated list of packages
to retrieve
-r, --retrievetargetdir RETRIEVETARGETDIR (required) directory root for the
retrieved files
-s, --singlepackage a single-package retrieve (default:
false)
-d, --sourcedir SOURCEDIR source dir to use instead of default
manifest sfdx-project.xml
-u, --targetusername TARGETUSERNAME username or alias for the target
org; overrides default target org
-k, --unpackaged UNPACKAGED file path of manifest of components
to retrieve
-w, --wait WAIT wait time for command to finish in
minutes (default: -1 (no limit))
--json format output as json
--loglevel LOGLEVEL logging level for this command
invocation
(error*,trace,debug,info,warn,fatal)
--verbose verbose output of retrieve result
The default target username is the admin user for the default scratch org. You can retrieve and deploy up to 10,000 files or 400 MB (39 MB compressed) at one time.
To retrieve a package with a space in its name, enclose the name in single quotes.
Example:
$ sfdx force:mdapi:retrieve -s -r ./mdapipkg -u <username> -p 'My Package'
Install a package in the target org
$ sfdx force:package:install -h
Usage: sfdx force:package:install [-i <id>] [-w <minutes>] [-k <string>] [-p <minutes>] [-r] [--package <string>] [-u <string>] [--json] [--loglevel <string>]
install a package in the target org
Flags:
-i, --id ID WARNING: The flag "id" has been
deprecated and will be removed in
v43.01.0 or later. Use "--package"
instead.
-k, --installationkey INSTALLATIONKEY installation key for key-protected
package (default: null)
-r, --noprompt allow Remote Site Settings and Content
Security Policy websites to send or
receive data without confirmation
-p, --publishwait PUBLISHWAIT number of minutes to wait for subscriber
package version ID to become available
in the target org WARNING: The short
name "-p" has been deprecated and will
be removed in v44.0 or later. Use
"--publishwait" instead.
-u, --targetusername TARGETUSERNAME username or alias for the target org;
overrides default target org
-w, --wait WAIT number of minutes to wait for
installation status
--json format output as json
--loglevel LOGLEVEL logging level for this command
invocation
(error*,trace,debug,info,warn,fatal)
--package PACKAGE ID (starts with 04t) or alias of the
package version to install
Supply the ID of the package version you want to install. The package installs in your default target org unless you supply the username for a different target org.
Examples:
$ sfdx force:package:install --package 04t... -u me@example.com
$ sfdx force:package:install --package awesome_package_alias
$ sfdx force:package:install --package "Awesome Package Alias"
Org with newly installed package
Exploring the installed package
Updating the packaging
Structure of sfdx-project.json file
Create Package and Package Version
The "NEXT" token
Key Points
- Sharing metadata:
- Packages can depend on each other
- Depenedcies can be enforced at build time
- Check of circular references
- Inter-package dependencies check during the build of packages, if there any issues, the transaction will be rolled back
- Common dependencies
- Package A and B are using util Package U
- Salesforce does not have class loader, this issue needed by worked by the developer to maintain the forward compatability
Finding out depreciated items in the package
- Tooling API can be used for this
- We do not hard-delete items
- Explicit hard-delete is coming soon
Scratch orgs have listener for the metadata changes
Delta packaging is coming soon
Enable Packaging 2 (Beta) in Dev Hub Org
Video: How Everyone Can Leverage Salesforce DX Packaging
Video: Simplify your code with Salesforce DX and module development
Video: Second Generation Packaging for Customers and Partners
List Package2
$ sfdx force:package2:list
No results found
Trailhead
Resouces
Trailblazer Community
FAQs
Webinar
MetadataComponentDependency (API Version 43.0 -- currently in Pilot)
Use SOQL queries to list the relationships between the metadata components in your org. The query results include one row for each relationship.
Example: Show all references to the Apex class (Type) YourClass (Name)
-- shows pages, components, flows, and other classes that YourClass depends on
SELECT MetadataComponentName,
MetadataComponentType
FROM MetadataComponentDependency
WHERE
RefMetadataComponentType = 'ApexClass'
AND
RefMetadataComponentName = 'YourClass'
Example: Shows all references to a field, including references from layouts, Apex code, flows, reports, and so on
-- queries FieldDefinition object
-- shows all the metadata components that the field with the ID yourFieldId depends on
SELECT MetadataComponentName,
MetadataComponentType
FROM MetadataComponentDependency
WHERE
RefMetadataComponentId = yourFieldId