Planera byggberoenden för din pipeline

Slutförd

I den här lektionen får du lära dig mer om paketeringskod för att göra det enklare att dela. Du kommer att upptäcka varför du bör skapa paket, vilka typer av paket du kan skapa, var du kan vara värd för paketen och hur du kan komma åt dem när de finns. Du får också lära dig mer om paketversionshantering.

Kodbaser blir alltid större och mer komplexa. Det är ovanligt att ett team skriver all kod som appen använder. I stället innehåller teamet befintlig kod som skrivits av andra utvecklare. Det kan finnas många av dessa paket, eller beroenden, i en app. Det är viktigt att aktivt hantera dessa beroenden för att kunna underhålla dem korrekt och se till att de uppfyller säkerhetskraven.

Nu ska vi kolla in och se hur det går för teamet. Andy har samlat teamet för att prata om en eventuell ändring i koden som skulle vara till hjälp för ett annat team.

Teammöte

Andy: Hej alla. Jag chattade med teamet som arbetar med backend-systemet för Space Game. De kan använda de modeller som vi använder för webbplatsen i en serverdelsapp som de planerar att skriva.

Amita: Vad menar du med modeller?

Andy: Som du vet är Space Game-webbplatsen ett ASP.NET Core-program. Den använder mönstret Model-View-Controller – eller MVC – för att separera data från hur dessa data visas i användargränssnittet. Jag tänkte att vi kunde skapa ett paket som innehåller våra modellklasser så att alla appar kan använda dem.

Amita: Vad exakt är målet?

Andy: Båda våra team delar samma databas. Spelet skickar de högsta poängen till databasen och vi läser dessa poäng så att vi kan visa dem på resultattavlan.

Amita: Det är vettigt. Hur ska vi skapa det här paketet?

Det var därför jag ville prata med dig. Vi har några alternativ och jag behöver fler idéer.

Tim: Jag skulle gärna hjälpa till, men först har jag några frågor. Det här är nytt för mig och jag vill förstå hur allt fungerar.

Vad är ett paket?

Ett paket innehåller återanvändbar kod som andra utvecklare kan använda i sina projekt, trots att de inte skrivit den.

För kompilerade språk innehåller ett paket vanligtvis den kompilerade binära koden, till exempel .dll filer i .NET eller .class-filer i Java. För språk som tolkas i stället för att kompileras, till exempel JavaScript eller Python kan ett paket innehålla källkod.

I båda fallen komprimeras paketen normalt till ZIP eller liknande format. Paketsystem definierar ofta ett unikt filnamnstillägg, till exempel .nupkg eller .jar, för att göra paketets användning tydlig. Komprimering kan minska nedladdningstiden och även skapa en enda fil för att förenkla hanteringen.

Paket innehåller också ofta en eller flera filer som tillhandahåller metadata eller information om paketet. Dessa metadata kan beskriva vad paketet gör och innehålla dess licensvillkor, författarens kontaktinformation och paketets version.

Varför ska jag skapa ett paket?

Det finns fördelar med att skapa ett paket i stället för att duplicera koden.

En anledning till att skapa ett paket i stället för att duplicera kod är att förhindra avvikelser. När koden dupliceras kan varje kopia snabbt avvika för att uppfylla kraven för en viss app. Det blir svårt att flytta ändringar från en kopia till andra. Med andra ord förlorar du möjligheten att förbättra koden på ett sätt som alla kan dra nytta av.

Paket innebär också att relaterade funktioner samlas i en återanvändbar komponent. Beroende på programmeringsspråket kan ett paket ge appar åtkomst till vissa typer och funktioner, samtidigt som åtkomsten till deras implementeringsinformation begränsas.

Ett annat skäl till att skapa paket är att du får ett enhetligt sätt att skapa och testa paketets funktionalitet. När koden dupliceras kan varje app skapa och testa koden på olika sätt. En uppsättning tester kan innehålla kontroller som en annan uppsättning kan ha nytta av.

En kompromiss är att du har en annan kodbas att testa och underhålla med ett paket. Du måste också vara försiktig när du lägger till funktioner. Generellt sett bör ett paket innehålla funktioner som gynnar många typer av appar. Till exempel är Json.NET ett populärt NuGet-paket för .NET som gör att du kan arbeta med JSON-filer. Json.NET är öppen källkod, vilket innebär att communityn kan föreslå förbättringar och rapportera problem.

När flera appar kan dra nytta av samma kod uppväger fördelarna vida nackdelarna. Du har bara en kodbas, bara en uppsättning med tester och bara en byggprocess att hantera.

Hur kan jag identifiera beroenden?

Om målet är att omorganisera koden till separata komponenter måste du identifiera de delar av appen som kan tas bort, paketeras för att kunna återanvändas, lagras på en central plats och versionshanteras. Du kanske till och med vill ersätta din egen kod med komponenter från tredje part som antingen är öppen källkod eller som du licensierar.

Det finns många sätt att identifiera potentiella beroenden i din kodbas. Dessa inkluderar genomsökning av koden efter återanvändningsmönster och analys av lösningens arkitektur. Här följer några sätt att identifiera beroenden:

  • Duplicerad kod.

    Om vissa delar av koden visas på flera platser är det en bra indikation på att du kan återanvända koden. Centralisera dessa dubbletter av kod och packa om dem på rätt sätt.

  • Hög sammanhållning och låg koppling.

    En annan metod är att leta efter kodelement som har hög sammanhållning till varandra och låg koppling till andra delar av koden. I grund och botten innebär hög sammanhållning att delar av en kodbas som är relaterade till varandra hålls kvar på en enda plats. Låg koppling handlar samtidigt om att separera orelaterade delar av kodbasen så mycket som möjligt.

  • Individuell livscykel.

    Leta efter delar av koden som har en liknande livscykel som du kan distribuera och släppa individuellt. Om den här koden kan underhållas av ett separat team är det en bra indikation på att du kan paketera den som en komponent utanför lösningen.

  • Stabila delar.

    Vissa delar av din kodbas kan vara stabila och ändras sällan. Kontrollera kodlagringsplatsen för att hitta kod med låg ändringsfrekvens.

  • Oberoende kod och komponenter.

    När kod och komponenter är oberoende och inte är relaterade till andra delar av systemet kan du eventuellt isolera dem i separata beroenden.

Du kan använda olika verktyg för att genomsöka och undersöka din kodbas. Dessa sträcker sig från verktyg som söker efter duplicerad kod och ritar lösningsberoende grafer till verktyg som kan beräkna mått för koppling och sammanhållning.

Vilka typer av paket finns det?

Varje programmeringsspråk eller ramverk har egna sätt att skapa paket. Populära paketsystem innehåller dokumentation om hur processen fungerar.

Du kanske redan är bekant med dessa populära paketsystem:

  • NuGet-paket: .NET-bibliotek
  • NPM: paket JavaScript-bibliotek
  • Maven-paket: Java-bibliotek
  • Docker: paketprogramvara i isolerade enheter som kallas containrar

Var finns paketen?

Du kan vara värd för paket i ditt eget nätverk eller använda en värdtjänst. En värdtjänst kallas ofta en paketdatabas eller ett paketregister. Många av dessa tjänster tillhandahåller gratis värdtjänster för projekt med öppen källkod.

Här är några populära värdtjänster för pakettyperna som vi precis beskrev:

  • NuGet-galleri

    NuGet-paket används för .NET-kodartefakter. Dessa artefakter omfattar .NET-sammansättningar och relaterade filer, verktyg och ibland metadata. NuGet definierar hur paket skapas, lagras och används. Ett NuGet-paket är i huvudsak en komprimerad mappstruktur med filer i ZIP-format och har .nupkg-tillägget .

  • NPM

    Ett NPM-paket används för JavaScript. Ett NPM-paket är en fil eller mapp som innehåller JavaScript-filer och en package.json fil som beskriver paketets metadata. För node.js innehåller paketet vanligtvis en eller flera moduler som kan läsas in när paketet har förbrukats.

  • Maven Central-lagringsplats

    Maven används för Java-baserade projekt. Varje paket har en Project Object Model-fil som beskriver projektets metadata och är den grundläggande enheten för att definiera ett paket och arbeta med det.

  • Docker Hub

    Docker-paket kallas avbildningar och innehåller fullständiga, fristående distributioner. Oftast representerar en Docker-avbildning en programvarukomponent som kan hanteras och köras av sig själv, utan några beroenden på andra avbildningar. Docker-avbildningar är skiktade och kan vara beroende av andra avbildningar.

En paketfeed refererar till din paketdatabasserver. Den här servern kan finnas på Internet eller bakom brandväggen i nätverket. Du kan till exempel vara värd för dina egna NuGet-feeds med hjälp av värdprodukter som Azure Artifacts och MyGet. Du kan också ha paketen på en filresurs.

När du är värd för paket bakom en brandvägg kan du ta med feeds till dina egna paket. Du kan också cachelagrat paket som du litar på i nätverket när systemen inte kan ansluta till Internet.

Vilka element utgör en bra strategi för beroendehantering?

En bra strategi för beroendehantering är beroende av följande tre element:

  • Standardisering.

    Standardisering av hur du deklarerar och löser beroenden hjälper din automatiserade lanseringsprocess att förbli repeterbar och förutsägbar.

  • Paketeringsformat och källor.

    Varje beroende ska paketeras med lämpligt format och lagras på en central plats.

  • Versionshantering.

    Du måste hålla reda på de ändringar som sker över tid i beroenden precis som med din egen kod. Det innebär att beroenden ska vara versionshanterade.

Vem kan komma åt paketen?

Många paketfeeds erbjuder obegränsad åtkomst till paketen. Du kan till exempel ladda ned Json.NET från nuget.org, utan att behöva logga in eller autentisera.

För andra paketfeeds krävs autentisering. Du kan autentisera åtkomst till feeds på flera sätt. För vissa typer av feeds krävs till exempel ett användarnamn och ett lösenord. Andra feeds kräver en åtkomsttoken, som vanligtvis är en lång serie tecken som identifierar vem du är och vilka resurser du har åtkomst till. Du kan ange att åtkomsttoken ska upphöra att gälla efter en viss tidsperiod.

Hur hanteras paketversioner?

Versionsschemat beror på vilket paketsystem du använder.

NuGet-paket använder till exempel semantisk versionshantering.

Semantisk versionshantering är ett populärt versionsschema. Så här ser formatet ut:

Major.Minor.Patch[-Suffix]

Här är vad var och en av dessa parametrar innebär:

  • En ny Major-version (huvudversion) innehåller ändringar som inte är bakåtkompatibla. Appar behöver vanligtvis uppdatera hur de använder paketet för att fungera med en ny huvudversion.
  • En ny delversion introducerar nya funktioner, men är bakåtkompatibel med tidigare versioner.
  • En ny korrigering introducerar bakåtkompatibla felkorrigeringar, men inte nya funktioner.
  • Delen -Suffix är valfri och anger att paketet är en förhandsversion. Till exempel kan 1.0.0-beta1 identifiera paketet som den första förhandsversionen av betaversionen för 1.0.0-versionen.

Du refererar till ett paket via versionsnumret.

Här är ett exempel på hur du installerar ett paket med hjälp av PowerShell och ett specifikt versionsnummer:

Install-Package Newtonsoft.Json -Version 13.0.1

Vad händer när paketet ändras?

När du refererar till ett paket från din app fäster eller anger du vanligtvis den version av paketet som du vill använda.

Med många ramverk kan du ange tillåtna intervall med paketversioner som ska installeras. Vissa låter dig också ange jokertecken, som vi kallar en flytande version.

I NuGet är till exempel version ”1.0” den första versionen som är lika med eller större än 1.0. ”[1.0]” anges för endast installation av version 1.0, och inte en nyare version.

Här följer några andra exempel:

Den här notationen: Väljer:
(1.0,) Den första versionen som är större än 1.
[1.0,2.0] Den första versionen som är större än eller lika med 1.0 och mindre än eller lika med 2.0
(1.0,2.0) Den första versionen som är större än 1.0 och mindre än 2.0
[1.0,2.0) Den första versionen som är större än eller lika med 1.0 och mindre än 2.0

När varje underhållare släpper en ny paketversion kan du utvärdera vad som har ändrats och testa din app mot den. När du är redo kan du uppdatera paketets versionsnummer i din konfiguration och skicka ändringen i din bygg-pipeline.

Här är ett exempel på hur du kan inkludera Newtonsoft.Json-paketet i C#-programmets projektfil (.csproj). Det här exemplet anger version 13.0.1 av paketet:

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

Kontrollera dina kunskaper

1.

Vad är ett paket?

2.

Anta att du har skapat ett paket som du vill dela offentligt. Hur gör du det på enklaste sätt?