Release managers who own the pipeline for one or many managed 2GP packages or unlocked packages want their DevOps build pipeline to be as efficient as possible. You may be a release manager at a Salesforce ISV partner that distributes apps using managed 2GP packages, or at a Salesforce customer company that manages your org metadata using unlocked packages. If so, this blog post is for you.

We’ll guide you through the three types of package builds we’ve made available, and how to use them to optimize your DevOps process.

A note on terminology: the phrase “package build” is synonymous with “package version create.”

Efficiency can be hard

One of the key steps in a continuous integration (CI) script for Salesforce packages is the creation of an installable package artifact — the package version. Depending on your development and release process, you may create one package version per week, many package versions per day, or even a package version per commit! Each package version creation can be time-consuming, and the duration it takes depends on two factors

  1. The amount of metadata in the package
  2. The packages it depends on

Line chart showing that package build times take longer as packages become larger, and as packages have more package dependencies

Package version creation can take anywhere from a few seconds to a few hours! Depending on how you structure your CI scripts and your pipeline, this duration can have a huge impact on your DevOps productivity. The last thing your developers or QA engineers want to do is to sit and wait for a build, just to get an installable package version to iterate on for further development or testing. 

As the release manager, it’s up to you to keep the pipeline humming along smoothly. But how do you do that when package builds start to take a long time?

The three types of package builds

Salesforce offers three different ways to create a package version in terms of validations, which affect how long the build takes. For simplicity, we’ll refer to these as a full build, a quick build, and an async build. Let’s see what each entails.

Full build

A full build performs rigorous checks upfront. For example, it validates package metadata and dependencies, runs Apex tests, and measures code coverage. If these steps are all successful, the build produces an installable package version. While these checks ensure technical validity from a packaging standpoint, this does not remove the need for testing. 

Such package versions can also be promoted from beta to the released state, so that they can be listed on AppExchange and installed in production orgs. The downside is, this is the most time-consuming build type. Use the sf package version create CLI command to perform a full build.

Quick build

A quick build completes very quickly because we validate very few things. We get you an installable package version as soon as possible without validating the completeness or consistency of package metadata and dependencies, or running Apex tests. You get an installable package version lightning fast, but it was never validated. As a result, you cannot promote the package version to the released state, or install it in production orgs. To specify a quick build, add the --skip-validation param to the sf package version create CLI command.

Async build

There is full build and quick build, what else is out there? Glad you asked! In Summer ‘24, we added another arrow in our quiver: async build. An async build sets out to do a full build, but creates an installable package version in the middle of the validation process prior to running Apex tests. As a result, it takes longer than a quick build, but shorter than a full build, and the package version produced is promotable to a released state if the Apex tests pass and the code coverage requirement is met. So, it is preferable to a full build in most scenarios. To specify an async build, add the --async-validation param to the sf package version create CLI command.

So which build type should I use?

You guessed right — it depends! But we won’t stop there. We’ll give you our two cents using the following scenarios: 

  1. In your CI process, if you are doing frequent builds and have validation built in before the package version creation step (e.g., you run all Apex tests before creating a package version), or immediately after the package version creation step (e.g., the first step after package version creation is installing the package version in a scratch org and running automated tests), then quick build is your best option.
  2. In your CI process, if you have a nightly build, a full build is likely best, as you don’t have developers actively waiting for the build to complete, making build speed less important.
  3. In your CI process, if you are doing 2-3 builds per day, and if your CI does not run tests outside of the build (unlike Scenario 1), async builds are likely best since developers are waiting, making build speed important.
Full Build Async Build Quick Build
Time to complete Most In between Least
Can promote to released state Yes, if code coverage > 75% Yes, if Apex tests pass and code coverage > 75% No
Executes Apex tests Yes Yes No
Validations run All All, package version is usable before Apex tests run Minimal
CLI command parameter None (this is the default option) --async-validation --skip-validation
When to use? No developers are waiting for the build to complete Developers are waiting, but you want to promote the resulting version Developers are waiting, and you don’t need to promote the resulting version

Try out all three of these on an existing package if you have one, and benchmark the duration of each. This is an important data point when deciding which to use.

Conclusion

Ultimately, you know your DevOps process and pipeline best, and you are most qualified to use a combination of these three build types to accomplish the best release management process. Happy innovating!

Resources

About the authors

Dileep Burki is part of the Salesforce Platform Product Management team overseeing products (managed packages, LMA, FMA, push upgrades) that enable ISVs to build, license, list, and distribute their business applications via AppExchange. His team also owns products (unlocked packages) that enable customers to adopt a package-based approach to managing their internal business applications.

James Quinn is a member of the Product Team working to make the Salesforce Platform extensible and easy to develop custom apps on. He strives to make partners’ and customers’ lives easier by actively listening to the community, driving developer experience standards across products internally, and rallying teams around a developer-focused product vision. Connect with him on LinkedIn.

Get the latest Salesforce Developer blog posts and podcast episodes via Slack or RSS.

Add to Slack Subscribe to RSS