Denna artikel är en spegelartikel om maskinöversättning, klicka här för att hoppa till originalartikeln.

Utsikt: 1081|Svar: 1

En kort introduktion till Reproducerbar Build

[Kopiera länk]
Publicerad den 2025-4-30 10:09:27 | | | |
Vad är en upprepbar build?

Deterministisk build eller reproducerbar build är något annorlunda, men de kan förstås som samma sak som i denna artikel.

Reproducerbara byggen avserFlera körningar av byggprocessen med samma indata och byggmiljö kan ge exakt samma resultat。 Denna teknik är viktig för mjukvaruutveckling, distribution och säkerhetskontroll.

En build är reproducerbar om den ger exakt samma utgång oavsett när och var den körs. Oavsett vilken dator du kör på, vilken tid på dygnet och vilka externa tjänster du använder via nätverket, producerar reproducerbara byggen samma byte-för-byte utdata. Detta är utmärkt både för utveckling (eftersom reproducerbara byggen är enkla att dela mellan olika utvecklarenheter) och produktion (eftersom det är enkelt att säkerställa att resultaten av reproducerbara byggen inte har manipulerats – kör bara om bygget på din egen maskin och kontrollera att resultaten är konsekventa!). är mycket användbara.



De tre pelarna i upprepningsbara byggen

Pelare 1: Upprepningsbara byggen

Byggupprepbarhet syftar på vad som händer med byggmaskinen själv. Om vi antar att våra byggindata är tillgängliga och inget förändras i världen omkring oss, ger vår byggnation samma resultat när den upprepas?

Deterministisk installationsplan

Det första, enklaste och mest uppenbara kravet i en repeterbar konstruktion är en deterministisk installationsplan för beroende.

I de flesta språk är det så enkelt som att kolla in en låst fil. Moderna byggverktyg tillåter ofta projekt att uttrycka direkta beroendekrav som begränsningar, och sedan lösa dessa begränsningar för att generera en installationsplan (en lista med beroendenamn och versionspar att installera). Många av dessa verktyg genererar också låsfiler för serialiserade installationsplaner. Utvecklare kan skicka in dessa låsfiler till versionshantering så att framtida versioner använder samma beroendenamn och versioner.

Observera att vi också behöver deterministisk i själva beroendebygget (inte bara versionsval), och en deterministisk installationsplan tillåter oss inte att uppnå detta!

Deterministisk konstruktion

När vi vet vad vi ska bygga måste vår egen build (inklusive vår egen kod och beroendekoden) faktiskt vara deterministisk.

Detta kanske inte är ett problem för projekt utan ett kompileringssteg! Till exempel är ett Node-projekt med alla beroenden ren JavaScript, och inget extra arbete krävs för att uppnå effektiv deterministicitet.

För projekt som inkluderar kompilerings- eller översättningssteg (källkod-till-källa-kompilering) är det klart svåraste att säkerställa determinism i att bygga en reproducerbar build. Kompileringsprocessen kan implicit introducera icke-determinism på flera sätt, inklusive:

  • Turing-kompletta programbyggar-skript kan ändra den kompilerade utdatan efter behag.
  • Efterinstallationsskript som bygger på exekverbara filsystemuppslagningar eller nätverksanrop.
  • C-bindning till ett systeminstallerat paket där bindningar på olika system med olika headers kan ge olika utgångar.
  • Steg för att bygga en fil som läses utanför versionskontrollen.
  • Bygg steg för att generera tidsstämplar med hjälp av systemtid.
  • Steg för att bygga beroenden som inte uttrycks i nätverksnedladdningsinstallationsplanen (till exempel ladda ner ett NPM-beroende från GitHub för en cachad binär build som är C-bunden).
  • Ändra beteendet baserat på den aktuella miljövariabeln, men skicka inte in en build med miljövariabelns konfiguration.


Alla dessa beteenden skapar inte nödvändigtvis osäkerhet när de ställs in korrekt, men att korrekt konfigurera byggprocessen kan vara komplext och svårt. Till exempel kan du läsa det här blogginlägget om osäkerhet i Chromium-byggen. Många av dessa problem kan mildras genom att kontrollera den lokala byggmiljön, vilket vi kommer att diskutera i nästa avsnitt.

Pelare 2: Oföränderlig miljö

Även med upprepbara byggen måste vi se till att bygginmatningarna inte ändras. Ofta innebär detta att vi vill se till att vi bygger på en oföränderlig ögonblicksbild av vår omgivning.

Oföränderlig lokal miljö

Som vi diskuterade ovan är en vanlig källa till byggosäkerhet att förlita sig på "beroenden" som inte fångas upp av byggverktyget. C-bundna systembibliotek är de vanligaste exemplen, men andra lokala miljöfaktorer som miljövariableinställningar och filer utanför versionshanteringens område kan också påverka bygget.

Ett enkelt sätt att mildra detta problem är att köra bygget i en känd, oföränderlig container. Till exempel hjälper en containerruntime som Docker till att säkerställa att alla använder samma systemberoenden, samma miljövariabler och körs på samma filsystem. Dessutom är det enkelt att verifiera att innehållet i containern matchar en känd bra byggcontainer, och vid behov kan containern enkelt tas bort helt från den kända goda avbilden och återskapas.

Observera att vi är mycket tydliga med kända behållare eller kända containerbilder. Det räcker inte att bara skicka in en Dockerfile! Varför? Eftersom Dockerfile i sig inte beskriver en fullt reproducerbar byggprocess för Docker-bilder, eftersom de inte körs i en oföränderlig global miljö.

Oföränderlig global miljö

Byggsystem interagerar ofta med externa tjänster för att slutföra uppgifter som versionsupplösning och nedladdningar av beroenden. Men externa tjänster ändras ofta.

Att köra apt install nodejs idag ger andra resultat än förra året, och troligen kommer nästa år också att ge andra resultat. Det är därför Dockerfiles själva inte kan beskriva reproducerbara byggen – att köra samma Dockerfile vid olika tidpunkter ger olika byggresultat!

Den enkla åtgärden här är att konfigurera bygget när det är möjligt, och specificera en exakt version (helst även en exakt innehållshash) så att framtida byggen använder samma version som den nuvarande versionen. Men externa tjänster kan också ändra sitt beteende oväntat – en verkligt pessimistisk reproducerbar build kör en intern image med så många av sina nätverksresurser som möjligt.

Pelare 3: Resurstillgänglighet

Låt oss säga att vår build är upprepbar och världen under våra fötter inte förändras. Allt vi behöver nu är tillgång till byggindata. Det verkar enkelt, eller hur? Brunn......

Registret misslyckas ibland

De flesta Node-utvecklare har upplevt minst ett NPM-avbrott, under vilket byggpipelinen utan caching eller spegling av NPM-paket störs. Många Node-utvecklare har också upplevt borttagningar av vänster platta och falskare, vilket har skadat NPM-ekosystemet allvarligt och i praktiken lett till ett avbrott.

Det enda pålitliga sättet att mildra sådana byggavbrott är att köra din egen paketregisterspegel. När externa tjänster inte är tillgängliga kan bilden förbli online; När det officiella registret raderar det gamla paketet kan spegeln fortsätta att tillhandahålla tjänster. Samma princip gäller för andra fjärrtjänster: om du inte kör din egen image är tillgängligheten för en byggpipeline endast jämförbar med tillgängligheten för dess tjänster.

Att välja att köra en servicebild är alltid en känslig avvägning. Å ena sidan har register som NPM dedikerade ingenjörs- och driftteam som har expertisen att hålla dessa system online. Å andra sidan är det mycket enklare att köra en liten bild för en liten uppsättning beroenden än att köra alla NPM-bilder. Du bör fatta spegelbeslut baserat på varje tjänsts specifika egenskaper, med hänsyn till tillförlitligheten hos historiska externa tjänster och ditt teams tillgänglighet och bemanningsbehov.

Leverantörer säkerställer maximal tillgänglighet

Ett enkelt sätt att säkerställa maximal tillgänglighet av ditt projekts beroenden är att lägga till dem hos din leverantör. De flesta pakethanterare stödjer någon form av "vendoring", vilket innebär att vi istället för att förlita oss på nedladdningar från externa tjänster lagrar beroendets källkod i versionskontroll, samexisterande med vår källkod. Till exempel kan detta i Node se ut som att committa node_modules till versionskontroll.

Även om denna lösning inte är perfekt (beroende på hur din leverantör och ditt projekt är uppbyggda, vilket kan belasta din versionskontroll mycket), är det ofta den enklaste och enklaste lösningen för maximal tillgänglighet.

Hänvisning:

Inloggningen med hyperlänken är synlig.
Inloggningen med hyperlänken är synlig.




Föregående:.NET/C# Använd UnsafeAccessor för att ändra innehållet i skrivskyddade fält
Nästa:Angular 18 Series (32) ControlValueAccessor anpassade formulärkontroller
 Hyresvärd| Publicerad den 2025-4-30 10:10:23 |
Om att använda upprepningsbara byggen när man bygger NuGet-paket i C#:

Inloggningen med hyperlänken är synlig.
Inloggningen med hyperlänken är synlig.
Friskrivning:
All programvara, programmeringsmaterial eller artiklar som publiceras av Code Farmer Network är endast för lärande- och forskningsändamål; Ovanstående innehåll får inte användas för kommersiella eller olagliga ändamål, annars kommer användarna att bära alla konsekvenser. Informationen på denna sida kommer från internet, och upphovsrättstvister har inget med denna sida att göra. Du måste helt radera ovanstående innehåll från din dator inom 24 timmar efter nedladdning. Om du gillar programmet, vänligen stöd äkta programvara, köp registrering och få bättre äkta tjänster. Om det finns något intrång, vänligen kontakta oss via e-post.

Mail To:help@itsvse.com