转载:Using PowerShell in the build process 使用Powershell进行build

来源:互联网 发布:游族网络电脑官网 编辑:程序博客网 时间:2024/05/22 06:15

Using PowerShell in the build process

by Mike Linnen 四月 08, 2009 06:37

Ihave used NAnt and MSBuild for years on many projects and I alwaysthought there has to be a better way to script build processes.  Well Itook a look at PowerShell and psake and so far I like it.  psake is a PowerShellscript that makes breaking up your build script into target tasks veryeasy.  These tasks can also have dependencies on other tasks.  Thisallows you to call into the build script requesting a specific task tobe built and have the dependant tasks get executed first.  This conceptis not anything new to build frameworks but it is a great startingpoint to use the goodness of PowerShell in a build environment.

You can get psake from the Google Code repository. I first tried the download link for v0.21 but I had some problemsgetting it to run my tasks so I went directly to the source and grabbedthe tip version (version r27 at the time) of psake.ps1 and my problemswent away. 

You can start off by using the default.ps1 scriptas a basis for your build process.  For a simple build process that Iwanted to have for some of my small projects I wanted to be able to dothe following:

  • “Clean”the local directory
  • “Compile” the VS 2008 Solution
  • “Test” the nunit tests
  • “Package” the results into a zip for easy xcopy deployment

Here is what I ended up with as a starting point for my default.ps1.

image

Thisreally doesn't do anything so far except set up some properties forpaths and define the target tasks I want to support.  The psake.ps1script assumes your build script is named default.ps1 unless you passin another script name as an argument.  Also since the task default isdefined in my build script if I don't pass in a target task then thedefault task is executed which I have set as Test.

Build invoked without any target task:

image

Build invoked with the target task Package specified:

image

Sonow I have the shell of my build so lets get it to compile my VisualStudio 2008 solution.  All I have to do is add the code to the Compiletask to launch VS 2008 passing in some command line options.

image

And here it is in action:

image

NoticeI had to pipe the result of the command line call to “out-null”.  If Ididn't do this the call to VS 2008 would run in the background andcontrol would be passed back to my PowerShell script immediately.  Iwant to be sure that my build script would wait for the compile tocomplete before it would continue on. 

What about if thecompile fails?  As it is right now the build script does not detectthat the compile completed successfully or not.  VS 2008 (and previousversions of VS) return an exit code that defines if the compile wassuccessful or not.  If the exit code = 0 then you can assume it wassuccessful.  So all we need to do is test the exit code after the callto VS 2008.  PowerShell makes this easy with the $LastExitCodevariable.  Throwing an exception in a task is detected by the psake.ps1script and stops the build for you.

image

Iplaced a syntax error in a source file and when I call the Test targetthe Compile target fails and the Test target never executes:

image

NowI want to add in the ability to get the latest code from my sourcecontrol repository.  Here is were I wanted the ability to supportmultiple solutions for different source control repositories likeSubversion or SourceGear Vault.  But lets get it to work first withSubversion and then later refactor it to support other repositories. For starters lets simply add the support for getting latest code in theCompile task.

image

Asyou can see right now this is very procedural and could certainly usesome refactoring, but lets get it to work first and then worry aboutrefactoring.  Here it is in action:

image

AsI mentioned before I want to be able to support multiple source controlsolutions.  The idea here is something similar to what CI Factory uses.  In CI Factoryyou have what is known as a Package.  A Package is nothing more than animplementation of a build script problem for a given product.  Forexample you might have a source control package that uses Subversionand another source control package that uses SourceGear Vault.  Yousimply include the package you want for the source control product thatyou are using.  Psake also allows for you to include external scriptsin your build process.  Here is how we would change what we have rightnow to support multiple source control solutions.

So I createda Packages folder under the current folder that my psake.ps1 scriptresides. I then created a file called SourceControl.SVN.ps1 in thePackages folder that looked like the following:

image

Inthe default.ps1 script Compile task I replaced the source control getlatest code (told you I was going to refactor it) with a call to theSourceControl.GetLatest function (Line #20).  I also added a call tothe psake include function (Line #10) passing in the following“Packages/SourceControl.SVN.ps1”.  Here is what the default.ps1 lookslike now:

image

Soif I wanted to support SourceGear Vault I would simply create anotherpackage file called SourceControl.Vault.ps1 and place theimplementation inside the GetLatest function and change the includestatement in the default.ps1 script to reference the vault version ofsource control.  I plan on adding in support for my Unit Tests the sameway I did the source control, that way I can easily have support formultiple unit testing frameworks.

Conclusion

Asyou can see it is pretty easy to use PowerShell to replace your buildprocess.  This post was just a short introduction on how you might getstarted and end that crazy XML syntax that has been used for so long inbuild scripting.  I have a lot more to do on this to make it actuallyusable for some of my small projects but hopefully I can evolve it intosomething that will be easy to maintain and reliable.  All in all Ithink PowerShell has some pretty cool ways of scripting some nice buildsolutions. 

原创粉丝点击