App.Exe 使用 Azure Devops 和发布变量进行配置转换

App.Exe Config Transform with Azure Devops and Release Variables

我目前正在使用 Azure Devops 和本地构建代理将 windows 服务部署到内部服务器,我正在寻找有关如何使用中定义的变量转换我的 MyApp.Exe.config 文件的信息我的发布任务。

对于 Web 应用程序,这似乎相当简单。我有一个 parameters.xml 文件,它与我的 IIS Web Deploy 任务中的 SetParameters File 一起使用。这将从发布任务中提取变量并相应地更新 web.config。

但是,我找不到关于如何使用可执行文件的配置文件执行此操作的明确答案。 This document 建议这应该是可能的,但看起来我需要提供一个已设置变量的转换文件。

总而言之,我想要做的是使用 Parameters.xml 文件来转换使用我的发布变量的可执行文件的配置文件。如何实现?

在您的问题中不清楚您要在目标文件中替换哪些值,因此可能需要注意:

". . . Variable substitution takes effect only on the applicationSettings, appSettings, connectionStrings, and configSections elements of configuration files. If you are looking to substitute values outside of these elements you can use a (parameters.xml) file, however you will need to use a 3rd party pipeline task to handle the variable substitution. . . ."

如果找不到第 3 方任务

当然 Document doesn't point us to any favored 3rd party task. So if you can't find a task that operates directly on the parameters.xml file, then you can use the File Transform task to add/replace values in your .config with tokens, and then use the Replace Tokens 插入变量值的任务。

示例:

在我的沙箱中,我可以通过简单地在我的管道中添加适当的变量来替换上面引用文本中指定部分中的 xml 值。

鉴于这是我的配置文件:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSection>
        <section name="entityFramework" />
    </configSection>
    <connectionStrings>
        <add name="DefaultConnection"
             connectionString="Data Source=(LocalDB)\LocalDB;FileName=Local.mdf" />
    </connectionStrings>
    <appSettings>
        <add key="ClientValidationEnabled" value="true" />
        <add key="UnobstructiveJavascriptEnabled" value="true" />
        <add key="AdminUserName" value="__AdminUserName__" />
        

<!-- Change AdminPassword in this line: --> 
        <add key="AdminPassword" value="__AdminPassword__" />


    </appSettings>
    <entityFramework>
        <defaultConnectionFactory type="System.Data.Entity.LocalDbConnectionFactory">
            <parameters></parameters>
        </defaultConnectionFactory>
        <providers>
            <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer" />
        </providers>
    </entityFramework>    
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <staticContent>
      <remove fileExtension=".woff" />
      <remove fileExtension=".woff2" />
      <mimeMap fileExtension=".woff" mimeType="application/font-woff" />
      <mimeMap fileExtension=".woff2" mimeType="application/font-woff" />
    </staticContent>
    <security>
      <requestFiltering>


<!-- change this value -->
        <requestLimits maxAllowedContentLength="1073741824" />


      </requestFiltering>
    </security>
  </system.webServer>
</configuration>

并在 yaml 中给出这些变量:

variables:
  solution: '**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'
  AdminPassword: 'fake password'
  maxAllowedContentLength: '25'

鉴于这是 yaml 任务:

- task: FileTransform@1
  inputs:
    folderPath: '$(System.DefaultWorkingDirectory)/src'
    enableXmlTransform: false
    fileType: 'xml'
    targetFiles: '*.config'

结果是这样的:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSection>
        <section name="entityFramework"/>
    </configSection>
    <connectionStrings>
        <add name="DefaultConnection" connectionString="Data Source=(LocalDB)\LocalDB;FileName=Local.mdf"/>
    </connectionStrings>
    <appSettings>
        <add key="ClientValidationEnabled" value="true"/>
        <add key="UnobstructiveJavascriptEnabled" value="true"/>
        <add key="AdminUserName" value="__AdminUserName__"/>


        <add key="AdminPassword" value="fake password"/>


    </appSettings>
    <entityFramework>
        <defaultConnectionFactory type="System.Data.Entity.LocalDbConnectionFactory">
            <parameters/>
        </defaultConnectionFactory>
        <providers>
            <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer"/>
        </providers>
    </entityFramework>    
    <system.webServer>        
        <security>
            <requestFiltering>


                <requestLimits maxAllowedContentLength="1073741824"/>


            </requestFiltering>
        </security>
    </system.webServer>

注意未替换的值!!

如文档中所述,我想更改的值 <requestLimits maxAllowedContentLength="1073741824"/> 未更改 b/c 它不是由 configSection 定义的,也不是预定义节点的一部分。

使用第三方替代默认值

采用相同的配置文件,但更改 yaml 任务以包含对以下内容的转换 transform.config

给定相同的配置文件

transform.config

<?xml version="1.0" encoding="utf-8"?>

<!-- For more information on using web.config transformation visit https://go.microsoft.com/fwlink/?LinkId=125889 -->

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<system.webServer>    
    <security>
      <requestFiltering>


        <!-- change this value -->
        <requestLimits maxAllowedContentLength="${maxAllowedContentLength}$" xdt:Transform="Replace" />


      </requestFiltering>
    </security>
</system.webServer>
</configuration>

新任务设置

- task: FileTransform@1
  inputs:
    folderPath: '$(System.DefaultWorkingDirectory)/src'
    enableXmlTransform: true
    xmlTransformationRules: '-transform transform.config -xml app.config'
    fileType: 'xml'
    targetFiles: '*.config'

- task: replacetokens@3
  inputs:
    rootDirectory: '$(build.sourcesdirectory)/src'
    targetFiles: 'app.config'
    encoding: 'auto'
    writeBOM: false
    actionOnMissing: 'warn'
    keepToken: false
    tokenPrefix: '${'
    tokenSuffix: '}$'

结果是:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSection>
        <section name="entityFramework"/>
    </configSection>
    <connectionStrings>
        <add name="DefaultConnection" connectionString="Data Source=(LocalDB)\LocalDB;FileName=Local.mdf"/>
    </connectionStrings>
    <appSettings>
        <add key="ClientValidationEnabled" value="true"/>
        <add key="UnobstructiveJavascriptEnabled" value="true"/>
        <add key="AdminUserName" value="__AdminUserName__"/>


        <add key="AdminPassword" value="fake password"/>


    </appSettings>
    <entityFramework>
        <defaultConnectionFactory type="System.Data.Entity.LocalDbConnectionFactory">
            <parameters/>
        </defaultConnectionFactory>
        <providers>
            <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer"/>
        </providers>
    </entityFramework>    
    <system.webServer>        
        <security>
            <requestFiltering>


                <requestLimits maxAllowedContentLength="25"/>


            </requestFiltering>
        </security>
    </system.webServer>