Start free
Andrew Hanna

Andrew Hanna

2GP CI/CD: Unlocked- und Managed-Package-Builds automatisieren

2GP CI/CD: Unlocked- und Managed-Package-Builds automatisieren

Kurze Antwort: Eine 2GP CI/CD-Pipeline erzeugt bei jedem Merge eine Paketversion, installiert diese Version in eine frische Scratch Org, laesst die Tests dagegen laufen und promotet nur, was besteht. Die Pipeline selbst sind fuenf Befehle. Was 2GP-Builds Monate spaeter wirklich bricht, ist nicht die Pipeline, sondern die Ancestry- und Namespace-Entscheidungen aus Woche eins.

Was macht eine 2GP CI/CD-Pipeline eigentlich?

Fuenf Stufen, in dieser Reihenfolge:

  1. Quellcode validieren. Statische Analyse und Linting am Pull Request, bevor etwas gebaut wird.
  2. Paketversion bauen. Eine Beta-Version, erzeugt aus dem Quellcode und nicht aus einer Org.
  3. Sauber installieren. Eine frische Scratch Org beweist, dass sich das Paket installieren laesst, und das ist eine andere Aussage als "der Code deployt".
  4. Gegen das installierte Paket testen. Code mit Namespace verhaelt sich nach dem Paketieren anders, Tests laufen also nach der Installation.
  5. Promoten, was besteht. Die Promotion ist das Tor und der einzige Schritt, der schwer ausloesbar sein sollte.

Der entscheidende Unterschied: Metadaten zu deployen beweist, dass sie in einer Org kompilieren, die Ihnen gehoert. Eine Paketversion zu installieren beweist, dass sie in einer Org funktioniert, die Ihnen nicht gehoert.

Was unterscheidet Unlocked und Managed 2GP?

  • Unlocked Packages sind fuer den eigenen oder den Org-Bestand eines Kunden. Kein Namespace noetig, keine Ancestry, keine Security Review. Versionen sind billig und ersetzbar.
  • Managed 2GP ist fuer die Distribution: registrierter Namespace, Schutz des geistigen Eigentums, Ancestry, Upgradepfade fuer Subscriber und AppExchange Security Review.

Die Form der Pipeline ist identisch. Die Folgen einer falschen Promotion nicht: eine bereute Unlocked-Version ersetzt man, eine promotete Managed-Version ist dauerhaft oeffentliche API.

Wie bauen Sie die Pipeline Schritt fuer Schritt?

  1. Dev Hub nicht-interaktiv authentifizieren. Ein JWT-Bearer-Flow mit Zertifikat im Secret Store Ihrer CI. Der Dev Hub muss die Org sein, der der Namespace gehoert, sonst scheitert die Versionserstellung sofort.
  2. Version erzeugen: sf package version create --package MyPackage --code-coverage --installation-key-bypass --wait 60. Die entstehende 04t-Id als Pipeline-Output sichern.
  3. Scratch Org starten: sf org create scratch --definition-file config/project-scratch-def.json --duration-days 1 --wait 10.
  4. Installieren und testen: sf package install --package 04tXXXX --wait 20, danach sf apex run test --test-level RunLocalTests --code-coverage --wait 30.
  5. Promoten, nur auf dem Release-Branch: sf package version promote --package [email protected].

Alles vor Schritt 5 laeuft bei jedem Pull Request. Schritt 5 laeuft auf genau einem Branch, hinter einer menschlichen Freigabe.

Wie bekommen Sie Ancestry und Namespace richtig hin?

Ancestry

Ancestry betrifft nur Managed 2GP, und genau dort laufen automatisierte Pipelines still aus dem Ruder. Salesforce verlangt, dass der angegebene Vorgaenger die hoechste promotete Versionsnummer des Pakets ist, und nur zu managed-released promotete Versionen duerfen als Vorgaenger gelten (Salesforce Developers). Drei Regeln fuer Ihre Pipeline:

  • Nutzen Sie das Schluesselwort. "ancestorVersion": "HIGHEST" in sfdx-project.json setzt den Vorgaenger automatisch auf die hoechste promotete Version, genau was CI braucht. Alternativen sind ein explizites major.minor.patch oder eine ancestorId.
  • Promoten Sie nie einen halb gruenen Build. Eine promotete Version wird zum naechsten Vorgaenger. Wer Rauschen promotet, vererbt Rauschen an die Linie.
  • Kennen Sie den Preis des Linienbruchs. Mit --skip-ancestor-check laesst sich die lineare Versionierung brechen, aber Pakete aktualisieren nur entlang der Ancestry-Linie: Subscriber auf einer aufgegebenen Version verlieren ihren Upgradepfad.

Patch-Versionen haben eine eigene Regel: Ein Patch kann nicht direkter Vorgaenger einer Nicht-Patch-Version sein.

Namespace

  • Verknuepfen Sie den Namespace mit dem Dev Hub, an dem sich Ihre CI anmeldet. Diese eine Abweichung ist der haeufigste Fehlschlag beim ersten Lauf.
  • 2GP erlaubt mehrere Pakete in einem Namespace. Trennen Sie nach Package Directory in sfdx-project.json und deklarieren Sie Abhaengigkeiten zwischen Paketen explizit, mit Versionen.
  • Sie kommen von 1GP? Salesforce hat Package Migrations mit Summer '25 allgemein verfuegbar gemacht: Konvertierung eines 1GP-Pakets nach 2GP mit sf package convert samt Migration installierter Subscriber.

Wie bleibt eine 2GP-Pipeline schnell?

  • Poolen Sie Ihre Scratch Orgs. Meist ist die Org-Erstellung langsamer als der Paketbau. Vorgewaermte Orgs nehmen sie aus dem kritischen Pfad.
  • Testumfang je Stufe. Relevante Tests am Pull Request, RunLocalTests vor der Promotion.
  • Version cachen. Hat sich die Quelle nicht geaendert, bauen Sie das Paket nicht neu.

All das laesst sich aus Salesforce CLI plus GitHub Actions, Azure Pipelines oder CumulusCI zusammensetzen. Serpent liefert dieselbe Pipeline ohne YAML: native 1GP-, 2GP- und Managed-Package-Workflows, Aufloesung paketuebergreifender Abhaengigkeiten und Versionsverwaltung ueber Subscriber-Orgs in jedem Plan, mit vorgewaermtem Scratch-Org-Pooling in Scale. Weitere Build- und Release-Guides finden Sie in den SF Guides.

FAQ

Laesst sich die 2GP-Paketerstellung vollstaendig automatisieren?

Ja. Versionserstellung, Installation, Tests und Promotion sind CLI-Befehle, der ganze Zyklus laeuft unbeaufsichtigt. Lassen Sie die Promotion trotzdem hinter einer menschlichen Freigabe.

Was ist Package Ancestry in 2GP?

Die deklarierte Abstammung zwischen Managed-Paketversionen. Sie definiert den Upgradepfad der Subscriber, denn Pakete aktualisieren nur entlang dieser Linie.

Brauchen Unlocked Packages einen Namespace?

Nein. Sie kommen ohne aus, deshalb passen sie zu internen Org-Bestaenden. Managed 2GP verlangt einen registrierten, mit dem Dev Hub verknuepften Namespace.

Warum scheitert meine Versionserstellung an der Ancestry?

Meist weil der genannte Vorgaenger keine promotete, managed-released Version ist, oder weil eine Patch-Version als Vorgaenger einer Nicht-Patch-Version gesetzt wurde.

Soll die CI jeden gruenen Build promoten?

Nein. Promotion ist praktisch unumkehrbar und setzt den naechsten Vorgaenger, gehoert also auf einen Release-Branch hinter eine Freigabe, nicht in jeden Merge.

Ähnliche Artikel

Neugierig auf schnelleres Shipping, bevor Sie einsteigen? Sprechen wir

Unverbindlich.