2013-07-31 7 views
11

Ok, ecco lo scenario: un team di sviluppatori vuole assicurarsi che tutto il nuovo codice corrisponda agli standard di codifica definiti e che tutti i test unitari passino prima che un commit venga accettato. Ecco il trucco, tutti i test devono essere eseguiti su una macchina di test dedicata e non abbiamo accesso a modificare il server Git, quindi questo deve essere fatto utilizzando un hook di commit locale su ogni macchina di sviluppo.Applica standard di codice in git prima che venga accettato il commit

Mentre le specifiche sono piuttosto rigide (non stiamo passando a Windows o Subversion, ad esempio) questo è un problema del mondo reale, quindi c'è una certa flessibilità se si dispone di una soluzione che si adatta quasi.

  • Stiamo utilizzando Git e * nix.
  • Il codice aggiornato deve essere inviato a un altro server per eseguire la suite di test.
  • È necessario fornire un elenco di file modificati per garantire che corrispondano allo standard di codifica.
  • È un codebase piuttosto grande, quindi dovremmo inviare la più piccola quantità di informazioni necessarie per garantire copie identiche del codice base.
  • Se i test falliscono, è necessario visualizzare un messaggio con l'errore e il commit deve essere bloccato.
  • Supponiamo che ci fidiamo del nostro team di sviluppo e della sua approvazione per consentire l'esclusione dei test con l'opzione --no-verify.

La domanda: Qual è il modo migliore per ottenere il server di prova per la sincronizzazione con l'ambiente locale per eseguire i test? Una sorta di hash-to-hash matching con una patch git per il nuovo commit? Salta Git del tutto e fai un rsync? Qualcos'altro?

Aggiornamento 8/7/13: Mi sono sparato ai piedi menzionando anche il repository remoto. Il punto non è quello di impedire che il codice venga trasferito al repository condiviso/remoto, per impedire che il commit locale si verifichi. Indipendentemente dal fatto che questa sia considerata una buona pratica, in realtà non è il punto in questo caso, in quanto ciò è specifico per un piccolo team di sviluppatori che desiderano tutti questa funzionalità esatta. La domanda riguarda il modo migliore per raggiungere l'obiettivo.

+0

Non è questo essenzialmente per le richieste pull? (È possibile che tu non stia utilizzando GitHub in questo progetto ma puoi quasi certamente fare qualcosa di simile.) – Ajedi32

+0

Le richieste di pull sono per la revisione del codice, sì, ma l'idea qui è che il codice non dovrebbe nemmeno essere impegnato sul repository a meno che non passi una prima revisione automatizzata. –

+3

Molti progetti Github utilizzano anche un server di integrazione continua come Travis per eseguire test sul codice nelle richieste pull e riportare i risultati, quindi non solo per le revisioni del codice. Inoltre, il codice nelle richieste pull non è tecnicamente nel repository finché la richiesta pull non viene unita. Ecco perché si chiama richiesta ['pull'] (https://www.kernel.org/pub/software/scm/git/docs/git-pull.html). – Ajedi32

risposta

1

Aggiungere un comando git personalizzato che:

  1. temporaneamente fa il commit
  2. Spinge al server remoto
  3. esegue i test (utilizzando un server CI, post-receive gancio o ssh)
  4. Annulla il commit se i test falliscono

Creare un eseguibile denominato git-test-n-commit e posizionarlo nel percorso:

#!/bin/bash 
echo "Committing results..." 
git commit "[email protected]" 
echo "Pushing to remote testing server..." 
git push remote-server-git-url remote-branch -f 
echo "Running tests" 
ssh remote-server 'cd my_repo; run-my-tests' || 
    (echo "Tests failed, undoing commit" && git reset HEAD^) 

Poi invece di chiamare git commit ARGS, gli sviluppatori possono chiamare git test-n-commit ARGS. Se i test superano il codice rimarranno impegnati. Se i test falliscono, sarà come se non fosse mai stato eseguito.

+0

Bella soluzione! Grazie. –

12

Gli hook di commit locali non sono assolutamente ciò che si desidera qui.

Il tuo requisito che "non abbiamo accesso per modificare il server git così questo deve essere fatto usando un hook di commit locale su ogni macchina di sviluppo" è completamente falso. Puoi sempre impostare un altro repository che è il tuo 'test remoto' su cui hai il pieno controllo (che poi si sincronizzerà con il server git su cui non hai alcun controllo).

Una volta impostato questo telecomando di prova, è possibile aggiungere ganci per eseguire i test su qualsiasi push. Lo sforzo di digitare per ottenere risultati di test è piuttosto ridotto.

Continuous integration with Git

controllare anche Jenkins, gitlab, ecc ...


Aggiornamento dopo 8/7/13:

Così si vuole veramente fare un po 'di test' sul un server remoto per prevenire i commit. Se si desidera impedire in base al contenuto del commit stesso, utilizzare l'hook pre-commit.See this question for how to get a list of changed files. Dopo aver modificato i file, è possibile caricarli su un server remoto utilizzando scp o rsync ed eseguire un comando di prova con ssh.

Se avete bisogno di controllare il messaggio di commit utilizzare il gancio commit-msg.

Ecco un buon tutorial su ganci: http://git-scm.com/book/en/Customizing-Git-Git-Hooks

Si menziona anche alcuni motivi per cui potrebbe essere una cattiva idea.

Sono spesso utilizzati per applicare determinate politiche, sebbene sia importante notare che questi script non vengono trasferiti durante un clone. È possibile imporre criteri sul lato server per rifiutare push di commit non conformi ad alcuni criteri, ma spetta interamente allo sviluppatore utilizzare questi script sul lato client. Quindi, questi sono script per aiutare gli sviluppatori, e devono essere configurati e mantenuti da loro, sebbene possano essere sovrascritti o modificati da loro in qualsiasi momento.

11

Risposta breve:

Non


Risposta lunga:

Non essendo in grado di fare un commit a causa di alcuni strani hook locali sembra strano per me: bisogna separare fare un commit (cioè salvare le modifiche) dalla pubblicazione di questo commit.

Mentre è in ottima posizione ragionevole avere un gancio pre-receive sul server git si parla che fa rispettare le regole, sarebbe drammatico per i pronti contro termine dei vostri sviluppatori: ogni volta che vogliono salvare il loro lavoro, provare qualcosa di nuovo o qualsiasi altra cosa , prima dovevano eseguire il commit, dovevano prima lucidare il codice.

Questo sarebbe controproducente: la gente avrebbe voglia di tornare ai vecchi tempi cattivi quando hanno dovuto impegnarsi nulla per il pronti contro termine e tutti potevano vedere i loro errori, stile di codifica male e così via. Si perderebbe la libertà offerta da un DVCS: ramificazione a basso costo, cronologia locale mantenendo un repository centrale per il codice di produzione.

Non applicare nulla quando si esegue un commit locale.

+3

Quello che dici è assolutamente giusto in quasi tutti i casi. Tuttavia, questa è una piccola squadra che lavora su un progetto privato con standard elevati e in quanto gruppo hanno deciso che questa è la strada che vogliono intraprendere. La domanda non riguarda le migliori pratiche, ma il metodo migliore per raggiungere un obiettivo per una squadra specifica. –

1

Dopo aver configurato un server intermedio come altri hanno suggerito, impostare il collegamento pre-receive per eseguire uno script sul commit in entrata e normalizzarlo secondo gli standard di codifica. Spesso gli standard di codifica sono definiti da regole applicabili al computer. Non fare in modo che i tuoi sviluppatori vadano a modificare gli spazi bianchi di qua e di là quando un semplice script di bash o qualsiasi cosa potrebbe farlo per loro. E se hai uno script per farlo, perché farlo eseguire manualmente dallo sviluppatore quando può essere eseguito automaticamente su ogni push sul repository intermedio.

3

penso che l'approccio migliore che ho visto è git + Gerrit + Jenkins. Il gerrit introduce la nozione di un changeset. Il plugin jenkins gerrit potrebbe creare ogni changeset pubblicato (eseguendo qualsiasi tipo di test che desideri) e contrassegnarli come "verificati", quindi il changeset verificato potrebbe essere unito a un ramo principale. Se il changeset fallisce nella compilazione, il committer riceve un'e-mail di notifica, quindi può modificare il commit e aggiornare il changeset.

0

Scrivi un Makefile che:

  1. copia i file in corso per testare server.

  2. Trova l'output dei test di unità.

2.1. Se non ci sono anomalie, eseguire 'git commit'

2.2 Se ci sono anomalie, echo un errore.

Utilizzo di Makefile per eseguire la mia compilazione E il commit è stato una vera manna. Posso automatizzare la formattazione complessa e la pulizia dei file prima di eseguire il commit.

Edit:

Naturalmente, Makefiles non sono le uniche cose che puoi fare. Ant/Bash/altri linguaggi di scripting possono farlo per te.

Problemi correlati