Build-afhankelijkheden voor uw pipeline plannen

Voltooid

In deze les leert u hoe u code inpakt, zodat u deze eenvoudiger kunt delen. U ontdekt waarom u pakketten moet maken, de soorten pakketten die u kunt maken, waar u de pakketten kunt hosten en hoe u ze kunt openen wanneer ze worden gehost. U krijgt ook informatie over pakketversiebeheer.

Codebases worden altijd groter en complexer. Het is ongebruikelijk dat een team alle code schrijft die door de app wordt gebruikt. In plaats daarvan bevat het team bestaande code die is geschreven door andere ontwikkelaars. Er kunnen veel van deze pakketten of afhankelijkheden in een app zijn. Het is belangrijk dat u deze afhankelijkheden actief beheert om ze correct te kunnen onderhouden en ervoor te zorgen dat ze voldoen aan de beveiligingsvereisten.

Laten we eens kijken hoe het team het doet. Andy heeft het team bij elkaar geroepen om te praten over een potentiële wijziging van de code waarmee een ander team kan worden geholpen.

Teamvergadering

Andy: Hallo iedereen. Ik was aan het chatten met het team dat aan het back-endsysteem voor Space Game werkte. Ze kunnen de modellen gebruiken die we voor de website gebruiken in een back-end-app die ze willen schrijven.

Amita: Wat bedoel je met modellen?

Andy: Zoals u weet, is de Space Game-website een ASP.NET Core-toepassing. Het maakt gebruik van het patroon Model-View-Controller (of MVC) om gegevens te scheiden van de manier waarop die gegevens worden weergegeven in de gebruikersinterface. Ik dacht dat we een pakket konden maken dat onze modelklassen bevat, zodat elke app deze kan gebruiken.

Amita: Wat is het doel precies?

Andy: Beide teams delen dezelfde database. Vanuit de game ontvangt de database de hoogste scores; wij lezen die scores om ze op het scoreboard weer te geven.

Amita: Dat is logisch. Hoe maken we dat pakket?

Andy: Daarom wilde ik met je chatten. Er zijn enkele opties en ik zoek ideeën.

Tim: Ik wil graag helpen, maar eerst heb ik wat vragen. Ik ben nieuw hier en wil weten hoe het allemaal werkt.

Wat is een pakket?

Een pakket maakt gebruik van herbruikbare code die andere ontwikkelaars in hun projecten kunnen gebruiken, ook al hebben ze de code zelf niet geschreven.

Voor gecompileerde talen bevat een pakket doorgaans de gecompileerde binaire code, zoals .dll bestanden in .NET of .class-bestanden in Java. Voor programmeertalen die worden geïnterpreteerd in plaats van gecompileerd, zoals JavaScript of Python, kan een pakket broncode bevatten.

Hoe dan ook, pakketten worden gewoonlijk gecomprimeerd naar een zip-indeling of iets dergelijks. Pakketsystemen definiëren vaak een unieke bestandsextensie, zoals .nupkg of .jar, om het gebruik van het pakket duidelijk te maken. Compressie kan helpen de downloadtijd te verminderen en ook één bestand te produceren om het beheer te vereenvoudigen.

Pakketten bevatten ook vaak een of meer bestanden met metagegevens of informatie over het pakket. Deze metagegevens bevatten informatie over wat het pakket doet, de licentievoorwaarden, de contactgegevens van de auteur en de pakketversie.

Waarom zou ik een pakket maken?

Het maken van een pakket biedt voordelen ten opzichte van het dupliceren van de code.

Een van de redenen om een pakket te maken is om drift te voorkomen. Wanneer code wordt gedupliceerd, kan elke kopie snel afwijken om te voldoen aan de vereisten van een bepaalde app. Het wordt op een gegeven moment lastig om wijzigingen van de ene kopie naar de andere kopieën te migreren. Met andere woorden, u kunt dan niet meer de code verbeteren op een manier dat iedereen er wat aan heeft.

In pakketten wordt ook gerelateerde functionaliteit in één herbruikbare component ondergebracht. Afhankelijk van de programmeertaal kan een pakket apps toegang bieden tot bepaalde typen en functies, terwijl de toegang tot hun implementatiedetails wordt beperkt.

Een andere reden om een pakket te maken is dat u een consistente manier hebt om de functionaliteit van het pakket te bouwen en te testen. Wanneer code wordt gedupliceerd, kan elke app die code op verschillende manieren bouwen en testen. Een reeks tests kan controles bevatten waaruit een andere set kan profiteren.

Een compromis is dat u een andere codebasis hebt om te testen en te onderhouden met een pakket. U moet ook voorzichtig zijn bij het toevoegen van functies. Over het algemeen moet een pakket functies bevatten die veel soorten apps ten goede komen. Json.NET is bijvoorbeeld een populair NuGet-pakket voor .NET waarmee u met JSON-bestanden kunt werken. Json.NET is open-source, dus de community kan verbeteringen voorstellen en problemen melden.

Wanneer meerdere apps kunnen profiteren van dezelfde code, wegen de voordelen veel op tegen de nadelen. Er is slechts één codebasis, slechts één reeks tests en slechts één buildproces dat u hoeft te beheren.

Hoe kan ik afhankelijkheden identificeren?

Als het doel is om uw code opnieuw in afzonderlijke onderdelen te organiseren, moet u die onderdelen van uw app identificeren die kunnen worden verwijderd, verpakt om herbruikbaar te worden gemaakt, opgeslagen op een centrale locatie en versiebeheer. Mogelijk wilt u zelfs uw eigen code vervangen door onderdelen van derden die open source zijn of die u een licentie hebt.

Er zijn veel manieren om de potentiële afhankelijkheden in uw codebasis te identificeren. Dit omvat het scannen van uw code op patronen van hergebruik en het analyseren van de architectuur van uw oplossing. Hier volgen enkele manieren om afhankelijkheden te identificeren:

  • Dubbele code.

    Als bepaalde stukjes code op verschillende plaatsen worden weergegeven, is dat een goede indicatie dat u de code opnieuw kunt gebruiken. Centraliseer deze dubbele stukjes code en verpak ze op de juiste manier.

  • Hoge samenhang en lage koppeling.

    Een tweede benadering is om te zoeken naar code-elementen die een hoge samenhang met elkaar hebben en weinig koppeling met andere onderdelen van de code. In wezen betekent een hoge samenhang dat delen van een codebasis die op één plaats aan elkaar zijn gerelateerd, behouden blijven. Een lage koppeling gaat over het zoveel mogelijk scheiden van niet-gerelateerde delen van de codebasis.

  • Individuele levenscyclus.

    Zoek naar onderdelen van de code met een vergelijkbare levenscyclus die u afzonderlijk kunt implementeren en vrijgeven. Als deze code kan worden onderhouden door een afzonderlijk team, is het een goede indicatie dat u deze als onderdeel buiten de oplossing kunt verpakken.

  • Stabiele onderdelen.

    Sommige onderdelen van uw codebasis zijn mogelijk stabiel en veranderen onregelmatig. Controleer de codeopslagplaats om code met een lage wijzigingsfrequentie te vinden.

  • Onafhankelijke code en onderdelen.

    Wanneer code en onderdelen onafhankelijk en niet gerelateerd zijn aan andere onderdelen van het systeem, kunt u deze mogelijk isoleren in afzonderlijke afhankelijkheden.

U kunt verschillende hulpprogramma's gebruiken om u te helpen bij het scannen en onderzoeken van uw codebasis. Deze variëren van hulpprogramma's die scannen op dubbele code en oplossingsafhankelijkheidsgrafieken tekenen tot hulpprogramma's waarmee metrische gegevens kunnen worden berekend voor koppeling en samenhang.

Welke soorten pakketten zijn er?

Elke programmeertaal of framework heeft zijn eigen manier waarop pakketten kunnen worden gebouwd. Populaire pakketsystemen bieden documentatie over hoe het proces werkt.

Mogelijk bent u al bekend met deze populaire pakketsystemen:

  • NuGet: verpakt .NET-bibliotheken
  • NPM: verpakt JavaScript-bibliotheken
  • Maven: verpakt Java-bibliotheken
  • Docker: verpakt software in geïsoleerde eenheden die containers worden genoemd

Waar worden de pakketten gehost?

U kunt pakketten hosten op uw eigen netwerk of u kunt een hostingservice gebruiken. Een hostingservice wordt ook wel een pakketopslagplaats of pakketregister genoemd. Veel van deze services bieden gratis hosting voor opensource-projecten.

Hier volgen enkele populaire hostingservices voor de pakkettypen die we zojuist hebben beschreven:

  • NuGet Gallery

    NuGet-pakketten worden gebruikt voor .NET-codeartefacten. Deze artefacten omvatten .NET-assembly's en gerelateerde bestanden, hulpprogramma's en, soms, metagegevens. NuGet definieert de manier waarop pakketten worden gemaakt, opgeslagen en gebruikt. Een NuGet-pakket is in feite een gecomprimeerde mapstructuur met bestanden in de ZIP-indeling en heeft de extensie .nupkg .

  • NPM

    Er wordt een NPM-pakket gebruikt voor JavaScript. Een NPM-pakket is een bestand of map met JavaScript-bestanden en een package.json-bestand dat de metagegevens van het pakket beschrijft. Voor node.js bevat het pakket meestal een of meer modules die kunnen worden geladen nadat het pakket is verbruikt.

  • Centrale Maven-opslagplaats

    Maven wordt gebruikt voor Java-projecten. Elk pakket heeft een Project Object Model-bestand dat de metagegevens van het project beschrijft en is de basiseenheid voor het definiëren van een pakket en het werken ermee.

  • Docker Hub

    Docker-pakketten worden installatiekopieën genoemd en bevatten volledige, zelfstandige implementaties. Meestal vertegenwoordigt een Docker-installatiekopie een softwareonderdeel dat door zichzelf kan worden gehost en uitgevoerd, zonder afhankelijkheden van andere installatiekopieën. Docker-installatiekopieën zijn gelaagd en zijn mogelijk afhankelijk van andere installatiekopieën.

Een pakketfeed verwijst naar de server met de pakketopslagplaats. Deze server kan zich op internet of achter uw firewall in uw netwerk bevinden. U kunt bijvoorbeeld uw eigen NuGet-feeds hosten met behulp van hostingproducten zoals Azure Artifacts en MyGet. U kunt ook pakketten op een bestandsshare hosten.

Als u pakketten achter een firewall host, kunt u feeds opnemen voor uw eigen pakketten. U kunt ook pakketten die u vertrouwt op uw netwerk in de cache opslaan wanneer uw systemen geen verbinding kunnen maken met internet.

Welke elementen vormen een goede strategie voor afhankelijkheidsbeheer?

Een goede strategie voor afhankelijkheidsbeheer is afhankelijk van deze drie elementen:

  • Standaardisatie.

    Door te standaardiseren hoe u afhankelijkheden declareert en oplost, blijft uw geautomatiseerde releaseproces herhaalbaar en voorspelbaar.

  • Verpakkingsindelingen en bronnen.

    Elke afhankelijkheid moet worden verpakt met behulp van de toepasselijke indeling en opgeslagen op een centrale locatie.

  • Versiebeheer.

    U moet de wijzigingen bijhouden die zich in de loop van de tijd voordoen in afhankelijkheden, net zoals u doet met uw eigen code. Dit betekent dat afhankelijkheden moeten worden geversied.

Wie heeft er toegang tot pakketten?

Veel pakketfeeds bieden onbeperkte toegang tot pakketten. U kunt bijvoorbeeld Json.NET downloaden van nuget.org, zonder dat u zich hoeft aan te melden of te verifiëren.

Voor andere pakketfeeds is verificatie vereist. U kunt de toegang tot feeds op een aantal manieren verifiëren. Voor sommige soorten feeds is een gebruikersnaam en wachtwoord vereist. Voor andere feeds is een toegangstoken vereist. Dit is meestal een lange reeks tekens die aangeeft wie u bent en tot welke resources u toegang hebt. U kunt instellen dat toegangstokens verlopen na een bepaalde periode.

Hoe vindt het versiebeheer van pakketten plaats?

Het versiebeheerschema is afhankelijk van het verpakkingssysteem dat u gebruikt.

Zo maakt NuGet gebruik van Semantic Versioning.

Semantic Versioning is een populaire versiebeheerschema. Dit is de indeling:

Major.Minor.Patch[-achtervoegsel]

Dit is wat elk van deze parameters betekent:

  • Een nieuwe, primaire versie introduceert wijzigingen die fouten veroorzaken. Apps moeten doorgaans bijwerken hoe ze het pakket gebruiken om te werken met een nieuwe primaire versie.
  • Een nieuwe secundaire versie introduceert nieuwe functies, maar is achterwaarts compatibel met eerdere versies.
  • Een nieuwe patch introduceert achterwaarts compatibele bugfixes, maar geen nieuwe functies.
  • Het gedeelte -achtervoegsel is optioneel en herkent het pakket als een pre-release-versie. 1.0.0-beta1 kan bijvoorbeeld het pakket identificeren als de eerste bèta-prerelease-build voor de release 1.0.0.

Verwijzen naar een pakket gebeurt door middel van een versienummer.

Hier volgt een voorbeeld van het installeren van een pakket met behulp van PowerShell en een specifiek versienummer:

Install-Package Newtonsoft.Json -Version 13.0.1

Wat gebeurt er als het pakket wordt gewijzigd?

Wanneer u vanuit uw app naar een pakket verwijst, maakt u doorgaans de versie van dat pakket vast of geeft u deze op.

Met veel frameworks kunt u toegestane bereiken van pakketversies opgeven die moeten worden geïnstalleerd. Sommige bieden u ook de mogelijkheid om jokertekens op te geven, die we een zwevende versie noemen.

Zo betekent NuGet versie 1.0 de eerste versie dat gelijk is aan of groter dan 1.0. [1.0] geeft aan dat alleen versie 1.0 moet worden geïnstalleerd en geen nieuwere versie.

Hier volgen enkele andere voorbeelden:

Deze notatie: Selecteert:
(1.0,) De eerste versie die groter is dan 1.
[1.0,2.0] De eerste versie die groter is dan of gelijk is aan 1.0 en kleiner dan of gelijk aan 2.0
(1.0,2.0) De eerste versie die groter is dan 1.0 en kleiner dan 2.0
[1.0,2.0) De eerste versie die groter is dan of gelijk is aan 1.0 en kleiner dan 2.0

Wanneer elke onderhouder een nieuwe pakketversie publiceert, kunt u evalueren wat er is gewijzigd en uw app erop testen. Als u klaar bent, kunt u het pakketversienummer bijwerken in uw configuratie en de wijziging naar uw build-pipeline verzenden.

Hier volgt een voorbeeld van hoe u het Newtonsoft.Json-pakket kunt opnemen in het projectbestand (.csproj) van uw C#-toepassing. In dit voorbeeld wordt versie 13.0.1 van dat pakket opgegeven:

<ItemGroup>
  <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>

Kennis testen

1.

Wat is een pakket?

2.

Stel dat u een pakket hebt gemaakt dat u openbaar wilt delen. Hoe kunt u dat het eenvoudigst doen?