Start free
Andrew Hanna

Andrew Hanna

Cross-package dependency resolution in Salesforce: modelleren, installatievolgorde en veilige upgrades

Cross-package dependency resolution in Salesforce: modelleren, installatievolgorde en veilige upgrades

Kort antwoord: cross-package dependency resolution is hoe Salesforce bepaalt welke packages al aanwezig moeten zijn, en in welke versies, voordat een ander package kan installeren of upgraden. Je legt dat vast in de array dependencies in sfdx-project.json, in installatievolgorde. Klopt de volgorde en kloppen de minimumversies, dan zijn upgrades bij subscribers saai. Klopt het niet, dan belandt een org op een versie waar hij niet meer vanaf komt.

Wat is een package-afhankelijkheid precies?

Er is een afhankelijkheid zodra metadata in het ene package verwijst naar metadata in het andere: een Flow op een managed object, een Apex-klasse die een baseklasse uitbreidt, een field set op andermans veld. Het praktische gevolg is een voorwaarde vooraf. Het package waarnaar verwezen wordt moet eerst geinstalleerd zijn, in een versie die minstens zo nieuw is als die waartegen je bouwde, anders faalt de installatie.

Hoe leg je een afhankelijkheid vast?

In het packagedirectory-item van sfdx-project.json, in een van twee vormen:

  • Een alias die de versie al bevat: { "package": "[email protected]" }
  • Package en versie apart: { "package": "MyPackage", "versionNumber": "1.0.0.RELEASED" }

Drie regels tellen zwaarder dan de syntax.

  • De volgorde is de installatievolgorde. Heeft een package meerdere afhankelijkheden, dan wordt de lijst gelezen als de volgorde waarin ze geinstalleerd moeten worden.
  • Circulaire afhankelijkheden worden niet ondersteund. A die van B afhangt terwijl B van A afhangt is geen puzzel om op te lossen, maar een ontwerp om op te knippen.
  • Ketens over meerdere niveaus kunnen wel. C mag van B afhangen en B van A. Zet "calculateTransitiveDependencies": true en je declareert alleen directe afhankelijkheden, terwijl de indirecte worden berekend. Laat je dat uit, dan moet je elk niveau zelf blijven opsommen.

Welke packagetypes mogen van welke afhangen?

Dit beperkt de architectuur, dus controleer het voordat je die tekent.

  • Managed 2GP mag afhangen van managed 2GP en van unlocked packages.
  • Managed 2GP mag niet afhangen van managed 1GP. Salesforce blokkeert het installeren van managed 2GP-packages in managed 1GP-packagingorgs. Heeft je product het echt nodig, dan loopt de route via een case bij Salesforce Partner Support voor een individuele uitzondering, niet via een trucje in een buildscript.
  • Managed 1GP mag afhangen van managed 1GP, managed 2GP en unlocked packages.
  • Unlocked packages die van managed packages afhangen worden afgeraden, en niets ondersteunds hangt af van een unmanaged package.

Een 1GP-basepackage onder een 2GP-uitbreiding is het meest voorkomende afhankelijkheidsontwerp dat laat weer ontrafeld moet worden, en op dat moment is het duur. Lees de ondersteunde combinaties voor de eerste build, niet erna.

Hoe modelleer je packages zodat de graaf ondiep blijft?

  1. Maar een richting. Basis, dan feature, dan rand. Willen twee packages naar elkaar verwijzen, dan hoort de gedeelde metadata in een derde package eronder.
  2. Klein en modulair verslaat een groot package. Zowel aanmaken als installeren gaat sneller, en je loopt minder snel tegen limieten aan.
  3. Diepte is de dure dimensie, niet breedte. Elk extra niveau vermenigvuldigt de releasecoordinatie: een wijziging onderaan vraagt een nieuwe versie op elk niveau erboven voordat een subscriber er iets van ziet.
  4. Pin bewust. Een vastgelegd buildnummer is reproduceerbaar en saai. Een keyword als RELEASED volgt je laatst uitgebrachte versie, wat handig is tijdens ontwikkeling en een verrassing in een releasebuild.

Wat is de juiste installatievolgorde in een subscriber-org?

  1. Installeer of upgrade eerst het laagste package in de graaf, dat zelf geen afhankelijkheden heeft.
  2. Werk niveau voor niveau omhoog, zodat elk package aan zijn voorwaarde voldoet op het moment dat het installeert.
  3. Installeer het bovenste package, dat wat je klant daadwerkelijk kocht, als laatste.
  4. Controleer in plaats van aan te nemen. Een SOQL-query op SubscriberPackageVersion vertelt je wat er in die org staat en in welke versie, wat beter is dan de pagina Installed Packages lezen en hopen.

Kun je die volgorde voor je eigen product niet uit je hoofd opnoemen, dan kan je supportteam dat ook niet op het moment dat een klant vastzit.

Hoe wijzig je een afhankelijkheid zonder subscribers vast te zetten?

  • De nieuwe versie moet een directe afstammeling zijn van de geinstalleerde. Subscribers kunnen de lijn niet overslaan, dus een package met gebroken ancestry is een package dat sommige orgs niet kunnen upgraden.
  • Beta-packages zijn niet upgradebaar. Een subscriber met een beta moet eerst deinstalleren voordat hij een released versie installeert, en in productie is dat een gesprek over dataverlies. Laat nooit een beta achter in een klantorg.
  • Verwijderde metadata wordt bij een upgrade deprecated of verwijderd. Een component van het ene naar het andere package verplaatsen is een verwijdering in het ene en een toevoeging in het andere, dus de releasevolgorde tussen die twee is het hele risico.
  • Verhoog minimumversies stap voor stap. De vereiste versie van een basepackage in een keer meerdere releases optillen dwingt een keten van upgrades af bij subscribers die daar niet op rekenden.

De volgorde die werkt als een basepackage verandert: breng de nieuwe baseversie uit, breng subscribers erop met een recommended version of een push upgrade, en breng dan pas het afhankelijke package uit dat die versie vereist. Draai je die twee om, dan krijg je een upgrade die faalt op een voorwaarde in een org die je niet ziet en van jouw kant niet kunt repareren.

Wat automatiseer je?

  1. Bouw de graaf bij elke pipelinerun uit sfdx-project.json en laat de build falen op een cyclus.
  2. Installeer de hele keten telkens in de opgegeven volgorde in een schone scratch org, zodat volgordefouten bij de build opduiken en niet in een klantorg.
  3. Leg per subscriber-org de geinstalleerde versies vast, zodat support de vraag kan beantwoorden voordat hij hem aan de klant stelt.

Serpent doet cross-package dependency resolution, 1GP-, 2GP- en managed-packageworkflows en versiebeheer over subscriber-orgs op elk plan, inclusief het gratis plan. Meer packaging-playbooks vind je in onze SF Guides-bibliotheek.

FAQ

Mag een managed 2GP-package afhangen van een managed 1GP-package?

Standaard niet. Salesforce blokkeert die combinatie, en een individuele uitzondering vraag je aan via een case bij Salesforce Partner Support.

Moet ik transitieve afhankelijkheden opsommen?

Alleen als je dat wilt. Met "calculateTransitiveDependencies": true declareer je directe afhankelijkheden en worden de indirecte berekend. Zonder dat moet elk niveau met de hand in de lijst.

Wat gebeurt er als twee packages van elkaar afhangen?

Niets goeds, want circulaire afhankelijkheden worden niet ondersteund. Haal de gedeelde metadata uit elkaar naar een lager package waar beide van afhangen.

Welk package upgrade ik als eerste in een subscriber-org?

Het package dat het diepst in de graaf zit. Afhankelijkheden gaan voor de packages die ze nodig hebben, in dezelfde volgorde als bij de installatie.

Waarom faalt de upgrade van mijn klant met een dependency-fout?

Meestal een te lage minimumversie. Het geinstalleerde basepackage is ouder dan wat je nieuwe release vereist, dus upgrade eerst het basepackage en probeer opnieuw.

Gerelateerde artikelen

Benieuwd naar sneller releasen voordat je instapt? Laten we praten

Vrijblijvend.