Showing posts with label Packaging. Show all posts
Showing posts with label Packaging. Show all posts

Saturday, 8 May 2021

The CLI GUI takes on Packages


Introduction

Second generation packaging via the Salesforce CLI is awesome, but it's the area I spend most of my time remembering what parameters it supports, as well as figuring out the ids or names of the packages I'm working with.

I've actually had this functionality in the GUI for a while now, but I hadn't been using it in anger across all the various package types, so I didn't publicise it. Since then I've used it to create managed, unlocked and org dependent packages, and base and extension packages, so I think it's good enough to unleash on the world. The examples below are based on the org-dependent package that I created for London's Calling 2021.

Commands

The updated commands configuration file in the repo adds support for five package commands in their own tab:


(I have them in the order that I typically use them on a day to day basis, but they can easily be reordered by updating the commands.js file).

Create Package



Typically only used when I start a project, the Create Package command will default to the configured dev hub if there is one, but I can change it if for some reason I want to use another. Only dev hub orgs appear in the select list. The Path parameter will be used to update the packageDirectories property from the sfdx-project.json file.

Create Version

This is probably the command I use most when developing packages - creating a new version in the hope that I've finally fixed that elusive bug, but expecting further disappointment! 


When I click the Get Packages button, the available packages managed by the dev hub are retrieved and the sfdx-project.json checked to see if there is already a package defined that it can default to. I can choose any other package if I need to.


The other parameter of note is Definition File - when you create a second generation package, there's no developer edition where the code lives, so something like a scratch org is created as part of the upload process, where the code is deployed, tests run etc. Most of the time I just specify my existing scratch org definition file (config/project-scratch-def.json), but very occasionally I'll have a different shape required for the upload and create a dedicated file.

I can specify a key (password) required to install the package, or bypass this. And I always specify a long wait, as if the command doesn't finish synchronously then the details of the version don't get written to the sfdx-project.json.

Promote Version

There's always a bit of Stockholm Syndrome about this command when developing a package. At the start, I'll do pretty much anything rather promote the version to fix the functionality and commit myself to the package contents, but after a few versions I'll be executing it without a second thought.


As before, the Get Packages button retrieves the packages being administered by the dev hub. Get Package Versions retrieves the versions for the selected package, saving me remembering names or ids. It also only shows my versions that haven't been promoted:


List Packages

A simple command - as it's name suggests it lists the packages currently being administered by the dev hub. 


The package information is shown in the log panel, which automatically opens when the command is executed:


List Package Versions

Again, does exactly what it says on the tin. 


Although this time I can reduce the results based on the when the version was created or modified, and limit it to released versions only. These parameters might seem unnecessary when you are starting out with a package, but after a few years and 100+ versions, you'll be glad of them.

Wrap Up

As usual, I've tested these commands on MacOS and Windows 10, but if you come across any issues feel free to raise them at the Github repository.

Related Posts


Saturday, 14 December 2019

Install Packages in Trailhead Playgrounds without Password Resets

Install Packages in Trailhead Playgrounds without Password Resets

The Credentials Conundrum

A number of Trailhead modules require you to install a package into a playground. This can present a challenge, as the package link provided is the generic version that starts with login.salesforce.com, requiring you to login with the org credentials. Org credentials which as a rule you don’t know, as you just open a playground by clicking on a link in the module itself:

 

The upshot is you need to reset your password to get something you can login with - this crops up so often that it has it’s own module.

The Package Link

Picking a Trailhead module that requires a package at random, Quick Start: Salesforce Connect, right clicking the link and copying the address gives us:

 

https://login.salesforce.com/packaging/installPackage.apexp?p0=04tE00000001aqG

As mentioned earlier, this points to login.salesforce.com, but it doesn’t have to. The part of the URL that drives the installation of the package is :

/packaging/installPackage.apexp?p0=04tE00000001aqG

where packaging/installPackage.apexp is the setup page for installing a package, and p0=04tE00000001aqG identifies the package to be installed, in this case  04tE00000001aqG.

Applying the Package Link to the Playground

Once you have the package link, this can be applied to any org that you are logged into. Continuing the example from above, here’s a Trailhead playground that I prepared earlier:

From the URL bar, I can see tyhe domain name for the org is: playful-shark-vh3q5k-dev-ed.lightning.force.com. Replacing login.salesforce.com from the package link determined above gives me:

https://playful-shark-vh3q5k-dev-ed.lightning.force.com/packaging/installPackage.apexp?p0=04tE00000001aqG

Changing the URL in the browser takes me to the installation page and I can install the package without knowing anything about the org password.

A CLI Tangent

It wouldn’t be a Bob Buzzard Blog post without pimping the CLI. Not particularly applicable to this scenario as you need to authenticate the org using the CLI so you’d have gone through the password reset already, but never any harm in learning about the power of the command line :)

If you have the package id, you can install directly from the command line using the following command:

sfdx force:package:install -r -p 04tE00000001aqG -w 10

The -r switch says not to ask for confirmation (useful when scripting an installation to run unattended as part of a CI setup) and -w 10 says to wait for up to 10 minutes for the package to install. 

 

Monday, 26 August 2019

Salesforce Unlocked Packages and Supplementary Code

Salesforce Unlocked Packages and Supplementary Code

Introduction

Unlocked packages have been Generally Available since the Winter 19 release, so almost a year at the time of writing (August 2019). Unlike 1.0 packaging, source of truth is the version controlled source, rather than the contents of a packaging org. In fact the only time you need anything other than a scratch org is if you are namespacing your package, in which case you’ll have to create a developer edition to annex the namespace. In packaging 2.0 the contents are determined by the code on the filesystem where you run the packaging commands and the Salesforce DX project configuration file (sfdx-project.json).

I’m not going to go into the detail of creating and publishing packages - the Trailhead module does a pretty good job of introducing the concepts, and if you want a deep dive then check out Fabien Taillon’s blog post about how Texei moved to unlocked packages (they were called Developer Controlled Packages back then, but the principles apply even if the commands have changed slightly.

SalesforceDX Project File

To generate an unlocked package, you need to define where the code lives in your SalesforceDX project file. Here’s the key part of the file for an example package:

"packageDirectories": [
        {
            "path": "force-app",
            "default": true,
            "package": "bbexample",
            "versionName": "Version 1.0",
            "versionNumber": "1.0.0.NEXT"
        }
    ]

When I run the Salesforce CLI commands to generate a package version, everything under the

force-app

directory will be added to the package and uploaded. And this to my mind is a key difference between 1.0 and 2.0 packaging. In 1.0 I create the package from the packaging org and I get to choose which components get added. In 2.0 not so much - everything that I have under the packaging directory goes in.

Supplementary Code

When I create a package there is typically a bunch of supplementary code that helps the development and test process, but I don’t want going into the package. If the package contains Lightning Web Components for example, I might have a flexipage with a  number of instances of the component showing various aspects of the functionality, allowing me to see at a glance that everything is working correctly. If the package works against generic sobjects, I might have some sample sobjects to execute tests against that I don’t want ending up in the subscriber org. I want these items available in the scratch o rgs where I’m developiing the package, but I don’t want to release them. In 1.0 I could just avoid adding them to the package, but in 2.0 I need a way to separate them from the packaged code. I could keep it in a separate repo, but that adds complexity to the development setup, and it’s always best to keep things as simple as possible.

Multiple Package Directories

The SalesforceDX project file can define multiple package directories for a single project. When you execute force:source:push, the contents of all of these directories are pushed to the scratch org, so i can store my supplementary code in another subdirectory and have it included in the development process. 

"packageDirectories": [
        {
            "path": "force-app",
            "default": true,
            "package": "bbexample",
            "versionName": "Version 1.0",
            "versionNumber": "1.0.0.NEXT"
        },
        {
            "path": “supplementary",
            "default": false
        }
    ]

When I push to my scratch org, the contents of both the force-app and supplementary subdirectories will be deployed, but when I generate a package version, only the directory with the package attribute gets included. All of my supplementary code stays out of the package and by extension the subscriber org.

There is one wrinkle to this - if I make some changes in the scratch org, when I execute force:source:pull to retrieve them, they will go into the package directory with the default attribute set to true - in this case force-app. If I don’t want these items in the package, I have to manually move them over to the supplementary subdirectory. Not a huge amount of effort but easy to forget.

Bonus - Installations via the CLI

If you haven’t used packaging in conjunction with the CLI yet, there’s one killer feature. Anyone who has worked with packaging 1.0 knows the fun and games around uploading a package, receiving the email that it has been published, then trying and failing to install it as it turns out not to be available after all. There’s a perfectly sound explanation for this - the emails means it was successfully uploaded to wherever packages live, but after that it has to be propagated around Salesforce infrastructure world, and until it’s made it to the instance you are trying to install in, you’ll get failures.

When you install via the CLI force:package:install subcommand, you can specify two wait times. The --wait switch that, like many other commands, specifies how long to wait for the command (installation) to complete, and the —publishwait that specifies how long to wait for the package to become available to the subscriber org. I typically specify big numbers for both of these switches and then fire and forget the installation. It’s a far less stressful user experience!

Related Posts