alessandro melchiori
() => melkio.OnStage();

Alessandro Melchiori

Build automation @codiceplastico with psake

09 Jul 2012

Come bentornato da una settimana di pseudo-ferie, mi sono imposto di sistemare e soprattutto standardizzare il processo e i tool di build che utilizziamo. Fino ad ora, chi aveva l’ownership del progetto ne determinava, in fase di startup, anche il tool per la build automatica. Non che questo generasse grossi problemi, ma avere qualche script di build in ruby utilizzando rake, altri, su “vecchi progetti” in xml utilizzando nant, proprio non mi piaceva.

Era da un po’ che avevo puntato psake e questa è stata l’occasione propizia per approfondirne un po’ l’uso.

Facciamo le dovute presentazioni: come riporta anche l’home page del wiki del progetto: ”psake is a build automation tool written in PowerShell“…proprio quello che serve a me :-) Psake non introduce nulla di sconvolgente, la semantica è la stessa di nant/rake (et simili): una serie di task da eseguire con una certa sequenza, con il grosso vantaggio di utilizzare un linguaggio di scripting che conosco abbastanza bene (PowerShell) e che ha tutta la potenza del .Net framework dalla sua parte.

Psake non è altro che un modulo PowerShell che contiene tutte le funzioni necessarie per eseguire i vari step. Per ottenerlo affidiamoci al solito fido nuget.

nuget install psake

Ecco…abbiamo già tutto il necessario per poter utilizzare psake :-)

Come per tutti i tool di build automatica citati in precedenza, anche con psake abbiamo, ovviamente, bisogno di uno script file. Lo scheletro di un possibile script di build potrebbe essere il seguente:

properties { 
  $prop1 = "value 1"
  $prop2 = $par1 
  $execute_check = $true
}

include .\external.ps1

task default -depends LastTask

task CheckParameters -precondition { $execute_check -eq $true } {
  Assert ($prop2 -ne $null) "par1 should not be null"
}

task FirstTask -depends CheckParameters {
  Write-Host "First task in action with prop1 value equals to $prop1"
}

task LastTask -depends FirstTask {
  Write-Host "Last task in action with prop2 value equals to $prop2"
}

In questo script abbiamo (quasi) tutti gli scenari disponibili:

  • dalla riga 1 alla 5 possiamo definire delle property che hanno lo stesso scope dello script e che sono quindi comuni a tutti i possibili task. Psake ha delle property standard (che vediamo tra un attimo) che sono valorizzate con dei valori di default, ovviamente, modificabili

  • alla riga 3 viene utilizzato un parametro ($par1) che sarà impostato in fase di esecuzione dello script. Sia le properties sia i parameters sono per psake delle semplici hashtable, con l’unica differenza che i parameters vengono valutati, nell’ordine, prima delle properties e quindi possono essere referenziati e combinati da una property.

  • alla riga 7, con l’istruzione “include” abbiamo la possibilità di includere, appunto, un file powershell esterno che contiene, per esempio, delle utility accessorie

  • Alla riga 9 c’è l’entry point di default dello script: il task “default”. All’interno di uno script ci può essere un unico task denominato “default” che non deve contenere alcuna istruzione. Con la keyword “depends” identifichiamo quale altro task deve essere eseguito prima del task in oggetto.

  • Alla riga 11, utilizzando la keyword “precondition”, stiamo identificando un task che verrà eseguito solo se la condizione proposta è verificata

  • Alla riga 12, con la funzione “Assert” messa a disposizione dall’engine (contenuta nel modulo psake.psm1), abbiamo la possibilità di fare delle asserzioni vere e proprie che interrompono l’esecuzione dello script qualora risultassero non verificate.

Ora che lo script è pronto dobbiamo poterlo “runnare”…ma non c’è nulla di più semplice :-) Aprendo la console powershell ecco le istruzioni da eseguire:

Import-Module .\psake.psm1
Invoke-psake .\test.ps1 -parameters @{'par1' = 'valore'}

  • Alla riga 1 stiamo importando il modulo di psake, per poter usufruire di tutte le funzionalità dell’ engine

  • Alla riga 2 viene eseguito effettivamente lo script, passando il par1 con il valore indicato

Come detto prima, nel modulo psake.psm1, sono già inizializzate alcune proprietà di default. Tra queste c’è il nome dello script di build che psake cerca qualora non fosse diversamente specificato (default.ps1) e la versione di default del framework (la 4.0) con cui, eventualmente, compilare solution. Oltre a queste ci sono altre proprietà, più o meno utili/importanti, che possono essere customizzate. Se si vuole fare in modo di cambiare in modo permanente il valore di default di tali property, un modo è quello di modificare il file  psake-config.ps1 che si trova nella stessa folder del file psake.psm1

Insomma, con pochissimo effort, abbiamo uno script engine molto versatile e che può sfruttare tutte le feature del .Net framework. Per ora mi fermerei qui…poche semplici istruzioni per essere fin da subito operativi. Al prossimo giro vediamo lo script di build che ho prodotto per uno dei nostri progetti.

Buona build a tutti con powershell e psake :-)

Comments