TFS 管道中多个环境的 Web.config

问题描述

我有一个 web 项目,它根据客户端和区域部署了 50 多个服务器,每个 webconfig 有 600 多个特定于每个客户端和环境的值。意味着 WebConfig 有 600 多个 appsetting 标签,并且每个客户端和环境都有自己的值。现在它的手册如果任何值更改比发布团队将在服务器上手动进行并在 webconfig添加/更新值。 我想处理它

tfs 通过标记 webconfig 的值来发布管道,但再次创建每个客户端的变量组并非易事,这将创建 50 个组变量,每个组变量将有 600 个值。 50x600 = 30,000

是否有一种简单的方法可以在 TFS 管道中的每个客户端发布时更新 webconfig

提前致谢

解决方法

您可以尝试在发布管道中使用 FileTransform 任务来更新 webconfig 值。

在构建或发布管道中定义的变量将与任何配置文件和 parameters.xml 的 appSettings、applicationSettings 和 connectionStrings 部分中的“key”或“name”条目进行匹配。变量替换在配置转换后运行。

FileTransform 任务会将管道变量与 appsettings 部分中的 keyname 条目进行匹配。并使用匹配的管道变量更新 webconfig 的 appsettings 值。

因此您可以定义一个与需要更改的 appsetting 的 keyname 条目同名的管道变量。创建新版本时,FileTransform 任务将使用管道变量的值更改应用设置。

您还可以使用 Magic Chuncks 任务更新 webconfig 应用设置。

查看 here 以了解如何使用魔术夹转换 xml 文件

请查看this similar thread了解更多信息。

更新:

由于手动创建所有变量的工作量很大,您可以尝试使用 Variablegroups - Add rest api 来执行此操作。

POST https://{instance}/{collection}/{project}/_apis/distributedtask/variablegroups?api-version=4.1-preview.1

您需要先编写脚本读取所有的appsettings,然后将所有的appsettings 添加到rest api 请求体中。见下例:

例如,我在 web.config 中有以下 appsettings。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings file="custom.config">
    <add key="ApplicationName" value="MyApplication" />
    <add key="ApplicationName2" value="MyApplication2" />
    <add key="ApplicationName3" value="MyApplication3" />
  </appSettings>
</configuration>

首先,我需要编写脚本将所有键和值添加到请求正文中。然后调用rest api。见下例:

$body=@{
  "variables"= @{};
  "type"= "Vsts";
  "name"= "VariableGroup1";  #variable Group Name
  "description"= "A test variable group"
}

$appConfig = New-Object XML 

$appConfig.Load("path\to\web.config") 

$settigs = $appConfig.configuration.appsettings

foreach($setting in $settigs.add) {

  $body.variables[$setting.key]=@{value=$setting.value}

}
# Call rest api to create variable group

$url = "https://{instance}/{collection}/{project}/_apis/distributedtask/variablegroups?api-version=4.1-preview.1"
$PAT="Personal access token"
$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($PAT)"))

$bodyjson = $body | convertto-json

$pipeline1 = Invoke-RestMethod -Uri $url -Headers @{authorization = "Basic $base64AuthInfo"} -Method post -ContentType "application/json" -Body $bodyjson

通过使用脚本,您无需手动创建变量组。