Questo articolo è un articolo speculare di traduzione automatica, clicca qui per saltare all'articolo originale.

Vista: 1081|Risposta: 1

Una breve introduzione a Reproducible Build

[Copiato link]
Pubblicato il 30-04-2025 10:09:27 | | | |
Cos'è una build ripetibile?

Deterministic Build o Reproducible Build sono leggermente diversi, ma possono essere intese come la stessa cosa da questo articolo.

Le build riproducibili si riferiscono alEsecuzioni multiple del processo di build con lo stesso input e ambiente di build possono produrre esattamente gli stessi risultati。 Questa tecnologia è importante per lo sviluppo, la distribuzione e la validazione della sicurezza.

Una build è riproducibile se fornisce esattamente lo stesso output indipendentemente da quando e dove viene eseguita. Non importa su quale computer stai usando, a che ora della giornata o quali servizi esterni accedi tramite la rete, le build riproducibili producono lo stesso output byte per byte. Questo è ottimo sia per lo sviluppo (perché le build riproducibili sono facili da condividere tra diversi dispositivi di sviluppo) sia per la produzione (perché è facile assicurarsi che i risultati delle build riproducibili non siano stati manomessi – basta rieseguire la build sulla tua macchina e controllare che i risultati siano coerenti!). sono molto utili.



I tre pilastri delle costruzioni ripetibili

Pilastro 1: Build ripetibili

La ripetibilità della build si riferisce a ciò che accade alla macchina di costruzione stessa. Supponendo che i nostri input di build siano disponibili e che nulla cambi nel mondo intorno a noi, la nostra build produce lo stesso output quando viene ripetuta?

Piano di installazione deterministico

Il primo, più semplice e più ovvio requisito in una build ripetibile è un piano di installazione di dipendenza deterministica.

Nella maggior parte delle lingue, è semplice come controllare un file bloccato. Gli strumenti di build moderni spesso permettono ai progetti di esprimere requisiti diretti di dipendenza come vincoli, e poi di risolvere tali vincoli per generare un piano di installazione (un elenco di nomi di dipendenze e coppie di versioni da installare). Molti di questi strumenti generano anche file di blocco per piani di installazione serializzati. Gli sviluppatori possono inviare questi file di blocco al controllo versioni affinché le future build utilizzino gli stessi nomi e versioni delle dipendenze.

Nota che abbiamo bisogno anche di deterministico nella build della dipendenza stessa (non solo nella selezione delle versioni), e un piano di installazione deterministico non ci permette di ottenere questo risultato!

Costruzione deterministica

Una volta che sappiamo cosa costruire, la nostra build stessa (incluso il nostro codice e la costruzione del codice di dipendenza) deve essere in realtà deterministica.

Questo potrebbe non essere un problema per i progetti senza un passaggio di compilazione! Ad esempio, un progetto Node con tutte le dipendenze è puro JavaScript, e non è necessario alcun lavoro aggiuntivo per raggiungere la deterministicità efficace.

Per i progetti che includono fasi di compilazione o traduzione (compilazione da sorgente a fonte), garantire il determinismo è di gran lunga la parte più difficile nella costruzione di una build riproducibile. Il processo di compilazione può introdurre implicitamente il non-determinismo in diversi modi, tra cui:

  • Gli script di compilazione del programma Turing-complete possono modificare l'output compilato a piacimento.
  • Script post-installazione che si basano su consultazioni eseguibili nel file system o chiamate di rete.
  • C binding a un package installato dal sistema, dove i binding su sistemi diversi con header differenti possono produrre output differenti.
  • Passaggi per costruire un file che si legge al di fuori del controllo versione.
  • Compila i passaggi per generare timestamp usando il tempo di sistema.
  • Passaggi per costruire dipendenze che non sono espresse nel piano di installazione del download di rete (ad esempio, scaricare una dipendenza NPM da GitHub per una build binaria cache che è C-bound).
  • Cambia il comportamento in base alla variabile di ambiente attualmente impostata, ma non inviare una build con la configurazione della variabile di ambiente.


Non tutti questi comportamenti introducono necessariamente incertezza se configurati correttamente, ma configurare correttamente il processo di build può essere complesso e difficile. Ad esempio, puoi leggere questo post sul blog sull'incertezza nelle build Chromium. Molti di questi problemi possono essere mitigati controllando l'ambiente costruttivo locale, di cui parleremo nella sezione successiva.

Pilastro 2: Ambiente immutabile

Anche con build ripetibili, dobbiamo assicurarci che gli input di build non cambino. Spesso, questo significa che vogliamo assicurarci di costruire su un'istantanea immutabile dell'ambiente circostante.

Ambiente locale immutabile

Come abbiamo discusso sopra, una fonte comune di incertezza nella build è affidarsi a "dipendenze" che non vengono catturate dallo strumento di build. Le librerie di sistema C-bound sono gli esempi più comuni, ma altri fattori ambientali locali come le impostazioni delle variabili ambientali e i file al di fuori dell'ambito del controllo versione possono influenzare la compilazione.

Un modo semplice per mitigare questo problema è eseguire la build in un contenitore noto e immutabile. Ad esempio, un runtime container come Docker aiuta a garantire che tutti usino le stesse dipendenze di sistema, le stesse variabili di ambiente e funzionino sullo stesso file system. Inoltre, è facile verificare che il contenuto del contenitore corrisponda a un contenitore di costruzione nota e, se necessario, il contenitore può essere facilmente rimosso completamente dall'immagine nota e ricreato.

Nota che siamo molto chiari riguardo ai contenitori noti o alle immagini dei contenitori noti. Non basta semplicemente inviare un Dockerfile! Perché? Perché il Dockerfile stesso non descrive un processo di compilazione completamente riproducibile per le immagini Docker, dato che non girano in un ambiente globale immutabile.

Ambiente globale immutabile

I sistemi di build spesso interagiscono con servizi esterni per completare compiti come la risoluzione delle versioni e il download delle dipendenze. Ma i servizi esterni cambiano spesso.

Eseguire oggi appun install nodejs ti darà risultati diversi rispetto all'anno scorso, e probabilmente anche il prossimo anno otterrai risultati diversi. Ecco perché Dockerfile stessi non può descrivere le build riproducibili: eseguire lo stesso Dockerfile in momenti diversi produrrà output build differenti!

La semplice mitigazione qui è configurare la build ogni volta che è possibile, specificando una versione esatta (idealmente, anche un hash di contenuto esatto) in modo che le build future usino la stessa versione della build attuale. Ma anche i servizi esterni possono cambiare il loro comportamento inaspettatamente: una build veramente pessimista e riproducibile gestisce un'immagine interna con quante più risorse di rete possibile.

Pilastro 3: Disponibilità delle risorse

Diciamo che la nostra build sia ripetibile e che il mondo sotto i nostri piedi non cambi. Tutto ciò di cui abbiamo bisogno ora è l'accesso agli input di build. Sembra semplice, vero? Bene......

Il registro a volte fallisce

La maggior parte degli sviluppatori di Node ha sperimentato almeno un'interruzione NPM, durante la quale la pipeline di build senza cache o mirroring dei pacchetti NPM viene interrotta. Molti sviluppatori di Node hanno anche subito rimozioni di left-pad e faker, che hanno gravemente danneggiato l'ecosistema NPM e hanno di fatto rappresentato un'interruzione.

L'unico modo affidabile per mitigare tali interruzioni di build è eseguire il proprio mirror del registro dei pacchetti. Quando i servizi esterni non sono disponibili, l'immagine può rimanere online; Quando il registro ufficiale elimina il vecchio pacchetto, lo specchio può continuare a fornire servizi. Lo stesso principio vale per altri servizi remoti: a meno che tu non gestisca la tua immagine, la disponibilità di una pipeline di build è comparabile solo alla disponibilità dei suoi servizi.

Scegliere di gestire un'immagine di servizio è sempre un compromesso delicato. Da un lato, registri come NPM hanno team di ingegneria e operazioni dedicati che hanno l'esperienza per mantenere questi sistemi online. D'altra parte, è molto più facile eseguire un'immagine piccola per un piccolo insieme di dipendenze piuttosto che eseguire tutte le immagini NPM. Dovresti prendere decisioni speculari basate sulle specifiche di ogni servizio, tenendo conto dell'affidabilità dei servizi esterni storici e delle esigenze di disponibilità di costruzione e personale del tuo team.

I fornitori garantiscono la massima disponibilità

Un modo semplice per garantire la massima disponibilità delle dipendenze del tuo progetto è aggiungerle al tuo fornitore. La maggior parte dei package manager supporta una qualche forma di "vendoring", il che significa che invece di affidarci ai download da servizi esterni, memorizziamo il codice sorgente delle dipendenze nel controllo versioni, coesistendo con il nostro codice sorgente. Ad esempio, in Node, questo potrebbe sembrare un commit node_modules al controllo del versione.

Anche se questa soluzione non è perfetta (a seconda di come è configurato il tuo fornitore e il progetto, il che può mettere molta pressione sul controllo versioni), spesso è la soluzione più semplice e semplice per la massima disponibilità.

Riferimento:

Il login del link ipertestuale è visibile.
Il login del link ipertestuale è visibile.




Precedente:.NET/C# Usa UnsafeAccessor per modificare il contenuto del campo di sola lettura
Prossimo:Controlli personalizzati di forma ControlValueAccessor Angular 18 Series (32)
 Padrone di casa| Pubblicato il 30-04-2025 alle 10:10:23 |
Informazioni sull'uso di build ripetibili quando si costruiscono pacchetti NuGet in C#:

Il login del link ipertestuale è visibile.
Il login del link ipertestuale è visibile.
Disconoscimento:
Tutto il software, i materiali di programmazione o gli articoli pubblicati dalla Code Farmer Network sono destinati esclusivamente all'apprendimento e alla ricerca; I contenuti sopra elencati non devono essere utilizzati per scopi commerciali o illegali, altrimenti gli utenti dovranno sostenere tutte le conseguenze. Le informazioni su questo sito provengono da Internet, e le controversie sul copyright non hanno nulla a che fare con questo sito. Devi eliminare completamente i contenuti sopra elencati dal tuo computer entro 24 ore dal download. Se ti piace il programma, ti preghiamo di supportare software autentico, acquistare la registrazione e ottenere servizi autentici migliori. In caso di violazione, vi preghiamo di contattarci via email.

Mail To:help@itsvse.com