Find Bugs Earlier with Second-Generation Packaging

Magnifying glass image

Building a trusted development lifecycle

What are packaging, 1GP, and 2GP?

Identifying legacy development process risks

  • Developers and product managers collaborate to design and build new features. This development takes place in a feature branch in the version control system, separate from the production code delivered to customers.
  • As a feature is developed, it’s tested along the way. At this stage, the team can only test changes to the product in an “unmanaged” form. The package that will really ship to customers hasn’t been created yet, which means the process does not meet the ideal state we talked about above. Since testing does not involve a real packaged version, there’s space for bugs to slip through.
  • Well-tested features move forward and are integrated into the main branch, representing the production code base. Then, package versions can be built, allowing for regression testing in a production-like environment. For first-generation managed packages in particular, it’s critical to preserve the integrity of the main branch and the packaging org.
  • Lastly, customers receive a released version of the package incorporating the new changes.
Development process before second-generation packaging

The challenges of end-to-end testing

Nonprofit Success Pack (NPSP) package architecture
  • Across all of the components of the product, development takes place in individual feature branches.
  • Each package or component’s changes are tested in isolation. In some cases, especially with features that have cross-package or off-platform dependencies, it’s impossible to fully test functionality at this stage. Even worse, some types of dependency prevent even feature testing from taking place for extension packages until a full release is completed in core packages.
  • Only once development is completed, merges are completed, and package versions are created can end-to-end testing take place. This entails assembling the latest versions of each component into an environment and performing end-to-end tests there. If any bugs are discovered, the process has to begin again — starting with the top of the dependency hierarchy and moving down.
  • Lastly, once all of the tests are successful, the release and delivery process can proceed.
Diagram of first generation packaged based software development lifecycle

Testing with second-generation packaging

Shifting feature testing left

  • Development takes place in a feature branch in our version control system, separated from the production code that we are currently delivering to customers. As the feature is developed, CumulusCI and MetaCI continuously build second-generation package versions from every single commit — a real artifact similar to what we will ultimately ship to a customer, with the same namespace as our production package.
  • We test the second-generation package version in continuous integration and via manual QA, giving us clear, consistent results reflecting what this work would look like when we ship in production. Using a real package at this level gives us a better picture of our customers’ experience and enables us to catch more bugs early in the development lifecycle.
  • Once a feature has completed testing, we can move forward confidently with integrating the changes into our production (main) code base. Then, we create a beta version of our package, and execute a final regression test pass — one where we can be more confident that critical bugs have already been found early in the process.
  • Lastly, once all final tests are completed, we create a release version of our package, and deliver it to our customers.
Diagram of second-generation packaged based software development lifecycle

Shifting end-to-end testing left

  • Across all of the components of the application (packages), development takes place in feature branches. Development teams use shared naming conventions — like feature/improve-customer-experience — across packages to correlate cross-package features in development.
  • On each commit, continuous integration builds a namespaced, second-generation beta managed package version using the Skip Validation option. This yields a package artifact that’s very similar (but not identical) to the packages we ship to customers, and using this specific package type offers us more capabilities we’ll discuss below.
  • Test builds create orgs that contain these package versions across a whole product. For example, if we have a feature/improve-customer-experience in development across packages A, B, and C, then our test builds will include the second-generation managed packages built from that feature branch, from all three packages.


  • We’ve moved risk left by testing in customer-like environments before we merge any code.
  • We’ve added a completely new capability: testing multiple dependent products, end-to-end, before cutting any releases at all.
  • We’ve improved our ability to scale and parallelize development work across large, complex package suites.
  • We’re more prepared for future migration of first-generation managed package products to second-generation packaging.

About the Authors



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Salesforce Architects

Salesforce Architects


We exist to empower, inspire and connect the best folks around: Salesforce Architects.