Ciclo di rilascio della società dispari: vai al controllo del codice sorgente distribuito?

13

Mi dispiace per questo lungo post, ma penso che ne valga la pena.

Ho appena iniziato con un piccolo negozio .NET che funziona in modo un po 'diverso rispetto agli altri posti in cui ho lavorato. A differenza di una qualsiasi delle mie precedenti posizioni, il software qui scritto è destinato a più clienti e non tutti i clienti ottengono l'ultima versione del software allo stesso tempo. In quanto tale, non esiste una "versione di produzione corrente". Quando un cliente ottiene un aggiornamento, ottiene anche tutte le funzionalità aggiunte al software dal loro ultimo aggiornamento, che potrebbe essere molto tempo fa. Il software è altamente configurabile e le funzionalità possono essere attivate e disattivate: i cosiddetti "commutatori di funzionalità". I cicli di rilascio sono molto stretti qui, in effetti non sono in programma: quando una funzionalità è completa, il software viene distribuito al cliente pertinente.

Il team solo l'anno scorso è passato da Visual Source Safe a Team Foundation Server. Il problema è che usano ancora TFS come se fosse VSS e impongono blocchi di Checkout su un singolo ramo di codice. Ogni volta che una correzione di bug viene messa in campo (anche per un singolo cliente), semplicemente costruisce ciò che è in TFS, verifica che il bug sia stato risolto e distribuito al cliente! (Proveniente da uno sfondo di software per dispositivi farmaceutici e medicali è incredibile!). Il risultato è che il codice dev half-cotto viene messo in produzione senza essere nemmeno testato. I bug stanno sempre scivolando nelle build di rilascio, ma spesso un cliente che ha appena ottenuto una build non vedrà questi bug se non usano la funzionalità in cui si trova l'errore. Il regista sa che questo è un problema dato che la società sta iniziando a crescere all'improvviso con alcuni grandi clienti a bordo e altri più piccoli.

Mi è stato chiesto di esaminare le opzioni di controllo del codice sorgente al fine di eliminare la distribuzione di codici bacati o non terminati, ma di non sacrificare la natura un po 'asincrona delle versioni dei team. Ho usato VSS, TFS, SVN e Bazaar nella mia carriera, ma TFS è dove la maggior parte della mia esperienza è stata.

In precedenza la maggior parte dei team con cui ho lavorato utilizza una soluzione a due o tre rami di Dev-Test-Prod, dove per un mese gli sviluppatori lavorano direttamente in Dev e quindi le modifiche vengono unite a Test e poi a Prod, o promosse "al termine". piuttosto che su un ciclo fisso. Sono state utilizzate build automatiche, utilizzando Cruise Control o Team Build. Nel mio precedente lavoro, Bazaar è stato utilizzato in vetta a SVN: gli sviluppatori hanno lavorato nelle proprie filiali di funzionalità, quindi hanno trasferito le loro modifiche a SVN (che era collegato a TeamCity). Questo è stato bello in quanto è stato facile isolare i cambiamenti e condividerli con altre branche della gente.

Con entrambi questi modelli c'era un ramo centrale di sviluppo e di prova (e talvolta di prova) attraverso il quale il codice veniva spinto (e le etichette venivano usate per contrassegnare le build nei prodotti da cui venivano rilasciati i rilasci ... e questi venivano trasformati in rami per correzioni di bug alle versioni e uniti nuovamente a dev). Questo però non si addice perfettamente al modo di lavorare qui: non c'è un ordine in cui verranno rilasciate varie funzionalità, che vengono spinte quando sono complete.

Con questo requisito l'approccio di "integrazione continua" quando lo vedo si rompe. Per ottenere una nuova funzionalità con l'integrazione continua deve essere spinto tramite dev-test-prod e questo catturerà qualsiasi lavoro incompleto in dev.

Sto pensando che per superare questo problema dovremmo andare su un modello ramificato pesantemente con NO rami di sviluppo-test, piuttosto la sorgente dovrebbe esistere come una serie di feature branch che quando il lavoro di sviluppo è completo sono bloccati, testati, risolto, bloccato, testato e quindi rilasciato. Altre ramificazioni di feature possono prendere modifiche da altri rami quando hanno bisogno / vogliono, quindi alla fine tutte le modifiche vengono assorbite da tutti gli altri. Questo si adatta molto a un modello di Bazaar puro da quello che ho sperimentato nel mio ultimo lavoro.

Per quanto flessibile come sembra, sembra strano avere un ramo di sviluppo o un ramo di produzione da qualche parte, e sono preoccupato che i rami non si reinseriscano mai, o piccoli cambiamenti tardivi fatti che non vengono mai trascinati in altri rami e gli sviluppatori si lamentano di unire i disastri ...

Quali sono i pensieri delle persone su questo?

Una seconda domanda finale: sono un po 'confuso circa la definizione esatta del controllo del source distribuito: alcune persone suggeriscono che si tratta semplicemente di non avere un repository centrale come TFS o SVN, alcuni dicono che si tratta di essere disconnessi (SVN è Il 90% è disconnesso e TFS ha una modalità offline perfettamente funzionante) e altri dicono che si tratta di Feature Branching e facilità di fusione tra filiali senza relazione genitore-figlio (TFS ha anche una fusione senza fondamento!). Forse questa è una seconda domanda!

    
posta MrLane 19.03.2012 - 08:00
fonte

5 risposte

5

Che cosa definisce un DVCS?

Il distribuito in DVCS significa che ogni clone di un repository ha tutte le informazioni necessarie per commettere, aggiornare, ramificare, unire o cercare qualsiasi revisione in quel repository, senza mai toccare un server . L'unica cosa che puoi fare offline in svn è in realtà modificare i file - hai bisogno di accesso al server per quasi tutti i comandi svn , incluso fare qualcosa di semplice come grepping un svn log , quindi è in realtà più vicino allo 0% rispetto al 90%!

Qualsiasi repository centrale autorevole che potresti impostare in un flusso di lavoro DVCS è solo un altro clone e l'unica volta che hai bisogno di interagire con esso quando abbassi gli aggiornamenti di altre persone o quando apporti le tue modifiche in modo che le altre persone possano vederle, praticamente tutto il resto può essere fatto offline.

Quale modello di diramazione è appropriato?

Sono stato nella situazione in cui ti trovi adesso. Tali sistemi possono essere un vero dolore, ma devi capire le ragioni pragmatiche che sono diventati così e rendersi conto che sono non oltre la redenzione . Sono stati sviluppati molti strumenti che possono aiutare a gestire questo tipo di complessità .

Prima di tutto, qualunque cosa tu faccia, non mostrare alle persone il modello di branching git riuscito , li confonderà e li spegnerà. Invece, sviluppa il tuo modello che riflette il tuo flusso di lavoro esistente , tuttavia risolve i problemi con il tuo flusso di lavoro esistente .

Alcune risorse che potresti voler considerare includono cose come git sottomoduli che permetteranno a diverse versioni dei clienti di specificare diverse combinazioni di configurazione del cliente, moduli applicativi e librerie. Un'altra opzione potrebbe essere l'uso di un sistema di gestione delle patch per applicare il cliente / code di patch specifiche del prodotto.

Entrambe queste opzioni offriranno maggiore flessibilità, trasparenza e sicurezza rispetto al flusso di lavoro corrente e potrebbero essere più facili da utilizzare rispetto a una strategia di branch only ancora più complessa. Vorrei certamente avere accesso a questi strumenti quando ero nella tua situazione.

Per ulteriori informazioni su queste opzioni, vedere le mie risposte alla strategia per utilizzare il controllo della versione su un sistema modulare , Come utilizzare il repository Subversion all'interno del repository Git e Controllo origine / versione per l'applicazione utilizzata da più società .

In fin dei conti, questo è davvero qualcosa che dovrai sviluppare con il resto della squadra. Se hai la visione di proporre qualcosa che funziona meglio di ciò che hai già, e puoi ottenere il buy-in dei tuoi colleghi sviluppatori, allora avrai un tempo molto più facile.

La cosa più importante è mostrare ai tuoi colleghi in che modo renderti più facile la vita . Una volta che sono convinti, hai molte più possibilità di convincere il management a buttare via il loro investimento in TFS e iniziare a utilizzare un modello più appropriato per i tuoi metodi di lavoro.

    
risposta data 19.03.2012 - 13:18
fonte
5

In primo luogo, DVCS è un'arma rossa per i problemi che hai - lo strumento di controllo della versione in uso non è la radice dei problemi che devono essere risolti. Può darsi che ci siano aspetti delle soluzioni DVCS che sono "migliori" di TFS ma non è ciò che deve essere corretto a questo punto.

Hai identificato che hai bisogno di una struttura di diramazione lavorabile che si adatti alla tua organizzazione - penso che scoprirai che hai ancora un bagagliaio, quando una funzionalità è completa viene riunita nel bagagliaio e chiusa. Ci sono alcune buone idee su come implementare anche le dipendenze comuni.

È inoltre necessario che l'integrazione continui funzioni (nessun motivo per non avere una build automatizzata per ogni singolo ramo attivo per darti la sicurezza di poter creare quel ramo e di superare i test rilevanti). Sono scomodo dove un commit (o almeno una "spinta") non innesca una build per me.

E devi iniziare i test automatici a tutti i livelli, ma soprattutto i test unitari e di integrazione per iniziare a ridurre le possibilità che i nuovi bug sfuggano allo scoperto. Quest'ultima è enorme e qualcosa con cui sto ancora lottando, ma è chiaro che una volta che sai che puoi costruire tutto questo avrà più valore.

È necessario combinare questo con l'assicurarsi che i pacchetti di distribuzione provengano dal server di build e che la distribuzione sia automatizzata il più possibile (dovresti essere in grado di passare da artefatto server a codice in tempo reale con il minimo sforzo e lo stress minimo ).

Hmm, ho presupposto che ci sia un buon sistema di tracciamento del problema ben ordinato ... anche tu hai bisogno di questo e per essere sicuro che sia usato correttamente. Idealmente, vuoi che le tue applicazioni live trasmettano errori a questo sistema (o per il triage) automaticamente.

Infine, non cercare di risolvere tutti i tuoi problemi in una volta: costruire e test mi sembrerebbero i luoghi su cui dovresti concentrarti per primi.

    
risposta data 19.03.2012 - 15:08
fonte
1

La seconda domanda è più facile e più breve, quindi cercherò di iniziare da essa

DVCS è un sistema, in cui nessuna fonte "autorevole" di codice (eccetto "su accordo", se usato) e lo scambio di dati P2P è possibile senza livelli aggiuntivi (definizione personale, non canonica)

Nell'argomento la prima domanda

Temo che l'azienda debba ricostruire il flusso di lavoro e ripensare allo stile per ottenere "codice in qualche modo gestito e prevedibile". Non posso dire di TFS (ad eccezione dell'opinione personale e del sentimento, che sia un sistema debole in Version Control part / mereless basge è male /), ma per qualsiasi VCS nella tua situazione ("Product" è impostato su "Modules" indipendenti, ogni "Cliente" ottiene diversi "Prodotti" - questa supposizione è corretta?) Preferisco lo sviluppo diviso di moduli in rami separati, avere Prodotto come "Supermodulo" (anche ramo?), lì ogni modulo legato alla revisione specifica del modulo- ramo, lo sviluppo del modulo utilizza il paradigma branch-per-task (e il ramo-modulo consiste solo di fusioni).

In questo modo puoi sempre sapere, quale "Collezione" (cioè insieme di moduli e relative revisioni) forma ogni "Prodotto", avere la possibilità di fare CI (per le branche di attività finite e unite ), Unit-testing e Build

    
risposta data 19.03.2012 - 09:58
fonte
1

Domanda principale dell'annuncio: credo che quello di cui stai parlando sia esattamente ciò che crea un modello di branching riuscito (e lo strumento helper git flow per supportarlo) è circa. Avere un ramo principale, che è sempre in stato di spiegamento e fare tutto il lavoro sui rami di funzionalità.

Puoi anche usare il processo usato da git stesso, che è derivato dallo stesso principio di base. Nello sviluppo git-core, tutto il lavoro avviene sui rami delle funzionalità. I rami di funzionalità vengono inviati all'integratore, che esegue uno script per unirli tutti per creare un ramo denominato pu (aggiornamenti proposti). Diverse persone prendono questo ramo e lavorano con esso per testarlo.

Invece di integratore, puoi fare in modo che il server di integrazione continua si unisca all'inizio di una compilazione. In questo modo ogni volta che qualcuno del team spinge le modifiche al repository centrale come ramo di una caratteristica (probabilmente usando alcune convenzioni di denominazione per dire quali rami dovrebbero essere selezionati).

In git il ramo della caratteristica procede a next , master o maint a seconda della versione a cui è destinato il targeting (maint è per il bugfixing release corrente, master per il rilascio in preparazione e successivo per quello successivo che), ma non ne avrai tanti.

Mentre le feature sono in pu ("cooking" nella terminologia di git maintainer), vengono riavvolti e il ramo pu viene scartato e creato di nuovo ogni volta, il che rende più facile la revisione, ma inadatto per basare altri lavorare su. Quando il ramo della funzione viene unito in una delle linee principali, viene chiuso per riavvolgere e ulteriori correzioni vengono eseguite come nuovi commit.

Personalmente raccomanderei git migliore. È un po 'più difficile da imparare inizialmente, perché cresce più organicamente, ma alla fine sembra più flessibile. Ma uno qualsiasi dei tre sistemi distribuiti, git, mercurial e bazaar ti serviranno bene (e puoi spesso persino mescolarli, ad esempio mercurial può tirare e spingere da / verso il repository git e credo che possa farlo anche nel bazar).

Seconda domanda dell'annuncio: mi è stato insegnato che "distribuito", in generale, significa che puoi spostare gli oggetti e mantenere la loro identità. Che è esattamente ciò che fa il controllo della versione distribuita: cloni il repository e contiene gli stessi commit e permette di fare le stesse cose con loro. La facilità di ramificazione e l'operazione disconnessa sono le principali funzionalità a livello utente che seguono il principio dello spostamento delle commit e il layout del grafico diretto che lo consente.

    
risposta data 19.03.2012 - 12:05
fonte
1

Sfortunatamente, non esiste una soluzione nota ai bug nel codice:)

Quindi stai solo cercando di impedire che i check-in non finiti vengano scoperti nella versione principale, e l'unica risposta è un'unione-lavoro-unione per ogni sviluppatore. L'ho fatto in una società precedente usando Clearcase, ha funzionato abbastanza bene (anche se dovevamo avere una dozzina di amministratori di clearcase).

Ora, presumo anche che tu esegua il bug fixing sulla versione del prodotto che ogni cliente ha attualmente ... quindi hai un problema di unione che porta bugfix dalla versione A fino alla versione Z. Non c'è un modo semplice per far fronte a questo, ma si dovrà avere un ramo per ogni versione spedita. Il modo migliore per far fronte a questo è mantenere i rami delle funzionalità solo sulla versione più recente e fare in modo che i clienti eseguano l'aggiornamento per ottenere le nuove funzionalità, allo stesso tempo eseguano la correzione dei bug direttamente sul ramo di rilascio e unificali verso tutte le altre diramazioni di rilascio al termine.

Non troppo bello, ma può funzionare molto bene. Mantieni il codice organizzato e ben separato. È anche facile da capire per gli altri sviluppatori - piccoli bugfix direttamente su "il codice", qualcosa di più di un paio di righe su un ramo dedicato dove possono impiegare tutto il tempo che vogliono per completarlo. (dovrai risolvere i problemi di unione e rassicurarli che è ok se 2 sviluppatori lavorano su 2 funzionalità contemporaneamente !!)

Dopo un po 'è possibile introdurre anche rami di funzionalità sui rami di rilascio, in cui vengono corretti i bug e poi uniti, ma questo è in genere più sforzo del necessario. Se è necessario aggiungere funzionalità alle vecchie versioni, allora è necessario seguire questo approccio - diramazione di un ramo di rilascio, quindi unire nuovamente il codice su quella release e unire la modifica anche alle versioni successive. Ciò renderà la tua squadra di test molto infelice poiché i rilasci saranno pesantemente ritardati a causa della necessità di testare più versioni ripetutamente, e il team di sviluppo sarà infelice in quanto dovranno fare un sacco di fusioni prima di poter iniziare il nuovo codice (nella mia attuale compagnia questo accade, principalmente a causa della quantità di lavoro che abbiamo che deve essere sempre completa al più presto possibile.

DVCS:

fondamentalmente un DVCS è dove ognuno ha la propria copia del server repo. Ha alcuni vantaggi (specialmente nei team distribuiti con una comunicazione limitata), ma ha anche alcuni svantaggi, quindi controllali prima di passare a un DVCS. Se sei un negozio di Windows, probabilmente troverai che Mercurial è il miglior DVC per te.

    
risposta data 19.03.2012 - 19:30
fonte

Leggi altre domande sui tag