Che cos'è un processo git efficace per la gestione della nostra libreria di codici centrale?

5

Sfondo rapido: siamo una piccola agenzia web (3-6 sviluppatori in qualsiasi momento) che sviluppa siti Symfony 1.4 di piccole e medie dimensioni. Abbiamo usato git per un anno, ma in precedenza abbiamo usato Subversion.

Negli ultimi 6 mesi abbiamo impiegato molto tempo per lo sviluppo in un plugin Symfony centrale che alimenta il nostro CMS personalizzato. Questo plugin include una serie di funzioni, helper, classi base ecc. Che utilizziamo per creare funzionalità personalizzate. Questo plugin è memorizzato in git, ma si ramifica selvaggiamente in quanto il plug-in viene utilizzato in vari prodotti e viene continuamente spostato da / premuto. Il repository viene solitamente utilizzato come sottomodulo all'interno di un grande progetto.

I problemi che stiamo iniziando a vedere ora sono un gran numero di conflitti di unione e modifiche incompatibili all'indietro introdotte nel repository dagli sviluppatori che aggiungono funzionalità personalizzate nel contesto del loro progetto.

Ho letto l'eccellente modello di branching git di Vincent Driessen e l'ho usato con successo per i progetti in passato, ma non sembra applicarsi bene alla nostra situazione particolare; abbiamo un certo numero di progetti che utilizzano contemporaneamente lo stesso plug-in core mentre sviluppano nuove funzionalità per questo.

Ciò di cui abbiamo bisogno è una strategia che fornisca le seguenti informazioni:

  • Una metodologia per lo sviluppo di funzionalità importanti all'interno del repository di codice.
  • Un modo per migrare tali funzionalità in altri progetti.
  • Un modo di versionare il repository principale e di tracciare la versione di ogni progetto principale.
  • Un piano per la migrazione delle correzioni dei bug a versioni precedenti.
  • Una cronologia più chiara che è più facile da vedere da dove provengono i cambiamenti.

Qualsiasi suggerimento o discussione sarebbe molto apprezzato.

    
posta Mathew Byrne 09.07.2012 - 08:32
fonte

6 risposte

5

Sento il tuo dolore mentre mi occupo di questo genere di cose ogni giorno. La mia situazione è dover mantenere più versioni cliente di un progetto open source, ognuna con una diversa selezione di plug-in, hack core, ecc. Non è divertente quando ne hai 50.

Non ho ancora trovato una soluzione ideale (perfettamente pulita), ma le mie modifiche a GitFlow sono:

  • Crea una filiale separata (diversa dal master) per il codice di produzione di ciascun cliente. Utilizza il master per la versione definitiva di tutte le funzionalità e unisci solo ciò che il cliente desidera nei propri.
  • Mantieni gli sviluppi (o plugin aggiuntivi, ecc.) su hotfix e feature branch strettamente definiti e lasciateli al loro posto, anche una volta uniti, in modo da poterli unire in altri rami del cliente, se necessario. Ciò rende anche facile tenere traccia di chi ha le caratteristiche sgranocchiando i log.
  • Quando si sviluppano nuove funzionalità, derivare dal ultimo antenato comune di tutti i clienti, se possibile. Ciò significa che sarai in grado di fonderti in uno sviluppo e poi di padroneggiare, ma anche di unirmi ai rami di produzione dei clienti senza (in teoria) causare conflitti.
  • Avere un repository principale solo per il lavoro di sviluppo, che sembra GitFlow. Avere un altro che ha il tuo repo di sviluppo come un telecomando, che viene utilizzato per archiviare i rami dei clienti in modo che il tuo repository di risorse abbia una cronologia pulita (er).
  • Se davvero non riesci a risolvere facilmente un conflitto e devi selezionare un intero ramo alla volta, usa rebase --onto come questo . Assicurati solo che sia chiaro nei messaggi di commit da cui proviene la camma e perché non è stato unito normalmente.

L'utilizzo di git ha avuto un ulteriore vantaggio in quanto ora possiamo eseguire un cron job su tutti i server di produzione che controllano i file non gestiti nei repository git. Ora sappiamo se il personale di supporto è stato deriso con il codice di produzione sui server senza dirlo a nessuno, il che ha impedito un sacco di grattacapi:)

Spero che ti aiuti.

    
risposta data 09.07.2012 - 10:50
fonte
5

L'errore principale in questo flusso sta creando filiali dei clienti !!! Gli unici rami possibili sono le nuove funzionalità della libreria, non quelle dei clienti .

È una libreria comune, quindi dovrebbe fornire API che POTREBBERO essere sostituite dalle classi dei clienti (dalle richieste di funzionalità). Ma queste classi personalizzate dovrebbero essere nel repository del progetto principale del client!

I tuoi sviluppatori scrivono codice troppo accoppiato. Leggi articoli sulla modularità del codice, le iniezioni, le interfacce, ecc. Questo ti ridurrà molto il dolore!

La seconda cosa è il flusso corretto per le biblioteche. Dovresti sviluppare librerie versionate (ad esempio 0.5, 0.7, 1.0, 1.2). Il problema con la libreria è l'utilizzo di diverse versioni per diversi progetti. Git flow non supporta questo in modo corretto (solo l'ultima release e lo sviluppo corrente). Sono solo alla ricerca di uno strumento di supporto adeguato per questo tipo di flusso.

Riassumendo: il dolore principale risiede nel codice della libreria scadente. Gli sviluppatori devono scrivere codice con comportamento predefinito, senza comportamenti da parte dei client e con API che consente di ignorare quello predefinito.

    
risposta data 04.11.2013 - 21:42
fonte
4

Il codice condiviso è più costoso da sviluppare e mantenere. Deve funzionare in più scenari; deve essere retrocompatibile; e dovrebbe avere casi di test per garantire che le modifiche non interrompano i client esistenti.

Come regola generale, la funzionalità condivisa vale la pena solo se viene utilizzata in tre o più posizioni.

developers adding custom functionality in the context of their own project.

Una modifica personalizzata per uno o due progetti non deve essere inserita nel codice condiviso. Se lo permetti, il codice condiviso aumenterà rapidamente in complessità, fino a un punto in cui diventa impossibile da mantenere. Nessun flusso di lavoro può essere d'aiuto.

    
risposta data 09.07.2012 - 10:20
fonte
1

Uso le filiali per modifiche del codice di breve durata, in genere da giorni a una settimana o due.

Le filiali dovrebbero essere utilizzate esclusivamente per la gestione di nuove funzionalità / correzioni / aggiornamenti / faccende domestiche, dovrebbero non essere un meccanismo per gestire le funzionalità del prodotto stesse.

Un'opzione è più master per ogni prodotto ma non risponde alla necessità di mantenere il codice comune in sincrono.

Sembra che tu abbia bisogno di sviluppare software / API / configurazioni che ti consentano di configurare queste cose tramite gli switch senza modificare il codice.

I principali rami "longevi" che mi aspetto di vedere sono versioni per differenze relative alle non applicazioni, come le versioni di ruby e / o rails.

    
risposta data 05.11.2013 - 13:56
fonte
1

Concorda con Matt Gibson sulla sua risposta.

Abbiamo la stessa situazione nella nostra azienda e la gestione di più versioni dello stesso repository a più clienti è avvenuta in passato e si dimostra inefficace. La soluzione migliore che abbiamo trovato è stata trasformare la nostra soluzione in un prodotto con la possibilità di abilitare / disabilitare le funzionalità in base alla configurazione (solo i programmatori possono farlo, non il cliente). Ciò si è dimostrato valido per i seguenti motivi:

  • Più facile mantenere il codice, dal momento che esiste un solo repository.

  • I clienti con un alto tasso di aggiornamenti (settimanalmente) ottengono correzioni di bug e piccole funzionalità "gratuite", rendendole più felici. Questo è anche importante per mantenere il codice aggiornato con i framework e CMS che utilizziamo, oltre a garantire correzioni di sicurezza.

  • I clienti con bassa frequenza di aggiornamenti o senza contratto di manutenzione hanno un ramo personalizzato con un'istantanea di una versione precedente e non aggiornata, che consente di correggere solo bug critici (e li aggiustiamo anche su master, quindi non c'è niente unico su questi rami più vecchi). Questo è un approccio che evitiamo, ma dal momento che un cliente specifico non vuole pagare per gli aggiornamenti, questo è il modo in cui lo gestiamo.

  • Le nuove funzionalità sono disponibili per i clienti con una frequenza ragionevole, consentendo al nostro team commerciale di proporle. Molto spesso questo funziona, il che significa che possiamo vendere funzionalità che sono già funzionali, quindi non devono aspettare il loro sviluppo e il costo è ridotto, dal momento che è una funzionalità condivisa.

Quindi, penso che l'opzione migliore sia ripensare a quello che hai. Non si tratta di filiali, ma del prodotto che la tua azienda ha.

    
risposta data 09.10.2017 - 15:18
fonte
0

Sembra più un problema di gestione delle dipendenze piuttosto che un problema di versione.

Che ne dici di usare qualcosa come compositore ? Definisci quali dipendenze ciascun progetto utilizza e quali versioni (es: 1.2.x) di quei progetti sono accettabili. Quando aggiorni i tuoi componenti condivisi, i tuoi progetti dipendenti non si aggiorneranno automaticamente. Devi dire esplicitamente al compositore di aggiornare le dipendenze per un determinato progetto.

Quando aggiorni le dipendenze di un progetto, puoi assicurarti che tutto funzioni ancora prima di commettere l'aggiornamento delle dipendenze. Questo ti dà la possibilità di provare le cose in sicurezza.

Ci sono molte risorse nei documenti Composer che dovrebbero indirizzarti nella giusta direzione.

    
risposta data 20.07.2012 - 21:43
fonte

Leggi altre domande sui tag