佈署不同環境時, Web.config 的值也是會不同
根據我目前最直覺的做法就是在組態管理員下手
- Web.Japan.config
- Web.Taiwan.config
利用不同組態去 Publish 就可以切換成不同的組態
但是目前情境是希望不想利用這種方式去切換
希望能透過 VSTS 的 Release Management 環境切換把不同的組態值設定進去
在 VSTS 進入 Release 階段前, 先了解 Build 階段到底要做到哪些事情
預設的 Visual Studio Template Build Definition 可以看到最後是 Publish Artifact
Artifact ? 姑且稱作它為「工件」
回想一下我們手動佈署的步驟: Build -> web deploy package -> deploy
而 Artifact 就是那包要被佈署的 package
為此我們重新打造一個 Build Definition 來實作此篇主題
切換 Web.config 除了新增多個組態檔
還有另一種方式就是利用 Web Deploy Package 出來的 SetParameters.xml
去替換 Web.config Mapping 到的 key-value
Add parameters.xml & Add Replace-SetParameters.ps1
在專案根目錄底下新增 parameters.xml
<?xml version="1.0" encoding="utf-8" ?>
<parameters>
<parameter name="DemoKey" description="The DemoKey setting" defaultvalue="__DemoKey__" tags="">
<parameterentry kind="XmlFile" scope="\\web.config$" match="/configuration/appSettings/add[@key='DemoKey']/@value">
</parameterentry>
</parameter>
</parameters>
使用 Web Deploy Package 產出的 SetParameters.xml 會有對應的設定
新增一個 Power Shell Script 在專案外層的資料夾內 (Release 階段使用)
param(
[string]$setParamsFilePath
)
Write-Verbose -Verbose "Entering script Replace-SetParameters.ps1"
Write-Verbose -Verbose ("Path to SetParametersFile: {0}" -f $setParamsFilePath)
# get the environment variables
$vars = gci -path env:*
# read in the setParameters file
$contents = gc -Path $setParamsFilePath
# perform a regex replacement
$newContents = "";
$contents | % {
$line = $_
if ($_ -match "__(\w+)__") {
$setting = gci -path env:* | ? { $_.Name -eq $Matches[1] }
if ($setting) {
Write-Verbose -Verbose ("Replacing key {0} with value from environment" -f $setting.Name)
$line = $_ -replace "__(\w+)__", $setting.Value
}
}
$newContents += $line + [Environment]::NewLine
}
Write-Verbose -Verbose "Overwriting SetParameters file with new values"
sc $setParamsFilePath -Value $newContents
Write-Verbose -Verbose "Exiting script Replace-SetParameters.ps1"
這 Script 語法不懂不打緊, 挑幾個關鍵的事情看即可
可以看到語法中是把 __(\w+)__ 替換成環境變量的 value
要注意的是環境變量永遠要保持 unique
再來就是站台名稱我也想要使用環境變量來替代
所以把 Package 發行檔的 Site Name 設置 __SiteName__
讓打包出來的 SetParameters.xml 有站台名稱替換的設定
創建 Artifact By Build
Add New Build Definition 選擇 Visual Studio template
調整 Build Soloution 的 MSBuild Arguments
/p:DeployOnBuild=true /p:PublishProfile=Package /p:PackageLocation="$(build.StagingDirectory)"
然後在 Build 底下增加兩條 Task
Copy Publish Artifact: drop - 將 package 出來的所有 files copy 到 Artifact/drop 資料夾
Publish Artifact: scripts - 把我們寫好 power shell 從 scripts 資料夾整份 copy 到 Artifact/scripts 資料夾
創建 Release Definition
創一個 Empty 的 Release Definition, 選擇剛剛我們做好的 Build Artifact
可以先勾選
這裡我們只需要加入 2 個 Task
PowerShell & Batch Script
PowerShell 設定 (執行替換內的SetParameters.xml
值)
Script Path: $(System.DefaultWorkingDirectory)/XXXXX/scripts/Replace-SetParameters.ps1
Arguments: -setParamsFilePath $(System.DefaultWorkingDirectory)\XXXXXX\drop\XXXXXX.SetParameters.xml
Batch Script 設定
Path: $(System.DefaultWorkingDirectory)/XXXXXX/drop/XXXXXX.deploy.cmd
Arguments: /Y /M:http://xxxxxx/MSDEPLOYAGENTSERVICE /U:*** /P:***
然後加入一個環境去設置我們要設置的環境變量給 PowerShell 替換的值
然後把要佈署站台名稱跟你 Web.config 想替換的 value 設定好即可
大功告成, 如果順利的話就可以在遠端的 IIS 站台檢查 Web.config 是否如期的更新成我們設定的值了
相關連結
WebDeploy, Configs and Web Release Management
WebDeploy and Release Management – The Proper Way
How to override ASP.NET deployment parameters when publishing
VSTS Release - Define custom variable in web.config and set at release time
WEBDEPLOY PARAMETERIZATION TIP: DONT PUBLISH YOUR PARAMETERIZATION FILES