
Andrew Hanna

Andrew Hanna

Short answer: the Salesforce DevOps category grew up solving org-to-org deployment, so its primitives are environments and metadata, not versioned artifacts. Package delivery, 1GP, 2GP and managed packages, arrived as an afterthought and is still commonly sold as an upgrade. That is why, in 2026, most ISVs and PDOs still release their product from scripts they wrote themselves.
An org-to-org release is short: build a change set, validate it against the target, deploy it. A package release is a different shape entirely:
Only step three looks anything like a deployment. Everything else is artifact management, and a pipeline that models environments has nowhere to put it.
Because that is where the volume is. The overwhelming majority of Salesforce teams run a single production org with a fan of sandboxes, and their release problem is genuinely "get this change from UAT to production without breaking anything." Copado, Gearset, AutoRABIT, Flosum, Salto and Blue Canvas all built strong products against that problem, and the model they share is the same: environments, branches, metadata, diffs.
None of those primitives contain a version number. A package is not a diff between two orgs. It is an immutable artifact with an identity, an ancestor, and a population of installs living in orgs you do not control.
Because that is what the ecosystem tells them to do. Search for how to release a 2GP
package and the results are step-by-step guides to building your own pipeline in Azure
DevOps or GitHub Actions, chaining sf package version create and
sf package version promote by hand. Salesforce's own
second-generation managed packaging guide
puts it plainly: packaging operations run via the CLI, or you automate them with
scripts.
That is a fine answer for a platform. It is a strange answer for a category that sells release automation.
Meanwhile the platform keeps moving.
Package Migrations went generally available in Summer '25, adding sf package convert to turn a 1GP version into a 2GP one and a
--migrate-to-2gp push upgrade that repoints subscribers without a
reinstall. A 1GP publisher now has a real migration path, and a real need for a
pipeline that understands both generations at once. Most tooling still treats
packaging as an integration you bolt on.
Three things, and they compound:
The test is simple: can the same pipeline that ships an org change also cut a version, resolve dependencies, install into a test matrix, promote and track subscribers, without leaving the product? On the same plan, not on the enterprise one.
That is the gap Serpent was built around, out of running an eHealth ISV through managed packages and AppExchange security review. 1GP, 2GP and managed-package workflows, cross-package dependency resolution, version management across subscriber orgs and AppExchange release workflows are on every plan, including the free tier, with pre-warmed scratch org pooling on Scale so clean-org validation stays cheap enough to keep running. See how Serpent handles package delivery.
Is 2GP required, or can I stay on 1GP?
You can stay, but the platform investment is going into 2GP. Package Migrations, generally available since Summer '25, converts a 1GP version and repoints subscribers with a push upgrade.
Can I not just use GitHub Actions?
You can, and many teams do. The cost is that you own the ancestry logic, the dependency ordering, the subscriber tracking and the person who understands it all.
Does this only matter for AppExchange ISVs?
No. Any team using unlocked or managed packages for internal modularity hits the same primitives, minus the security review.
What is the single hardest part of a package release?
Ancestry and promotion, because both are irreversible. A wrong ancestor breaks the upgrade path for every subscriber, and a promoted version cannot be unpromoted.
Commitment free!