Photo by Ruben Mishchuk from Unsplash

When Change Sets Fail in Salesforce

With the growing popularity of DX and the GA release of DevOps Center, I’ve seen fewer questions about Change Sets the last couple of years. I expect that organizations that have used change sets successfully for a long time are less motivated to change their processes and those that had issues have had sufficient time to move to the newer options.

What I have seen in the past around legacy processes that work well for small teams is that they are often passed to newer members experientially and at some point someone joins that is not mentored into to how things have been done and struggle on their own. Here are a few tips for those that run into this gap with change sets.

Practice makes it home by dinner time

Even the simplest change can result in big problems if something critical is missed. Always test the change set by pushing from one sandbox to another that has been refreshed since the last production update. If there is a possibility of changes being done directly in production, this means to create or refresh the test target sandbox immediately before the deployment test.

Go small or stay home

Incremental changes are best. I prefer to do a deployment anytime there is a completed task that has tested in development. The push could just be to a fresh sandbox with the final production release being a series of pushes. Another approach is to use dark deployments, pushing out tested work products incrementally even though not all pieces are ready for users. The dark deployments may require some custom metadata types or permissions to keep them from being used before they are ready, something it is really useful for large projects to avoid big-bang pushes.

The incremental pushes to sandboxes should result in a series for change sets. As they progress, dependencies may be discovered and indicate a need to revise the change sets so that dependencies are pushed first. Again, the dark deployments are useful here.

The mighty DX

Among many good reasons for switching to DX, verbose error messages for deployments helps speed up debugging. Using Workbench, it is possible to turn change sets into packages for use in DX, which is handy if you are just starting to migrate to DX. Again, test deployments against fresh sandboxes are critical to avoiding critical situations.

The only constant…

Is change, not change sets. Eventually change sets will probably go away, so if you are reading this post you are either bored and avoiding more productive tasks or you are struggling with a change set today.  Now is a good time to start looking into alternatives.

Facebooktwitterredditlinkedinmail
© Scott S. Nelson
Daily Limit Reached

Solution for sfdx package create error “couldn’t retrieve the design time component information for component”

(Formerly titled SOLVED! sfdx force:package:version:create -p error: We couldn’t retrieve the design time component information for component)

Now and then I find myself looking for what I expect to be a simple set of steps for what seems to be a common need and instead wind up on a Google journey that is frustrating as all heck. I hit a double-header in this area over the weekend (ironically, following the steps from my own post Get Hands-on with VS Code, Salesforce DX and Packages), and while the second annoyance is still annoying me the first part was resolved and I’m sharing that here. While I won’t make you repeat all the steps I went through to complete a 5 minute task in as many hours, I will share the path before the conclusion (tldr;).

Problem: running force:package:version:create -p to create an unlocked package for an app that has a dependency on a managed package results in an error “We couldn’t retrieve the design time component information for component [foo:bar]”.

Ok, simple enough. Add the managed package as a dependency. GiMF, so off I go and find https://salesforce.stackexchange.com/questions/236881/how-do-you-create-a-package-version-with-dependencies-on-both-2gp-and-1st-gen-ma which usefully points out I need to add the package as dependancy and some examples of what it looks like. Hmmm. I note a key requirement is the package ID. There examples clearly show the ID but no where in the thread does it mention how to get the ID. Down the search engine rabbit hole again to find https://developer.salesforce.com/docs/atlas.en-us.222.0.sfdx_dev.meta/sfdx_dev/sfdx_dev_unlocked_pkg_config_file.htm, which tells me exactly how to find it for my own packages, but not a hint of how to do this for a package from AppExchange. Continuing on… I find how to find the info using SOQL at https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_unlocked_pkg_extract_dependency_info.htm, but, alas, still only good for my own packages.

Eventually I found this command (and, in all honesty, I was so frustrated by then that I lost the link where I found it):

sfdx force:package:installed:list -u [alias to org that has managed packaged installed]

Which rendered:

ID Package ID Package Name Namespace Package Version ID Version Name Version
------------------ ------------------ -------------------------- ------------ ------------------ ----------------- --------
0A375000000GsstCAC 0332E000000U76DQAS Launch Flow Modal sf_flowmodal 04t2E000003VsuMQAS Launch Flow Modal 1.14.0.1
0A375000000Gss2CAC 03330000000wDAbAAM Salesforce Connected Apps sf_com_apps 04t30000001DUvrAAG Winter '16 1.7.0.1
0A375000000GssoCAC 0333X0000006XwlQAE Enhanced Approval Requests ear 04t3X000002xUYTQA2 Summer 2021 1.10.0.1

And yay, I had what I needed to create the entry depencies entry for managed packages used by an unlocked package:

"dependencies": [
    {
        "subscriberPackageVersionId": "04t2E000003VsuMQAS"
    },
    {
        "subscriberPackageVersionId": "04t3X000002xUYTQA2"
    }
]

Basically. I actually would have preferred to find the 0Ho ID so I could also just use LATEST instead of the last digit of the version, but alas, time to move on to the remaining issue(s):

Picklist value: ...not found
Defined value not found

Which I am stopping on today because:

ERROR running force:package:version:create: The package2 version create request failed because this organization has reached its daily limit
Author has (also) reached its daily limit

In summary, to add a managed package as a dependency for an unlocked package:

With an org where the managed package is installed run the following:

sfdx force:package:installed:list -u [alias to org that has managed packaged installed]

Then add this to your sfdx-project.json under packageDirectories that contains your package:

"dependencies": [ { "subscriberPackageVersionId": "04tPACKAGEID" } ]

Where 04tPACKAGEID is the value returned from the CLI command.

Facebooktwitterredditlinkedinmail
© Scott S. Nelson
sfdx cli versions.map-is-not-a-function

FIXED! ERROR running force:mdapi:retrieve: versions.map is not a function

Ran into this fun error message today when attempting to pull from a Salesforce sandbox from the CLI:

ERROR running force:mdapi:retrieve: versions.map is not a function

Most of what I found on the web was FUD and also about trying to push rather than pull. The comments all seem to agree it was related to the recent update for Enhanced Domains on Winter23-enabled sandboxes.

Fortunately for me, I had just added another org to my CLI. I was surprised at no approval prompt and it got me to thinking that I had probably authorized it before. So it occured to me that the fix may just be to run the authorization again, i.e.,

sfdx force:auth:web:login --setalias [ALIAS] --instanceurl [MY.DOMAIN.URL]

And that did the trick for me. Hope this helps others.

Facebooktwitterredditlinkedinmail
© Scott S. Nelson

Get Hands-on with VS Code, Salesforce DX and Packages

(Originally published at Logic 20/20 as SFDX, VSCode, and deploying from a package the editors stripped out all of the links, rendering it an entirely different post. This is the original version.)

While I do not immediately dislike new tools, I do struggle with adopting them when I find nothing wrong with the old ones. And then I delay learning them until I’m forced to, which is the case of Visual Studio code for Salesforce (they are no longer supporting the Eclipse IDE and abandoned the DX extension for Eclipse before DX went GA) and Git (because that is the way the dev world has gone). I find the best way to learn new tools is to write about how to learn them, so here we go.

(In the spirit of working in a low code platform, we will also see how much of this I can do with just links to existing documentation…)

If you haven’t already, Install Salesforce Extensions for VS Code.

Then Enable Dev Hub in Your Org and Enable Second-Generation Packaging (note that while 2GP is beta as of this writing, this is required to enable first generation Unlocked Packages which is GA).

Next…Well, that didn’t take long. I cannot find a stand-alone URL for creating an SFDX project, so I’m going to steal a section from a Trailhead lesson (because it is as much typing to say what not to do as it is to re-create it here):

  1. Open VS Code.
  2. From the menu, select View | Command Palette.
  3. In the command palette search box, enter [PROJECT_NAME].
  4. Select SFDX: Create Project.
  5. Use the same name as your GitHub repo, then click Enter.
  6. Click Create Project.
  7. Create a .gitignore file to ignore hidden directories:
    1. Hover over the title bar for the DX project. then click the New File icon.
    2. Enter .gitignore. [check if it already exists and just edit if so]
    3. In the text editor, indicate to ignore these two hidden files:
.sfdx
.vscode

To foster good habits, I will set up a github repo to store this project in (though following a full lifecycle will be another article) by following the excellent documentation at https://help.github.com/en/github/importing-your-projects-to-github/adding-an-existing-project-to-github-using-the-command-line and add the project to the repository.

Now go do some work in Salesforce. For example purposes, let’s do the Build a Simple Flow project.

After you complete the project, follow the instructions to Create and Upload an Unmanaged Package, skipping the Upload part. I named the project TH_Flow_Project, which you don’t have to, I only mention that as I will use that text in the example commands.

Salesforce provides a nice reference to Create a Salesforce DX Project from Existing Source.  I have some additional thinking around how to go about this part, so I will end the approach of linking to references and switch to my own approach. If you followed the last link and stopped here, you won’t learn anymore about the Salesforce DX capabilities, but you may miss out on some of my shortcuts and wit. With that said…

Authorize the org you created the flow in with the following:

sfdx force:auth:web:login –setalias <MY_SOURCE_ALIAS> –instanceurl <MY_ SOURCE_ORG_URL>

Example:

sfdx force:auth:web:login --setalias TH-ORG02 --instanceurl https://infa-ca-wav-dev-ed.my.salesforce.com/

A bit late to mention, but if you are using a Developer org, I highly recommend to Set Up My Domain. Trailhead orgs already have one. If you haven’t, you can probably leave off the instanceurl parameter and it should pick it up from the default configuration for your project (YMMV). Otherwise use the URL that you login to your org with.

Next, download the package using the following:

sfdx force:mdapi:retrieve -r ../ -p <PACKAGE_NAME> -u <USERNAME>, ex:

sfdx force:mdapi:retrieve -r ../ -p TH_Flow_Project -u scott@trailh2.org

Let’s break that down just a bit. The first part is the base command to retrieve (sfdx force:mdapi:retrieve). The -r parameter determines where the downloaded zip file will be located. The example uses a relative path indicating the folder above the DX project. As a best practice, I recommend always staying in the project directory inside the VSC terminal, with all commands base on being relative to that location. This way you can maintain a list of commonly-used commands that will be re-usable across all projects. The downloaded file name is always unpackaged.zip.

The files need to be unzipped before they can be used (someone should make a feature request for the convert command to work on zip files instead of having to unpack them first). In Linux the relative command is:

unzip ../unpackaged.zip -d ../

Now we add the files from the package to our project using the relative path command:

sfdx force:mdapi:convert -r <PATH_TO_UNZIPPED_PACKAGE> -d <PATH_TO_[/force-app]>, ex:

sfdx force:mdapi:convert -r ../TH_Flow_Project -d force-app

Now all of the files from your package are part of your project.

To add this to your target org, first authorize that org as done previously for the source org, i.e.:

sfdx force:auth:web:login –setalias <MY_TARGET_ALIAS> –instanceurl <MY_ TARGET_ORG_URL>

Example:

sfdx force:auth:web:login --setalias TH-ORG02 --instanceurl https://infa-ca-wav-dev-ed.my.salesforce.com/

And (almost) finally, deploy the updates from your project to the target org with:

sfdx force:source:deploy -u <TARGET_USERNAME> -x <PATH-TO-PACKAGE.XML>

sfdx force:source:deploy -u apex@theitsolutionist.com -x ../TH_Flow_Project/package.xml

(Another feature recommendation is to have an alias option instead of only the username.)

And finally (this time for real!) look in your list of flows to see the flow installed in your target org.

Of course, you are doing this with a throw-away org, right? Because I forgot to mention that deploying will over-write any existing components with the same name.

One final note. We used the package.xml from the downloaded package for the sake of simplicity. Once the package import is validated, you will want to combine the package.xml from the download with the package.xml in your project located in the manifest folder of your project.

The project created from the writing of this article can be found at https://github.com/ssnsolutionist/trailhead1

Facebooktwitterredditlinkedinmail
© Scott S. Nelson