Start tracking your progress
Trailhead Home
Trailhead Home

Create, Test, and Deploy Your Unlocked Package

Build and Test the Project in a Scratch Org

As with any Salesforce DX project, you’re going to start working in your own scratch org. You can run and test your app there before you build the package and install it in your target environment.

  1. Make sure you are in the GIFter directory.

    The GIFter project has a scratch org configuration file ready for you to use.

  2. If you’re not connected to the Dev Hub org, log in to it:
    sfdx force:auth:web:login -d -a DevHub
  3. Go ahead and create your scratch org.
    sfdx force:org:create -s -f config/project-scratch-def.json

    You get a response like:

    Successfully created scratch org: 00D1100000BvDK3EAN, username:
            test-ou0arkv1qbow@example.com

    You now have a scratch org ready to use and set as the default for your project workspace.

  4. Next, push all your source from the force-app folder into your newly created scratch org.
    sfdx force:source:push

    You’ll see a readout of all the source that was pushed into your org.

    === Pushed Source
    STATE  FULL NAME                             TYPE                  PROJECT PATH
    ─────  ────────────────────────────────────  ────────────────────  ─────────────────────────────────────────────────────────────────────────
    Add    GIFter                                CustomApplication     force-app/main/default/applications/GIFter.app-meta.xml
    Add    SearchGIPHY/SearchGIPHY.auradoc       AuraDefinitionBundle  force-app/main/default/aura/SearchGIPHY/SearchGIPHY.auradoc
    Add    SearchGIPHY/SearchGIPHY.cmp           AuraDefinitionBundle  force-app/main/default/aura/SearchGIPHY/SearchGIPHY.cmp
    Add    SearchGIPHY/SearchGIPHY.cmp           AuraDefinitionBundle  force-app/main/default/aura/SearchGIPHY/SearchGIPHY.cmp-meta.xml
    Add    SearchGIPHY/SearchGIPHY.css           AuraDefinitionBundle  force-app/main/default/aura/SearchGIPHY/SearchGIPHY.css
    Add    SearchGIPHY/SearchGIPHY.design        AuraDefinitionBundle  force-app/main/default/aura/SearchGIPHY/SearchGIPHY.design
    Add    SearchGIPHY/SearchGIPHY.svg           AuraDefinitionBundle  force-app/main/default/aura/SearchGIPHY/SearchGIPHY.svg
    Add    SearchGIPHY/SearchGIPHYController.js  AuraDefinitionBundle  force-app/main/default/aura/SearchGIPHY/SearchGIPHYController.js
    Add    SearchGIPHY/SearchGIPHYHelper.js      AuraDefinitionBundle  force-app/main/default/aura/SearchGIPHY/SearchGIPHYHelper.js
    Add    SearchGIPHY/SearchGIPHYRenderer.js    AuraDefinitionBundle  force-app/main/default/aura/SearchGIPHY/SearchGIPHYRenderer.js
    Add    ChatterHelper                         ApexClass             force-app/main/default/classes/ChatterHelper.cls
    Add    ChatterHelper                         ApexClass             force-app/main/default/classes/ChatterHelper.cls-meta.xml
    Add    GIPHY                                 CspTrustedSite        force-app/main/default/cspTrustedSites/GIPHY.cspTrustedSite-meta.xml
    Add    GIFter                                FlexiPage             force-app/main/default/flexipages/GIFter.flexipage-meta.xml
    Add    GIFter_UtilityBar                     FlexiPage             force-app/main/default/flexipages/GIFter_UtilityBar.flexipage-meta.xml
    Add    GIFter                                PermissionSet         force-app/main/default/permissionsets/GIFter.permissionset-meta.xml
    Add    GiphyMedia0                           RemoteSiteSetting     force-app/main/default/remoteSiteSettings/GiphyMedia0.remoteSite-meta.xml
    Add    GiphyMedia1                           RemoteSiteSetting     force-app/main/default/remoteSiteSettings/GiphyMedia1.remoteSite-meta.xml
    Add    GIPHY                                 StaticResource        force-app/main/default/staticresources/GIPHY.resource
    Add    GIPHY                                 StaticResource        force-app/main/default/staticresources/GIPHY.resource-meta.xml
    Add    jquery331                             StaticResource        force-app/main/default/staticresources/jquery331.js
    Add    jquery331                             StaticResource        force-app/main/default/staticresources/jquery331.resource-meta.xml
    Add    GIFter                                CustomTab             force-app/main/default/tabs/GIFter.tab-meta.xml
    

    In your source there’s a permission set (named GIFter) that you use to govern access to the GIFter app you’re building.

  5. Assign the default user in the scratch org to this permission set.
    sfdx force:user:permset:assign -n GIFter
    === Permsets Assigned
    USERNAME                       PERMISSION SET ASSIGNMENT
    ─────────────────────────────  ─────────────────────────
    test-ou0arkv1qbow@example.com  GIFter
  6. OK, let’s open the app and try it out.

    While you can open the org and then browse to the GIFter app from the App Launcher, let’s go one step further and open it up directly.

    sfdx force:org:open -p lightning/n/GIFter

    This is an example of what you’ll see if you enter funny animals in GIPHY Search Terms.

    The GIPHY Search Terms window enables you to search for animated GIFs based on keywords. You enter the search term in Search Terms, and the images that meet the criteria are displayed.
  7. Try the app out. Have some fun.

At this point, you’ve validated that the app works as expected. Let’s go ahead and create your package!

Create the Unlocked Package

There are two parts to a package: the first is the package and the second is the package version.

A package is really a manifest about what it is you're going to create, whereas the package version is a snapshot in time of the metadata and code that relates to what you're building and installing.

So the first step is to create a package, specifying information that’s unlikely to change, like the name and description. You’re also going to choose the type of package you want to create, in this case, an unlocked package.

  1. Open sfdx-project.json in your favorite text editor.
    GIFter is an open-source project that can change at any time. To ensure that you can successfully complete the steps, let’s make sure your project file looks like this one to start out.
    {
       "packageDirectories": [
          {
             "path": "force-app",
             "default": true
          }
       ],
       "namespace": "",
       "sfdcLoginUrl": "https://login.salesforce.com",
       "sourceApiVersion": "43.0"
    }
  2. If necessary, delete some existing parameters, such as id, versionName, and versionNumber. Update the sourceApiVersion to match the version of the Salesforce CLI. Don’t forget to save!
  3. Create the package.
    sfdx force:package:create -n GIFter -d "Using GIPHY to find GIFs and post to Chatter" -r force-app -t Unlocked -v DevHub

    The parameters that you specify provide this important information:

    • -n is the package name. This name is an alias you can use when running subsequent packaging commands.
    • -r is the directory that contains the contents of the package.
    • -t is the package type, in this case, unlocked.

The package alias (GIFter) is now associated with the Package ID (0Ho).

=== Ids
NAME                  VALUE
───────────────────── ──────────────────
Package Id           0Hoxxx
Tip

Tip

If you forget the package alias or package ID, you can list all the packages you created in your Dev Hub by running sfdx force:package:list.

Create the Package Version

Now that you have the package defined, you can create a specific version of the package. This package version is the artifact that’s installed into various orgs. As you make updates to your app, you create new package versions that contain the updated source.

Important

Important

This project illustrates the workflow for creating the package versions. If you copy and paste the command line examples, be sure to substitute your specific information to complete the hands-on challenge.

  1. Open the sfdx-project.json file.

    Notice that the package:create command updates the project file to include important details about the package. In packageDirectories, you can see the package name you defined, with placeholders for the version name and version number. The command also creates a packageAliases section, which maps the package name (alias) to its corresponding package ID (0Ho).

    {
       "packageDirectories": [
          {
             "path": "force-app",
             "default": true,
             "package": "GIFter",
             "versionName": "ver 0.1",
             "versionNumber": "0.1.0.NEXT"
          }
       ],
       "namespace": "",
       "sfdcLoginUrl": "https://login.salesforce.com",
       "sourceApiVersion": "43.0",
       "packageAliases": {
          "GIFter": "0Hoxxx"
       }
    }

    The versionName is really up to you, and doesn’t necessarily have to change with each new version you create. More importantly, the versionNumber auto-increments based on the use of the NEXT keyword. You can leave the rest alone.

  2. Let’s say you’re ready to release the first version of GIFter.

    Update the versionName and versionNumber.

    "versionName": "Summer '18",
    "versionNumber": "1.0.0.NEXT"
  3. Save sfdx-project.json.
  4. With this information set, create your first package version.
    sfdx force:package:version:create -p GIFter -d force-app -k test1234 --wait 10 -v DevHub
    • -p is the package alias that maps to the package ID (0Ho).
    • -d is the directory that contains the contents of the package.
    • -k is the installation key that protects your package from being installed by unauthorized individuals.

    This operation can take several minutes. But when complete, it provides the necessary information to install this package version in an org. The output contains this information:

    Successfully created the package version [08cxxx]. Subscriber Package Version Id: 04txxx.
    Package Installation URL: https://login.salesforce.com/packaging/installPackage.apexp?p0=04txxx
    As an alternative, you can use the "sfdx force:package:install" command.

OK, so now you’re ready to install this package in another org!

Install and Test the Package Version in a Scratch Org

Before you install the package in your TP (or in the real world, or any of your sandbox or production orgs), it’s always best to first test it in a newly created scratch org. So let’s repeat a few of the steps you performed earlier, yet this time you install your app in a scratch org using the package version you just created.

  1. Create the scratch org.
    sfdx force:org:create -s -f config/project-scratch-def.json
  2. Install the package into the scratch org using the alias for the package version.
    sfdx force:package:install --wait 10 --publishwait 10 --package GIFter@1.0.0-1 -k test1234 --noprompt

    This operation takes several moments to complete. When it does, you see the message:

    Successfully installed package [04t_xxx]

    The install command effectively replaces the force:source:push command you used earlier.

  3. Assign the permission set.
    sfdx force:user:permset:assign -n GIFter
  4. Now, let’s open the scratch org and see if things work as expected.
    sfdx force:org:open -p lightning/n/GIFter

As expected, the app works! And if you go into Setup and choose Installed Packages, you can see that your GIFter package has been installed.

View your installed packages in the Installed Packages dialog. You can see GIFter listed here with its version number and install date and time.

This looks good! Time to install it in your Trailhead Playground.

Install the Package Version in Your Trailhead Playground (TP)

Unsurprisingly, you use some of the same commands to install the package version into your TP. Unlike the scratch org, however, the TP already exists so there’s no step to create it.

  1. Install the package, this time targeting your TP.
    sfdx force:package:install -u MyTP --wait 10 --package GIFter@1.0.0-1 -k test1234 --noprompt
  2. Once that completes, assign the permission set.
    sfdx force:user:permset:assign -n GIFter -u MyTP
  3. And finally, open the org and run the app.
    sfdx force:org:open -p lightning/n/GIFter -u MyTP

You’ve successfully used an unlocked package to create, test, and deploy your application. Nice!

We won't check any of your setup. Click Verify Step to go to the next step in the project.

retargeting