Manual config transform as TFS build step

702 views Asked by At

I have a solution file that contains a web site project (among other project types). It uses a publish profile for deployment and I'm trying to move the entire thing to TFS (2015) to automate the build and deploy process. As stated here I cannot manage the build configuration since it is a web site project and consequently cannot use the Web.config Transformation feature.

I'd like to execute some sort of transform, perhaps as a build step. I can manually create and maintain the web.release.config file but don't know how to manually transform it. Does an XLST file exist to transform it outside of Visual Studio (e.g. a cmd build step to call an XSLT processor)?

Addendum: converting to a web project would most definitely fix the issue but not a solution for me as that would require involvement from the remote contractors contributing to our code base - a TFS build-level solution is the only thing I'm looking for.

2

There are 2 answers

0
mlhDev On BEST ANSWER

Since my actual transforms were relatively simple I developed this XSL transform:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    exclude-result-prefixes="msxsl">
  <xsl:output method="xml" indent="yes"/>
  <xsl:variable name="xformPath">web.Prod.config</xsl:variable>
  <xsl:variable name="xform" select="document($xformPath)"></xsl:variable>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template name="output-transform">
    <xsl:param name="xformNode" />
    <xsl:variable name="key" select="@key" />
    <xsl:choose>
      <xsl:when test="$xformNode">
        <xsl:copy-of select="$xformNode" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:copy>
          <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template match="/configuration/appSettings/add">
    <xsl:variable name="key" select="@key" />
    <xsl:call-template name="output-transform">
      <xsl:with-param name="xformNode" select="$xform/configuration/appSettings/add[@key=$key]" />
    </xsl:call-template>
  </xsl:template>

  <xsl:template match="/configuration/connectionStrings/add">
    <xsl:variable name="name" select="@name" />
    <xsl:call-template name="output-transform">
      <xsl:with-param name="xformNode" select="$xform/configuration/connectionStrings/add[@name=$name]" />
    </xsl:call-template>
  </xsl:template>

  <xsl:template match="/configuration/system.web/customErrors">
    <xsl:call-template name="output-transform">
      <xsl:with-param name="xformNode" select="$xform/configuration/system.web/customErrors" />
    </xsl:call-template>
  </xsl:template>
</xsl:stylesheet>

That has some obvious shortcomings,

  • Items to be replaced must be manually defined
  • Replaces with the entire element, not only the specified attributes
  • Does not maintain children elements (e.g. I tried to change system.web/compilation@debug to false but I lost all my system.web/compilation/assemblies entries)

I plan to add this in a Command Line step, between my Visual Studio Build step and Copy Files step, and call either msxsl.exe or Saxon's HE transform engine.

0
Cece Dong - MSFT On

As @MrHinsh mentioned in comment, it's suggested to create a Web Application project instead of a Web Site project, as Web Site project doesn't have web.release.config file by default, while a Web Application project has.

To replace tokens in files with variable values, you can add a Replace Tokens task in your build definition.

enter image description here