iT邦幫忙

DAY 17
4

使用Jenkins打造.Net CI Server系列 第 17

CI Server 17 - 使用MsBuild整合常用工作

  • 分享至 

  • xImage
  •  

MsBuild是Visual Studio的建置系統,它是一個Xml格式的文件,
Visual Studio的專案檔其實就是使用MsBuild來寫的,
裡面描述了專案所包含的檔案有哪些,建置的設定等等資訊,
除了使用在Visual Studio的專案檔之外,我們也可以使用MsBuild來撰寫建置的流程,
再利用MsBuild寫好基本的範本之後,我們只要將需要分別設定的參數抽出來,
即可很快速地將我們的建置流程套用到不同的專案上面,
本篇文章將向大家介紹如何撰寫基本的MsBuild檔案
※基本框架
MsBuild的內容其實是由一個Project包含著多個Target所組合而成,
再依照參數的不同來決定將會執行那些Target,最基本的檔案格式如下

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
	<Target Name="Build">
		<Message Text="Hello Msbuild!" />
	</Target>
</Project>

在專案檔中我們指定了預設執行的Target為Build,
在Build之中執行了顯示訊息的任務,在畫面上輸出Hello Msbuild!,
我們通常稱Message這項工作為Task,除了預設包含的Task之外也可以自己開發擴充,
更多的Task可以參考http://msdn.microsoft.com/zh-tw/library/7z253716.aspx
使用Visual Studio命令提示字元執行後可看到結果
執行語法: msbuild Sample01.csproj

如果今天我們希望可以按照順序執行多個任務,我們可以使用下面的寫法

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
	<Target Name="Build">		
		<CallTarget Targets="Step 1"/>
				
		<CallTarget Targets="Step 2"/>
				
		<CallTarget Targets="Step 3"/>		
	</Target>
	
	<Target Name="Step 1">	
		<Message Text="Step 1" />
	</Target>
	
	<Target Name="Step 2">
		<Message Text="Step 2" />
	</Target>
	
	<Target Name="Step 3">
		<Message Text="Step 3" />
	</Target>
</Project>

執行結果

※ItemGroup和Item
我們在MsBuild中通常都會使用Item來指定專案建置所包含的項目,而ItemGroup代表Item的集合,
在ItemGroup之中,我們可以自己為Item取名,下面的例子中我將Item取名為ProjectFiles,
我用以下的語法來代表專案之中所有的cs檔,並可透過@(ItemName)來輸出內容

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
	<ItemGroup>		
		<ProjectFiles Include="C:\Users\kirkchen\Documents\GithubProject\CI-Sample\**\*.cs" />		
	</ItemGroup>
	
	<Target Name="Build">
		<Message Text="@(ProjectFiles)" />
	</Target>
</Project>

執行結果

Item預設是使用分號做分隔,我們也可以透過@(ItemName,'Seperator')來指定分隔符號,
但如果我們將Item使用在串指令的時候,可使用@(ItemName->'Files:%(FullPath)','%0a'),例如

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">	
	<ItemGroup>		
		<ProjectFiles Include="C:\Users\kirkchen\Documents\GithubProject\CI-Sample\**\*.cs" />		
	</ItemGroup>
	
	<Target Name="Build">
		<Message Text="@(ProjectFiles->'Files:%(FullPath)','%0a')" />
	</Target>
</Project>

執行結果 (%0a代表換行符號)

關於格式化輸出內容可以參考http://en.csharp-online.net/MSBuild%3A_By_Example%E2%80%94Formatting_Your_Output

※PropertyGroup和Property
在Msbuild中Project代表使用者定義的屬性和值,通常我們會用來存放可變更的參數
(例如: SourceMonitor執行路徑,檔案輸出位置等等)
並且可以使用$(PropertyName)來呼叫,請參考以下範例

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">	
	<PropertyGroup>
		<SimianPath>"C:\Program Files (x86)\Simian\bin\simian-2.3.33.exe"</SimianPath>		
	</PropertyGroup>
	
	<Target Name="Build">
		<Message Text="$(SimianPath)" />
	</Target>
</Project>

執行結果

※執行Task
在Target中的每一個執行動作,我們都稱他為Task (例如Message),
除了MsBuild本身支援的Task之外,我們也可以引用ThirdParty開發的Task,
例如我在之前掃描StyleCop時所寫的MsBuild檔案就是使用StyleCop所提供的Task,
透過Using Task來引用Dll,再執行所引用的Task,例如

<?xml version="1.0" encoding="utf-8"?>
<Project Defaulttargets="StyleCop" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
	<UsingTask AssemblyFile="$(MSBuildExtensionsPath)\..\StyleCop 4.7\StyleCop.dll" TaskName="StyleCopTask"/>

	<ItemGroup>		
		<StyleCopFiles Include="C:\Users\kirkchen\Documents\GithubProject\CI-Sample\**\*.cs" Exclude="C:\Users\kirkchen\Documents\GithubProject\CI-Sample\**\*Test.cs" />		
	</ItemGroup>
	
	<Target Name="StyleCop">		   
		<StyleCopTask
			ProjectFullPath="$(MSBuildProjectDirectory)"
			SourceFiles="@(StyleCopFiles)"
			ForceFullAnalysis="true"
			TreatErrorsAsWarnings="true"
			OutputFile="$(MSBuildStartupDirectory)\StyleCopReport.xml"
			CacheResults="true" />    
	</Target>
</Project>

執行結果

※總結
透過本篇文章的介紹,我們已經可以初步了解MsBuild的撰寫方法,
接下來的文章中我將向大家介紹如何將建置流程的語法以MsBuild改寫,
以方便整合Jenkins時不需要設定太多的資料或建置的流程,
只要透過共用的MsBuild建置邏輯配合專案的獨立屬性設定,
就可以很快速地將CI每日建置套用到每個專案身上,
關於今天的分享,若有問題歡迎大家一起討論!


上一篇
CI Server 16 - 整合程式碼複雜度及深度報表 (Source Monitor)
下一篇
CI Server 18 - 使用MsBuild控制建置流程
系列文
使用Jenkins打造.Net CI Server30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
ted99tw
iT邦高手 1 級 ‧ 2012-10-25 15:21:43

沙發

金係粉可怕的內容呀!!

讚讚讚

我要留言

立即登入留言