· tutorials · 5 min read
How to use Unlocked Packages - Tutorial
Leverage unlocked packages in Salesforce development to segment your features.
In Salesforce development, there are two ways of managing code. Org development, and package development.
Org development is the idea of keeping all code inside an individual Salesforce organization. In this model, all apex code, custom fields, and any other metadata are all tracked inside the org. This is sometimes referred to as Happy Soup.
This is a great way of developing Salesforce software. It is also what most developers are familiar with. But using this approach can lead to issues with:
- Distributing to more than one production org
- Managing dependencies
To circumvent this, we can organize features inside of packages. With the package development model, we can distribute our code as-is to many orgs. Packages come in flavors like:
- Managed packages (from the appexchange)
- Unlocked packages
We are going to dive into unlocked packages, as they are a great way of segmenting feature sets into individual packages.
Requirements
Before we get started, we’ll need a few boxes checked.
First, ensure you have the SF CLI installed.
Additionally, you will need a DevHub org to link these packages to. If you don’t have a DevHub, you can:
- Go to developer.salesforce.com
- Create a new org
- Go to Setup -> DevHub
- Enable Dev Hub
- Enable Unlocked packages.
Then, you can authenticate your dev hub with the following command:
sf org login web --set-default-dev-hub --alias MyDevHub
Dev Environment Setup
Now that you are authenticated, it’s time to write some code. We need a project to store this code. My favorite way of performing this is using the template I built to make a new repo, then pull the repo into my local machine.
Initial Package Creation
Then, you can create your package with this command.
sf package create --name "Clever Package Name" --path force-app --package-type Unlocked
- You pass in a package name
- Tell it where the code lives with
--path
- Specify that we are using an unlocked package
We can see these details inside the sfdx-project.json
. This is the file that showcases:
- Package Name
- Version Name
- Version Number
- Version Description
We can also add additional fields like:
releaseNotesUrl
to showcase the patch notes
We also need a place to do some of this customization. We can use a scratch org to develop and make customizations as needed.
Using the following command, we can create a scratch org:
sf org create scratch --edition developer --alias scratch-org
We can then open the scratch org, using the following command:
sf org open --target-org scratch-org
Then we can add any customizations needed. This can be in the form of custom fields, custom apex, or any other Salesforce related metadata.
For Apex classes, we can create them like usual. Create an apex class and some accompanying test code, and we’re good to go.
public with sharing class HelloWorld {
public static void setHelloWorld(Account a){
a.hello_world__c = true;
}
}
@isTest
public class HelloWorldTest {
@isTest(seeAllData=false)
static void testHelloWorld() {
Account a = new Account();
a.Name = 'Subscribe!';
insert a;
Test.startTest();
HelloWorld.setHelloWorld(a);
Test.stopTest();
System.assert(a.Hello_World__c, 'Not Hello World!');
}
}
But you’ll notice that we have a custom field that isn’t in our package. With Org development, we could use change sets to deploy and manage these custom fields. But that’s not an option in Package development. To get this field metadata inside our package we need to:
- Create a
manifest/package.xml
- Add the definition under the
CustomField
- Retrieve the changes from the org.
Now that we have all of the metadata we want to distribute, let’s bundle this into a package version.
Creating a Package version
We can use the following command to create a new package
sf package version create --package "Clever Package Name" -x --wait 10
We pass in the reference to the package name in either a name or id with the --package
flag.
We specify that we don’t want a password with the -x
flag. If we did, we could use -k
followed by the password. One of these two flags is required.
And we can keep the command open using the --wait
flag to prevent the need from polling Salesforce with addtional commands.
We can then use the url in the output, or take the id use the following command to install the package inside our sandbox or scratch org:
sf package install --package 04tak0000002WevAAE --target-org MyDevHub --wait 10
The package created is a beta package. This is useful for testing in a sandbox, but cannot be installed in production orgs.
Preparing Package for Production
We can create another package version, that specifies the -c
flag.
sf package version create --package "Clever Package Name" -x -c --wait 10
We need to use this flag to get test coverage.
We can then check the code coverage of our package using the following command:
sf package version report --package 04tak0000002WrpAAE
Promote Unlocked Package Version
Since our test coverage is met, it is time to promote our package. We can get a production ready package by using the following command:
sf package version promote --package 04tak0000002WrpAAE
And once the package is ready, we can install this package inside our production org:
sf package install --package 04tak0000002WrpAAE --target-org MyDevHub --wait 10
Bumping package versions
We can promote 1 package per minor version. Inside the sfdx-project.json
, we can see package versions:
{
"packageDirectories": [
{
"path": "force-app",
"default": true,
"package": "Jira Integration",
"versionName": "ver 0.2",
"versionNumber": "0.2.0.NEXT",
"versionDescription": ""
}
]
}
We can increment the versionNumber
field, where:
X.y.z
the first number is the major versionx.Y.z
the second a minor versionx.y.Z
and the third a patch.
Incrementing any of these will suffice.
We can then run the same command to make a new version.
sf package version create --package "Jira Integration" -x -c --wait 10
Need Our Help To Get Your Data Into Salesforce?
Join dozens of other companies by learning how you can get all your company's data in one place.