CumulusCI includes a custom implementation of support for 2GP that takes a different approach than sfdx allowing for a better user experience and unlocking new capabilities for product teams. I’ll cover what’s different and the advantages that difference creates in this post.
What’s Different?
CumulusCI’s 2GP support is now over 2 years old and has been continually enhanced and matured over that time.
CumulusCI’s approach to user experience has always been about making complex tasks easy for users. We designed the 2GP implementation to reduce the need for manual steps wherever possible.
Aside from the fact that the end result is a 2GP package, CumulusCI’s implementation is completely custom and doesn’t utilize sfdx’s 2GP functionality. Instead, it directly interacts with the relevant objects in the Tooling API:
- Package2: A 2GP package
- Package2Version: A version of a 2GP package, contains the 04t… package version id in the SubscriberPackageVersionId field
- Package2VersionCreateRequest: A request to create a Package2Version of a Package2 with base64 encoded zipped package metadata
- Package2VersionCreateRequestError: An error from a Package2VersionCreateRequest attempt
- SubscriberPackageVersion: What we commonly think of as a package version. 1GP and 2GP packages both have records here. These records have the PackageVersionId that starts with 04t…
Advantages
By directly interfacing with the Tooling API objects, we were able to completely rethink the developer experience of creating 2gp packages. That enabled us to do things like:
- No need to create the package: CumulusCI queries the DevHub org to see if a package with that name and type exists and if not, create it for you automatically.
- No need to write to files: CumulusCI uses queries against the DevHub to look up the package id and the latest versions, removing the need to modify and commit files after each release. CumulusCI also stores release information in GitHub via tags, commit statuses, and releases and can inspect a repository. This is especially useful if you run builds on every push to your main branch and don’t want to have to rebuild just because you modified files to record a release.
- Skip upload of an existing version: This is a neat trick using the Tag field of Package2VersionCreateRequest. The documentation describes the field as “Optional tags for the package version” so we decided to create a hash of the zipped package metadata and put it in that field. Before creating a new version, we check if a version with that hash already exists and if so just reuse it. Of course, there are options to force upload no matter what, but this is a nice way of reducing the number of package versions you create.
- Automatically handle dependencies: CumulusCI was built for extension package development from the beginning. As a result, it has rich dependency management functionality to automate handling of dynamically resolved dependencies. Our goal was to leverage CumulusCI’s dependency management to automate 2GP dependency management.
- Namespace & Other String Injection: If you need to inject strings such as namespace prefixes or credentials into package source when creating a package, CumulusCI can handle that for you automatically since it’s directly interacting with the Package2VersionCreateRequest.
- Ability to Maintain Mulitple Package Lines: Want to maintain a separate unlocked package line for feature branch testing or have a separate package used to create unverified managed package versions for testing? CumulusCI’s 2GP implementation allows for this. This also applies to packages released in production as 1GP but who want to conduct packaged testing using 2GP. For more details on this approach, check out Find Bugs Earlier with Second-Generation Packaging on the Salesforce Architects blog.
All of these come together to create an amazingly seamless user experience for creating and releasing 2GP products.
CumulusCI Tasks and Flows for 2GP
Almost all the logic for creating package versions lives in the create_package_version
task which has options to specify the package name, type, and various other packaging options.
CumulusCI has always had built in flows for release operations that automate interaction with GitHub to create release artifacts like tags and releases. The built in release_2gp_beta
and release_2gp_production
handle the release operations automation for creating 2GP beta versions and promoting them to production.
More details about these flows is available in the Release Managed and Unlocked Packages section of CumulusCI documentation.
A Demo is Worth a Thousand Words?
The best way to illustrate the user experience made possible by CumulusCI’s 2GP implementation is to show the process of creating a new project, creating and testing a beta verison, then promoting it to production.
This demo uses the following commands:
# Create local git repo
$ mkdir CumulusCI2GPDemo
$ cd CumulusCI2GPDemo
$ git init
# Initialize CumulusCI
$ cci project init
# Create Dev Org
$ cci org default dev
$ cci flow run dev_org
# This demo existing package metadata. If you want to try yourself,
# you can use the following commands to access the scratch org and
# capture your changes from the org into the package source.
# You can also use VS Code or sfdx to capture the changes
$ cci org browser
$ cci task run retrieve_changes
# Commit local files
$ git add --all
$ git commit -m "Initial configuration for CumulusCI"
# Not shown in demo but required: Create a GitHub repo, link your
# local to it, and push using whatever git tooling you like
# Create 2GP Beta Version (and Package)
$ cci flow run release_2gp_beta
# Test the 2GP Beta Version in a new Scratch Org
$ cci flow run ci_beta --org
# Promote the 2GP Beta Version to Production
$ cci flow run release_2gp_production
And now, kick back and watch how easy it is to create 2GP package releases with CumulusCI in this screencast demo:
Conclusion
CumulusCI’s 2GP implementation takes a different approach to sfdx’s 2GP implementation. By interacting directly with the Tooling API objects for 2GP packaging, CumulusCI’s implementation is able to automate more of the user experience making 2GP packaging more powerful and adds new capabilities to 2GP based processes not available in sfdx alone.
While CumulusCI comes with a best practices based release operations automation, there are many options available to adapt to most product strategies and package architectures. Interested in learning more? Grab some time for us to chat at https://calendly.com/muselab
Comments