用VSTS去部署Web Site有什麼難的?尤其部署到Azure Web Site更是沒有難度,基本上只要用Azure web app deployment這個Task就可以。但是,部署到地端的IIS裡面,就沒有這樣簡單,尤其是要從雲到地的部署,沒有這樣簡單的原因,不外乎幾點:
IIS沒有辦法裝Web deploy套件
地端Agent可能沒有用Web deploy的權限
VSTS並沒有類似Azure web app deployment簡單操作的Task可用
如果真的要做到第三點,可以用這兩種做法去做,不過,前提都是必須要克服第一和第二點問題
用Visual Studio Build Task內的MSBuild Arguments,透過MSBuild參數做Web deploy,直接部署到IIS,不過,這樣流程就不容易拆分Build和Release
用Visual Studio Build Task內的MSBuild Arguments,透過MSBuild參數做Web deploy Package,再用IIS Web App Deployment的Task,取得Web deploy package的Zip檔作部署動作
所以,除了Web Deploy外,另一個作法就是產生要Publish檔案,透過File Copy方式放到IIS中Application資料夾內,這樣也可以同時把Build和Release流程分開
Build 的流程
設定Build流程其實不難,如下圖這樣做法就可以
其中,有一個需注意的就是Copy Publish Artifact或是Publish Artifact這兩個Task,它們並不會自動把你Build完的專案,產出只需要Publish的檔案,它只會把Build完畢的專案資料夾內檔案原封不動放到$(Build.ArtifactStagingDirectory)資料夾內,所以,還是會把像是.cs檔案一併取出來。如果,要在$(Build.ArtifactStagingDirectory)存放真正要部署的檔案,必須在Visual Studio Build的Task去下MSBuild Arguments的Command,其指令為1
/p:OutDir=$(Build.StagingDirectory) /P:TransformConfigFiles=true
然後,把Build完畢檔案放到$(Build.StagingDirectory)內,在Copy Publish Artifact的Task設定如下:
不過,這樣產生部署的檔案,還會有一點點問題,這問題會在你的專案中如果有加入這兩個Package
Microsoft.Net.Compilers 1.1.1
Microsoft.CodeDom.Providers.DotNetCompilerPlatform 1.0.1
它會產生一個Roslyn的資料夾在Bin資料夾內,這樣Build後會發現要Publish的資料夾中,在Roslyn中內的dll或是其他程式會放在跟Bin同一層目錄下
當你執行這個Web site就會發生這種錯誤,
找不到\bin\roslyn\csc.exe的錯誤資訊
如果沒有用到這兩個Package就把它移除吧,但是,如果真的有在使用的話,就必須在.csproj裡面加入下面指令1
2
3
4
5
6
7
<Target Name ="CopyRoslynFiles" AfterTargets ="AfterBuild" Condition ="!$(Disable_CopyWebApplication) And '$(OutDir)' != '$(OutputPath)'" >
<ItemGroup >
<RoslynFiles Include ="$(CscToolPath)\*" />
</ItemGroup >
<MakeDir Directories ="$(WebProjectOutputDir)\bin\roslyn" />
<Copy SourceFiles ="@(RoslynFiles)" DestinationFolder ="$(WebProjectOutputDir)\bin\roslyn" SkipUnchangedFiles ="true" Retries ="$(CopyRetryCount)" RetryDelayMilliseconds ="$(CopyRetryDelayMilliseconds)" />
</Target >
或是1
2
3
4
5
6
7
8
9
10
11
<Target Name ="EnsureNuGetPackageBuildImports" BeforeTargets ="PrepareForBuild" >
<PropertyGroup >
<ErrorText > This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText >
<PostBuildEvent >
if not exist "$(WebProjectOutputDir)\bin\Roslyn" md "$(WebProjectOutputDir)\bin\Roslyn"
start /MIN xcopy /s /y /R "$(OutDir)roslyn\*.*" "$(WebProjectOutputDir)\bin\Roslyn"
</PostBuildEvent >
</PropertyGroup >
<Error Condition ="!Exists('..\packages\Microsoft.Net.Compilers.1.3.2\build\Microsoft.Net.Compilers.props')" Text ="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Net.Compilers.1.3.2\build\Microsoft.Net.Compilers.props'))" />
<Error Condition ="!Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.2\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" Text ="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.2\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props'))" />
</Target >
又或者是在Visual studio中加入也可以1
2
if not exist "$(WebProjectOutputDir)\bin\Roslyn" md "$(WebProjectOutputDir)\bin\Roslyn"
start /MIN xcopy /s /y /R "$(OutDir)roslyn\*.*" "$(WebProjectOutputDir)\bin\Roslyn"
這樣就會在bin裡面多一個roslyn資料夾,且裡面也會有相關檔案,不過,這樣做法,其實是把原本Publish資料夾外的roslyn資料夾,拷貝一份到bin裡面
原始在bin資料夾內的roslyn資料夾中的檔案還是存在bin資料夾內
Release流程
在Release部分就相當簡單,就是把產生的Publish資料夾內的檔案複製到你IIS
所以,使用Copy Files toTask完成,在Source Path中,選_PublishedWebsites內的檔案就可以,如果還有多一層目錄,就選到那個目錄內的檔案即可,而Target Folder就是IIS Web Site資料夾路徑位置,這樣就可以透過Copy File方式部署檔案了