A diff package is a variant of 'source package' , where the contents of the package only contain the components that are changed. This package is generated by sfpowerscripts by computing a git diff
of the current commit id against a baseline set in the Dev Hub Org
A diff package mimics a Change Set model, where only changes are contained in the artifact. As such, this package is always an incremental package. It only deploys the changes incrementally compared to baseline and applied to the target org. Unless both previous version and the current version have the exact same components, a diff package can never be rolled back, as the impact on the org is unpredictable. It is always recommended to roll forward a diff package by fixing or creating a necessary change that counters the impact that you want on the target orgs.
Diff packages doesnt work with scratch orgs. It should be used with sandboxes only.
A diff package is the least consistent package among the various package types available within sfpowerscripts, and should only be used for transitioning to a modular development model as prescribed by flxbl
The below example demonstrates a sfdx-project.json where the package unpackaged
is a diff package. You can mark a diff package with the type 'diff'. All other attributes applicable to source packages are applicable for diff packages.
A manual entry in sfpowerscripts_Artifact2__c
custom object should be made with the name of the package and the baseline commit id and version. Subsequent deployments will automatically reset the baseline when the package gets deployed to Dev Hub
Source Packages is an sfp cli feature that mimics the behaviour of native unlocked packages.
Source Packages are metadata deployments from a Salesforce perspective, it is a group of components that are deployed to an org. Unlocked packages are a First Class Salesforce deployment construct, where the lifecycle is governed by the org, such as deleting/deprecating metadata and validating versions.
We always recommend using unlocked packages over source packages whenever you can. As a matter of preference, this is our priority of package types
Source Packages
Source Packages are typically used for application-config (configuring an application delivered by a managed package such as changes to help text/description of fields ) or when you come across these constraints
Facing bugs while deploying the metadata using unlocked packages
Unlocked Package validation takes too long (still we recommend go org-dependent)
Dealing with metadata that is global or org-specific in nature (such as queues, profiles, etc or composite UI layouts, which doesn't make sense to be packaged using unlocked package)
Development teams who are starting to adopt package-based development and want to organize their metadata
A Salesforce Org can be composed only with source packages, however the lack of dependency validation as in unlocked packages, lack of automated destruction of changes can make it a bit challenging. As salesforce org is not aware of the source package, there is no component lock , so another source package with same metadata component can alwasy overwrite a metadata component deployed by another package. For these, reasons, we always recommend you prefer unlocked package or its variant org dependent unlocked packages.
An example of a common metadata component that typically gets overridden is Custom Labels which can span across multiple packages.
Source packages can depend on other unlocked packages or managed packages, however dependencies of source packages are validated during deployment time, ie., source packages assume that dependent metadata is already there in your org before the metadata in the source package is being deployed. That being said, for purposes of development in scratch org, you could add 'unlocked/managed package' dependencies to a source package, so sfp cli commands like prepare and validate (in sfpowerscripts:orchestrator) will install the dependencies to the target org before proceedint to install source package
Unlocked/Org Dependent Unlocked Packages
There is a huge amount of documentation on unlocked packages. Here are list of curated links that can help you get started on learning more about unlocked package
The Basics
Advanced Materials
The following sections deals with more of the operational aspects when dealing with unlocked packages
Unlocked Packages, excluding Org-Dependent unlocked packages have mandatory test coverage requirements. Each package should have minimum of 75% coverage requirement. A validated build (or build command in sfp) validates the coverage of package during the build phase. To enable the feedback earlier in the process, sfp provide you functionality to validate test coverage of a package such as during the Pull Request Validation process.
For unlocked packages, we ask users to follow a semantic versioning of packages.
Please note Salesforce packages do not support the concept of PreRelease/BuildMetadata. The last segment of a version number is a build number. We recommend to utilize the auto increment functionality provided by Salesforce rather than rolling out your own build number substitution ( Use 'NEXT' while describing the build version of the package and 'LATEST' to the build number where the package is used as a dependency)
Note that an unlocked package must be promoted before it can be installed to a production org, and either the major, minor or patch (not build) version must be higher than the last version of this package which was promoted. These version number changes should be made in the sfdx-project.json
file before the final package build and promotion.
Unlocked packages provide traceability in the org by locking down the metadata components to the package that introduces it. This feature which is the main benefit of unlocked package can also create issues when you want to refactor components from one package to another. Let's look at some scenarios and common strategies that need to be applied
For a project that has two packages.
Package A and Package B
Package B is dependent on Package A.
Remove a component from Package A, provided the component has no dependency
Solution: Create a new version of Package A with the metadata component being removed and install the package.
Move a metadata component from Package A to Package B
Solution: This scenario is pretty straight forward, one can remove the metadata component from Package A and move that to Package B. When a new version of Package A gets installed, the following things happen:
If the deployment of the unlocked package is set to mixed, and no other metadata component is dependent on the component, the component gets deleted.
On the subsequent install of Package B, Package B restores the field and takes ownership of the component.
Move a metadata component from Package B to Package A, where the component currently has other dependencies in Package B
Solution: In this scenario, one can move the component to Package A and get the packages built. However during deployment to an org, Package A will fail with an error this component exists in Package B. To mitigate this one should do the following:
Deploy a version of Package B which removes the lock on the metadata component using deprecate mode. Some times this needs extensive refactoring to other components to break the dependencies. So evaluate whether the approach will work.
If not, you can go to the UI (Setup > Packaging > Installed Packages > <Name of Package> > View Components and Remove) and remove the lock for a package.
Package dependencies are defined in the sfdx-project.json. More information on defining package dependencies can be found in the Salesforce docs.
Let's unpack the concepts utilizing the above example:
There are two unlocked packages
Expense Manager - Util is an unlocked package in your DevHub, identifiable by 0H in the packageAlias
Expense Manager - another unlocked package which is dependent on ' Expense Manager - Util', 'TriggerFramework' and 'External Apex Library - 1.0.0.4'
External Apex Library is an external dependency, it could be a managed package or any unlocked package released on a different Dev Hub. All external package dependencies must be defined with a 04t ID, which can be determined from the installation URL from AppExchange or by contacting your vendor.
Unlocked packages have two build modes, one with skip dependency check and one without. A package being built without skipping dependency check cant be deployed into production and can usually take a long time to build. sfp cli tries to build packages in parallel understanding your dependency, however some of your packages could spend a significant time in validation.
During these situations, we ask you to consider whether the time taken to build all validated packages on an average is within your build budget, If not, here are your options
Move to org dependent package: Org-dependent unlocked packages are a variant of unlocked packages. Org-dependent packages do not validate the dependencies of a package and will be faster. However please note that all the org's where the earlier unlocked package was installed, had to be deprecated and the component locks removed, before the new org-dependent unlocked package is installed.
Move to source-package: Use it as the least resort, source packages have a fairly loose lifecycle management.
Create a source package and move the metadata and any associated dependencies over to that particular package.
Org-dependent unlocked packages, a variation of unlocked packages, allow you to create packages that depend on unpackaged metadata in the target org. Org dependent package is very useful in the context of orgs that have lots of metadata and is struggling with understanding the dependency while building a ''
Org dependent packages significantly enhance the efficiency of #flxbl projects who are already on scratch org based development. By allowing installation on a clean slate, these packages validate dependencies upfront, thereby reducing the additional validation time often required by unlocked packages.
Org-dependent unlocked packages bypass the test coverage requirements, enabling installation in production without standard validation. This differs significantly from metadata deployments, where each Apex class deployed must meet a 75% coverage threshold or rely on the org's overall test coverage. While beneficial for large, established orgs, this approach should be used cautiously.
To address this, sfpowerscripts incorporates a default test coverage validation for org-dependent unlocked packages during the validation process. To disable this test coverage check during validation, additional attributes must be added to the package directory in the sfdx-project.json
file.
sfp cli supports operations on various types of packages within your repository. A short summary on the comparison between different package types is provided below
Dependency Validation
Occurs during package creation
Occurs during package installation
Occurs during package installation
N/A
Occurs during package installation
Dependency Declaration
Yes
Yes (supported by sfp)
Yes
Yes
Yes (supported by sfp)
Requires dependency to be resolved during creation
Yes
No
No
N/A
No
Supported Metadata Types
Unlocked Package Section in Metadata Coverage Report
Unlocked Package Section in Metadata Coverage Report
Metadata API Section in Metadata Coverage Report
N/A
Metadata API Section in Metadata Coverage Report
Code Coverage Requirement
Package should have 75% code coverage or more
Not enforced by Salesforce, sfp by default checks for 75% code coverage
Each apex class should have a coverage of 75% or above for optimal deployment, otherwise the entire coverage of the org will be utilized for deployment
N/A
Each apex class that's part of the delta between the current version and the baseline needs a test class and requires a coverage of 75%.
Component Lifecycle
Automated
Automated
Explicit, utilize destructiveManifest or manual deletion
N/A
Explicit, utilize destructiveManifest or manual deletion
Component Lock
Yes, only one package can own the component
Yes, only one package can own the component
No
N/A
No
Version Management
Salesforce enforced versioning; Promotion required to deploy to prod
Salesforce enforced versioning; Promotion required to deploy to prod
sfp enforced versioning
sfp enforced versioning
sfp enforced versioning
Data packages are a sfpowerscripts construct that utilise the to create a versioned artifact of Salesforce object records in csv format, which can be deployed to the a Salesforce org using the sfpowerscripts package installation command.
The Data Package offers a seamless method of integrating Salesforce data into your CICD pipelines , and is primarily intended for record-based configuration of managed package such as CPQ, Vlocity (Salesforce Industries), and nCino.
Data packages are a wrapper around SFDMU that provide a few key benefits:
Ability to skip the package if already installed: By keeping a record of the version of the package installed in the target org with the support of an unlocked package, sfpowerscripts can skip installation of data packages if it is already installed in the org
Versioned Artifact: Aligned with sfpowerscripts principle of traceability, every deployment is traceable to a versioned artifact, which is difficult to achieve when you are using a folder to deploy
Orchestration: Data package creation and installation can be orchestrated by sfpowerscripts, which means less scripting
Simply add an entry in the package directories, providing the package's name, path, version number and type (data). Your editor may complain that the 'type' property is not allowed, but this can be safely ignored.
Data packages support the following options, through the sfdx-project.json.
sfpowerscripts support vlocity RBC migration using the vlocity build tool (vbt). sfpowerscripts will be automatically able to detect whether a data package need to be deployed using vlocity or using sfdmu. (Please not to enable vlocity in preparing scratchOrgs, the enableVlocity flag need to be turned on in the pool configuration file)
A vlocity data package need to have vlocityComponents.yaml file in the root of the package directory and it should have the following definition
The same package would be defined in the sfdx-project.json as follows
Export your Salesforce records to csv files using the . For more information on plugin installation, creating an export.json file, and exporting to csv files, refer to Plugin Basic > Basic Usage in SFDMU's .
Refer to this for more details on how to add a pre/post script to data package