Archivio tag: shell

Deploy di un progetto su Git via FTP

Git-Icon-1788C

Git è eccezionale, una volta scoperto difficilmente si torna indietro.
Tutti i miei progetti infatti ora sono su Git e per la maggior parte di essi il relativo ambiente di produzione risiede su Hosting Linux “normali”, quelli in cui il provider fornisce come unica possibilità di aggiornamento dei file il servizio FTP. Così, dopo aver terminato lo sviluppo di nuove features, mi ritrovo spesso con diversi commit eseguiti e per aggiornare l’ambiente in produzione avevo 2 possibilità:

  1. effettuare l’upload dell’intero progetto sovrascrivendo tutti i file
  2. creare un file di tutti i file modificati (estrandoli da tutti i commit) per poi aggiornarli via FTP

La prima soluzione è sicuramente la più veloce ma spesso risulta lunga e si va ad utilizzare banda inutilmente perchè la maggior parte dei file non dovrebbe essere aggiornata (parliamo di tutti quelli non modificati). La seconda soluzione richiedeva un lavoro da certosino che poi ho scoperto di poter eseguire tramite alcuni comandi Git. Da qui ho pensato di realizzare uno script shell per ottimizzare le operazioni di deploy in produzione: Git-Deploy-by-FTP.

E’ il mio primo shell script e l’ho condiviso via GitHub, sicuramente può essere migliorato! 😉
L’ambiente su cui sviluppo e su cui ho testato il corretto funzionamento è OSX.

Come funziona?

Questo script può essere richiamato da riga di comando e devono essere passati alcuni parametri che vedremo successivamente.
Le operazioni che esegue possono essere sostanzialmente riassunte in:

  • crea un git clone del repository e su questa copia lavora
  • effettua un git diff per estrarre tutti i file modificati/eliminati/aggiunti basandosi su 2 commit che definiamo “deploy” e “production
  • esegue l’aggiornamento di tutti i file (eliminandoli dove necessario) dell’ambiente di produzione via FTP (tramite CURL)

Ho preferito far lavorare lo script su un clone in modo da poter stare tranquilli su eventuali problemi dovuti ad interruzione delle procedure. Lavorando su una copia del repository infatti in qualsiasi momento posso interrompere la procedura senza creare problemi al repository principale.

I due commit “deploy” e “production” sono identificati dal loro SHA. Il primo (deploy) rappresenta lo stato dei file nel commit che vorrei mandare in produzione, il secondo (production) identifica l’ultimo commit mandato in produzione. Il comando git diff esegue le operazioni anche a ritroso, quindi potrei anche effettuare un downgrade del software anzichè un upgrade.

L’aggiornamento dei file avviene tramite comando CURL che effettua il login via FTP e invia i comandi necessari.

Configurazione

Ho pensato ad un sistema flessibile che mi permettesse di gestire più progetti tramite un unico script. L’idea quindi è quella di poter scrivere diversi file di configurazione e richiamare quello interessato tramite parametro da riga di comando (vedi sotto). Nello script trovate un file di esempio di configurazione: dp-sample-config.
Create una copia del file e rinominatelo secondo questo criterio: .dp-config-ProjectName
dove ProjectName identifica un vostro progetto. In questo modo potrete avere diversi file di configurazione, uno per ogni progetto. I file di configurazione devono necessariamente risiedere nella stessa directory dello script (iniziando col . però dovrebbero rimanere nascosti).

Le variabili da valorizzare obbligatoriamente in ogni file sono quelle nella sezione “SETTINGS”:

  • EXPORTED_DIR – è la directory temporanea utilizzata per creare il repo clone di cui sopra
  • PROJECT_REPO_DIR – è la directory in cui si trova il repository da utilizzare
  • FTP_SERVER – il nome del server FTP dell’ambiente in produzione
  • FTP_PATH – il path dell’ambiente in produzione del suddetto server FTP
  • FTP_USERNAME – FTP username per connettersi al server
  • FTP_PASSWORD – FTP password per connettersi al server

Nel file troverete anche altri parametri secondari che potrete configurare in un secondo momento dopo averne capito il loro utilizzo.

Usage (come usare lo script)

Lo script dp.sh può essere richiamato da riga di comando passando alcuni parametri di cui 2 obbligatori:

  • -p, –project Imposta il nome del progetto di cui si vuole effettuare il deploy
  • -d, –deploy Imposta il commit di cui si vuole effettuare il deploy
  • –not-simulate Con questo parametro lo script eseguirà il deploy realmente, viceversa effettuerà solo una simulazione

Il parametro -p (o –project) deve essere seguito dal ProjectName di cui sopra.
Il parametro -d (o –deploy) deve essere seguito dal SHA del commit di cui si vuole effettuare il deploy.
Dopo aver verificato tramite simulazione che tutto è corretto potrete aggiungere il parametro –not-simulate per effettuare realmente il deploy. Questo parametro è stato aggiunto per ovvi motivi di sicurezza, meglio una simulazione in più che qualche file errato in produzione!

Ora un esempio di comando:
# dp.sh --project progetto1 --deploy bb5c8d9

Questo comando per prima cosa cercherà il file di configurazione .dp-config-progetto1 da cui prelevare le suddette variabili. Successivamente effettuerà una simulazione del deploy del commit bb5c8d9 in ambiente di produzione. Aggiungendo come ultimo parametro –not-simulate i file verranno realmente inviati via FTP al server.

Tag “production”

Ho cercato una soluzione che mi permettesse di tenere traccia dell’ultimo deploy effettuato in modo da sapere sempre in che commit si trova l’ambiente di produzione. Per fare questo utilizzo un tag chiamato “production” sul repository principale. Prima di effettuare il “git diff” di cui sopra lo script interroga il repository per ottenere il commit relativo al tag “production”.

In fase di chiusura delle operazioni, solo nel caso in cui non sia stata effettuata una simulazione, lo script sposta il tag “production” sul nuovo commit di cui si è appena effettuato il deploy. Questa è l’unica operazione che viene eseguita sul repository principale e non sulla copia clonata.

ToDo list

Lo script al momento funziona bene quando i commits “deploy” e “production” sono sullo stesso branch. Nel caso si trovino su due branch diversi è bene verificare con attenzione cosa accade (simulate!).
Una nuova feature da implementare è sicuramente la gestione dei sub-moduli che al momento vengono ignorati dalla procedura.

Buon deploy! 😉

 

 

 

 

 

 

 

 

Ottimizzare la shell per Git

Oh-My-Zsh è un framework per gestire al meglio la configurazione della shell Zsh. Include oltre 40 plugin (rails, git, OSX, ecc.) e oltre 80 temi. E’ facile da installare sul vostro sistema OSX e già la configurazione base aiuta notevolmente nell’utilizzo dei Repository Git, ad esempio. Come si vede dall’immagine sopra la shell riconosce che nella directory in cui si è posizionati vi è un repository Git e ne segnala il branch corrente. Io, oltre a git, ho abilitato anche il plugin per OSX:

  • aprire il file ~/.zshrc
  • modificare la riga: plugins=(git osx)

Appunti Shell

Variabili Shell

Per interrompere uno script shell e richiedere un parametro all’utente:
read -p "Quale versione ripristino? > " ver
Successivamente potete utilizzare la variabile $ver nello script così (con l’utilizzo anche di double quote):
echo "Versione: $ver"

Encrypting and decrypting files

Per criptare un file con GPG lanciare il comando:
gpg --batch --no-tty -c --passphrase "my_passphrase" file_to_crypt.ext

Per decriptare lo stesso file:
gpg --batch --yes --passphrase "my_passphrase" --output file_to_crypt.ext --decrypt file_to_crypt.ext.gpg

MySQL eseguire query da command line

Per esguire una query da riga di comando bisogna usare il parametro “-e”. Per creare, ad esempio, un database MySql da riga di comando:
mysql -uroot -e "CREATE DATABASE my_db"