Features and Settings and Scratch Orgs, Oh My!

Scratch orgs are one of the really great capabilities provided with Salesforce DX. One of the benefits of scratch orgs is that they start empty, allowing you to configure them how you want and develop in a clean and known environment. But what is a benefit can also be a challenge. With all the optional product add-ons and flexible configuration that Salesforce offers, it can be tricky sometimes to figure out how to enable the functionality that you want in a scratch org. The scratch org definition file is where you can specify the configuration of the scratch org when it’s created. This configuration is also referred to as the “shape” of the org. Shape includes things such as licenses, permissions, and settings (aka preferences) that determine the functionality that is available in the org.

Edition, Features, Settings in the scratch org definition file

Within the scratch org definition file, there are three key fields that allow you to define the shape of the org — they are edition, features and settings.

Edition

edition is fairly self-explanatory. This specifies the Salesforce Edition for the org (Professional, Enterprise, Developer, Group) and when you do this, all functionality that is provided out-of-the-box with that Edition is available in the scratch org.

Features and Settings can be more tricky to understand, both in terms of what they enable and in how they interact with each other.

Features

features in the scratch org definition file provide the ability to specify additional add-on functionality that can be supported in the Edition, but isn’t available out of the box. Features generally enable add-on licenses in the org and things that a user cannot enable themselves in the org via Setup, and that would be provisioned through a sales or support process in a standard production org. Examples of these add-on features include IoT, Live Agent or Communities, and their corresponding scratch org definition file Features can be found in the Scratch Org Definition Configuration Values documentation.

Settings

settings in the scratch org definition file provide the ability to programmatically enable or disable Settings in the org. Settings in the org are generally found in “Settings” pages in the Setup UI — for instance “Email Settings” or “Notes Settings” — and are often (but not always) boolean checkboxes that allow you to turn on or off various capabilities available with the associated feature. Sometimes when you enable a Setting, additional functionality is then made visible/available in the Setup UI. In sandbox and production orgs, settings are often set by Admins configuring the shape of the org for their users and are basically set once. With scratch orgs, Settings can be toggled the same way in the Setup UI but because a scratch org starts out empty every time it’s created, it’s better to be able to programmatically toggle these settings in order to support automated development and Continuous Integration (CI) flows. The use of Settings in the scratch org definition file simply automates the enablement/disablement of these Settings as part of Scratch Org creation.

Features vs. Settings

Think of Features as the way you provision/purchase/add-on functionality in your org. When this was done in your production org originally, you or someone at your company likely worked through a sales process to provision that functionality. Your org was then licensed to use that functionality. However, it may not have been until you or your admin actually went into the Settings in the org and flipped the switch to enable it, that you could actually use the functionality. Scratch org Features allow you to provision or license functionality into the org to give the org access to that functionality, and Settings allow you to then enable capabilities within that provisioned set of functionality to give you the ability to use the functionality in the org.

Still not totally clear? Let’s walk through a real-world example here. Pictures are worth a thousand words, right?

A “Live Agent” example

Let’s look at “Live Agent.” This is an add-on license that is available for an extra cost in Enterprise Edition. This means that by default, a scratch org that is created with Enterprise Edition will not have this functionality available.

The default case

Let’s start by looking at an Enterprise Edition scratch org that is created with default settings. Here’s what the scratch org definition file that we used to create our first scratch org in this example looks like. Note that there are no additional “Features” or “Settings” specified.

{
  "orgName": "Sample Org",
  "edition": "enterprise"
}

Now let’s look at the Setup tree in the scratch org that was created. Note that there’s a lot of functionality available, but there is no Live Agent node in the Setup tree at all. This is because the org has not been provisioned for the Live Agent add-on.

Furthermore, if we have metadata in our project that defines Live Agent functionality (for example: “LiveChatButton” or “Skill” metadata types), and we try to push or deploy that metadata into this scratch org, we see the following errors. These errors indicate that these metadata types are not available for deploy in this org. This is because the org is not properly set up to allow for use of these metadata types. So how do we resolve this?

$ sfdx force:source:push -u testlivechatnsnf
PROJECT PATH ERROR
─────────────────────────────────────────────────────────────────────────── ──────────────────────────────────────────────
force-app/main/default/liveChatButtons/MyChatButton.liveChatButton-meta.xml Not available for deploy for this organization
force-app/main/default/skills/MySkill.skill-meta.xml                        Not available for deploy for this organization

The Metadata Coverage Report is a good place to start to figure out what we need to include in our scratch org definition file to properly configure the scratch org to support these metadata types. From this we can see that we need to specify both a “Feature” and a “Setting” to properly configure the org to allow for use of the LiveChatButton and Skill metadata types. We’ll make this update in our example shortly, but before we do that, let’s walk through a few more examples to try to drive home how features and settings work with scratch org configuration.

Specifying the LiveAgent “Feature”

In this next example, we’ll go ahead and add the LiveAgent feature to the scratch org definition file. Again, remember that a “Feature” in the Scratch Org Definition file provisions/licenses the org for the add-on functionality.

{
  "orgName": "Sample Org",
  "edition": "enterprise",
  "features": [
    "LiveAgent"
  ]
}

Note: Feature values are case insensitive.

Now, if we look at the resultant scratch org, we now see the Live Agent node in the Setup tree (yay!), but only one child-node under it – Live Agent Settings. In Live Agent Settings, we can see that Live Agent has not yet been enabled. Even though the org is now licensed for use of Live Agent, the functionality still needs to be explicitly enabled in the org. Again, this is the process that an Admin would typically go through when setting up the org for use. So, until Live Agent is “enabled”, the capabilities of this feature aren’t yet available.

To further highlight this, if we go ahead and again try to push our Live Agent metadata into the scratch org, we’ll see the same failure we saw before because the org still does not have Live Agent functionality enabled. It’s now licensed to be able to enable it, but it’s not yet enabled.

$ sfdx force:source:push -u testlivechatns
PROJECT PATH ERROR
─────────────────────────────────────────────────────────────────────────── ──────────────────────────────────────────────
force-app/main/default/skills/MySkill.skill-meta.xml                        Not available for deploy for this organization
force-app/main/default/liveChatButtons/MyChatButton.liveChatButton-meta.xml Not available for deploy for this organization

So, while we’ve got the Setup UI open, we could do a quick flip of the switch here to enable Live Agent. When we do that, we see a bunch more child nodes appear in the Setup tree, now providing access to the actual Live Agent functionality.


Now that we’ve enabled the Live Agent functionality in the org, let’s try to push our source again. This time, it’s successful. Yippie!

$ sfdx force:source:push -u testlivechatns
=== Pushed Source
STATE FULL NAME TYPE PROJECT PATH
───── ──────────── ────────────── ───────────────────────────────────────────────────────────────────────────
Add MyChatButton    LiveChatButton  force-app/main/default/liveChatButtons/MyChatButton.liveChatButton-meta.xml
Add MySkill         Skill           force-app/main/default/skills/MySkill.skill-meta.xml

But while this may be cause for celebration, it’s short-lived once you realize that you have to manually enable this Setting every time you create a scratch org. The goal with Salesforce DX is to be able to entirely automate the Application Lifecycle Management (ALM) and Continuous Integration and Deployment (CI/CD) processes. This is where settings in the Scratch Org Definition File come in.

Specifying Settings programmatically

Settings are available not only in the Setup UI, but also via the Metadata API and the scratch org definition file. The naming convention that is used in the scratch org definition file mirrors the Metadata API, with the slight nuance of using camelCase in the scratch org definition file. Every “*Setting” object and field that is supported in the Metadata API is automatically supported in the scratch org definition file as a “setting.” In our Live Agent example here, the “liveAgentSettings” metadata type contains the enableLiveAgent boolean field which enables the “Enable Live Agent” setting that we saw in the Setup UI. This information can be found in the Metadata API Developer Guide, or even more conveniently, in the Metadata Coverage Report in the sample scratch definition file for either the LiveChatButton or Skill metadata types that we’re working with here.

Although we do have settings that are not yet available in the Metadata API (but are in the Setup UI), we WILL be providing support for these in the Metadata API and therefore the scratch org definition file as well. Our plan (Forward Looking Statement) is to have all settings supported in the Metadata API and therefore scratch org definition file by Winter ’20 at the latest.

So let’s get back to our example. Here’s the fully populated scratch org definition file with both the LiveAgent feature and the enableLiveAgent setting enabled.

{
  "orgName": "Sample Org",
  "edition": "enterprise",
  "features": [
    "LiveAgent"
  ],
  "settings": {
    "liveAgentSettings": {
      "enableLiveAgent": true
    }
  }
}

If we look at the new scratch org that is created from this scratch definition file, we can see the full set of Live Agent functionality enabled in the Setup tree.

And if we push our Live Agent source into the scratch org, it is successful. Yippee, for real this time! No manual intervention required!

$ sfdx force:source:push -u testlivechat
=== Pushed Source
STATE FULL NAME TYPE PROJECT PATH
───── ──────────── ────────────── ───────────────────────────────────────────────────────────────────────────
Add MyChatButton    LiveChatButton  force-app/main/default/liveChatButtons/MyChatButton.liveChatButton-meta.xml
Add MySkill         Skill           force-app/main/default/skills/MySkill.skill-meta.xml

It’s worth noting that in cases where the Feature is included with the Edition by default, it won’t be necessary to specify the “Feature” in the scratch org definition file because the functionality is already licensed in the org by default, but it is still necessary to specify a “setting” in the scratch org definition file to enable that functionality you want to use. This scenario would apply in our example here if we were using Developer Edition instead of Enterprise, because the Live Agent add-on is licensed by default in Developer Edition, unlike in Enterprise edition.

Extra credit

If you’re interested in learning a little more about how this stuff works, we can look at one more example. In this case, we have specified the enableLiveAgent setting, but NOT the LiveAgent feature in the scratch org definition file.

What do you think will happen in this case?

{
  "orgName": "Sample Org",
  "edition": "enterprise",
  "settings": {
    "liveAgentSettings": {
      "enableLiveAgent": true
    }
  }
}

When we attempt to create the scratch org, it fails:

$ sfdx force:org:create -f config/project-scratch-def_nofeature.json -a testlivechatnf -v kfidelak@forcegs.com

=== Component Failures [1]
TYPE FILE NAME PROBLEM
───── ───────────────────────────────── ───────── ──────────────────────────────────────────────
Error shape/settings/LiveAgent.settings LiveAgent Not available for deploy for this organization

ERROR:  Failed to deploy settings to scratch org.


$ sfdx force:org:open -u testlivechatnf
ERROR:  No org configuration found for name testlivechatnf.

Why did this fail?

As we hinted at above, the way the “Settings” from the scratch org definition file are actually applied to the scratch org is by deploying the Metadata Settings object (behind the scenes) using the Metadata API. Now, this Metadata Settings object may also require special licensing in the org, and in this case, it’s again the Live Agent add-on license that is required. So, the scratch org creation fails because it could not successfully deploy the LiveAgentSettings metadata because the Live Agent license is not enabled in the org.

Quiz time: How do we enable that Live Agent license in the org? Answer: By using the LiveAgent “Feature”! You can even see this in the Metadata Coverage Report if you look at the “LiveAgentSettings” metadata type. In that report, the sample scratch org definition file indicates that the LiveAgent feature is required to deploy the LiveAgentSettings metadata type, just like that LiveAgent feature is required to deploy other metadata types that are associated with Live Agent functionality, namely LiveChatButton and Skill from our example above.

A little more on “orgPreferences” vs. “Settings”

You may have a scratch org definition file that uses orgPreferences instead of settings to enable/disable settings (aka preferences). settings are the newer way to specify settings and have the advantage of automatically supporting any setting that is supported in the Metadata API. orgPreferences also relied on the associated setting being supported in the Metadata API, but even if that was the case, it wasn’t necessarily the case that it would also be supported via an orgPreference in the scratch org definition file. In this way, settings are much more extensible and consistent and will provide fuller coverage for us.

Below is an excerpt of an older “orgPreferences”-based scratch org definition File, and the corresponding new “Settings”-based scratch org definition file. Note again how the “Settings”-based format mirrors the Metadata API syntax. Also, pay special attention to cases where the old format followed a “Is<Pref>Enabled” pattern, whereas the new format and the Metadata API follows a “enable<Pref>” pattern, as shown with the enableLiveAgent setting below.

OLD FORMAT:

"orgPreferences": {
  "enabled": ["S1DesktopEnabled","IsLiveAgentEnabled"],
  "disabled": ["IsOrdersEnabled"]
}

NEW FORMAT:

"settings": {
  "orgPreferenceSettings": {
    "s1DesktopEnabled": true
  },
  "liveAgentSettings": {
    "enableLiveAgent": true
  },
  "orderSettings": {
    "enableOrders": false
  }
}

Today, we support both the “orgPreferences” format and the “Settings” format in scratch definition files, but you can only use one or the other in a given scratch definition file. settings provide more complete coverage of settings today and we highly encourage you to use this format moving forward. In Winter ’20, we plan to discontinue support of the orgPreferences format in scratch definition files and we’ll be issuing a warning about this as part of scratch org creation in Summer ’19. We also have plans in Spring ’19 to provide an upgrade utility that can convert your scratch definition file from using the old orgPreferences format to using the new settings format.

Conclusion

Through the example detailed above, we hope you have a better understanding of how to take advantage of the configuration capabilities of scratch orgs to efficiently build applications on the Lightning Platform using Salesforce DX.

About the author

Karen Fidelak works on the Salesforce DX product management team and is responsible for many aspects of Metadata in the platform, including the Metadata API, Tooling API, Change Sets, and driving Metadata coverage and usability throughout the platform in general. Follow her on Twitter: @karenfidelak

Leave your comments...

Features and Settings and Scratch Orgs, Oh My!