简体   繁体   English

TFS Build未按预期转换web.config

[英]TFS Build not transforming web.config as expected

The goal is to have TFS build and deploy 2+ different configurations, and have the web.config transform files include the intended content in their output. 目标是让TFS构建并部署2个以上的不同配置,并让web.config转换文件在其输出中包含预期的内容。 This in an ASP.NET MVC project. 这是在ASP.NET MVC项目中。

替代文字

Web.Debug.Config - see on PasteBin . Web.Debug.Config - 请参阅PasteBin
Web.Release.Config - see on PasteBin Web.Release.Config - 请参阅PasteBin

The 2 transformed config files have their Build Action set to None . 2个转换后的配置文件将其Build Action设置为None This was modified because all 3 web.*.config files were being included in the deployment. 这是因为所有3个web。*。配置文件都包含在部署中。

TFS is configured correctly to build and deploy both configurations. 正确配置TFS以构建和部署这两种配置。 It deploys to the 2 drop locations as expected. 它按预期部署到2个丢弃位置。 There are no MSBuild Arguments specified in the build definition. 在构建定义中没有指定MSBuild参数。

替代文字

Problem : The 2 built and deployed web sites have the same web.config file. 问题 :2个构建和部署的Web站点具有相同的web.config文件。 Basically it's as if the transformed files did not exist. 基本上就好像转换后的文件不存在一样。

Expected : the changes specified ( xdt:Transform="Replace" and xdt:Transform="Remove" ) would be present in the web.config files. 预期 :指定的更改( xdt:Transform="Replace"xdt:Transform="Remove" )将出现在web.config文件中。

How can you configure your project or TFS to ensure the web.config transformations are processed and their outputs deployed to the correct deployment locations? 如何配置项目或TFS以确保处理web.config转换并将其输出部署到正确的部署位置? What else can I check/modify? 我还可以检查/修改什么?

  • Have confirmed that the transformations are good -- Vishal's Joshit's tutorial with the MSBuild on the command line output the correct transformations! 确认转换是好的 - 在命令行上使用MSBuild的Vishal的Joshit教程输出正确的转换!
  • No modifications have been made to the .csproj for any post-build or deployment. 对于任何后期构建或部署,都没有对.csproj进行任何修改。
  • Are any xdt attributes being misused or missing? 是否有任何xdt属性被滥用或丢失?
  • There are no MSBuild Arguments specified in the build definition. 在构建定义中没有指定MSBuild参数。
  • Are the web.config Build Actions set correctly? web.config构建操作是否设置正确?
  • We're not using web deployment packages or anything. 我们没有使用Web部署包或任何东西。 Simply expecting to xcopy these outputs over to their various webserver locations at a later date. 只需要将这些输出xcopy复制到以后的各个Web服务器位置。

If I'm missing any important information, please leave a comment, and I'll include any more relevant information! 如果我遗漏了任何重要信息,请发表评论,我会提供更多相关信息!

Previously I had been doing something similar to the other answers. 以前我一直在做类似于其他答案的事情。 However, I just found what seems to be a better solution to this problem. 但是,我刚刚发现了解决这个问题的更好方法。 Just add "/p:UseWPP_CopyWebApplication=true /p:PipelineDependsOnBuild=false" to your MSBuild arguments. 只需将“/ p:UseWPP_CopyWebApplication = true / p:PipelineDependsOnBuild = false”添加到MSBuild参数中即可。 I just tried this out on one of my TFS builds and it works just fine. 我刚刚在我的一个TFS版本上尝试了这个,它运行得很好。

I found this great tip here: http://www.andygeldman.com/index.php/2011/10/web-and-app-config-transformations-with-tfs-build . 我在这里找到了这个很棒的提示: http//www.andygeldman.com/index.php/2011/10/web-and-app-config-transformations-with-tfs-build

TFS Team Build 2010 does not automatically transform your Web.configs. TFS Team Build 2010不会自动转换您的Web.configs。 You need to add a custom workflow activity to your build process template to accomplish this. 您需要向构建过程模板添加自定义工作流活动才能完成此操作。

Edwald Hofman has a good blog that explains how to modify TFS 2010 Build Process Templates, so I won't go in depth on that here. Edwald Hofman有一个很好的博客,解释了如何修改TFS 2010构建过程模板,所以我不会在这里深入探讨。

http://www.ewaldhofman.nl/post/2010/04/29/Customize-Team-Build-2010-e28093-Part-4-Create-your-own-activity.aspx http://www.ewaldhofman.nl/post/2010/04/29/Customize-Team-Build-2010-e28093-Part-4-Create-your-own-activity.aspx

After you figure out how to add custom activities to your build process template, add the following activity into your workflow, I added the activity after "Drop FIles to Drop Location". 在弄清楚如何将自定义活动添加到构建过程模板后,将以下活动添加到工作流程中,我在“删除文件到删除位置”之后添加了活动。 It utilizes the Microsoft.Web.Publishing.Tasks assembly (located: C:\\Program Files (x86)\\MSBuild\\Microsoft\\VisualStudio\\v10.0\\Web ) to perform the transformations: 它利用Microsoft.Web.Publishing.Tasks程序集(位于: C:\\Program Files (x86)\\MSBuild\\Microsoft\\VisualStudio\\v10.0\\Web )来执行转换:

/// <summary>
/// Transforms configuration files using TransformXml
/// </summary>
[BuildActivity(HostEnvironmentOption.All)]
public sealed class WebConfigTransform : CodeActivity
{
    #region Public Properties

    /// <summary>
    /// The binaries folder
    /// </summary>
    [RequiredArgument]
    public InArgument<string> BinariesLocation { get; set; }

    #endregion

    #region Overrides of CodeActivity

    /// <summary>
    /// When implemented in a derived class, performs the execution of the activity.
    /// </summary>
    /// <param name="context">The execution context under which the activity executes.</param>
    protected override void Execute(CodeActivityContext context)
    {
        var binariesFolder = context.GetValue(BinariesLocation);

        foreach (var sourceFolder in Directory.GetDirectories(Path.Combine(binariesFolder, "_PublishedWebsites")))
        {
            var sourceFile = Path.Combine(sourceFolder, "Web.config");
            if (File.Exists(sourceFile))
            {
                var filesToTransform = Directory.GetFiles(sourceFolder, "Web.*.config");


                foreach (var fileToTransform in filesToTransform)
                {

                    var tempSourceFile = Path.GetTempFileName();
                    var tempTransformFile = Path.GetTempFileName();

                    File.Copy(sourceFile, tempSourceFile, true);
                    File.Copy(fileToTransform, tempTransformFile, true);

                    var transformation = new TransformXml
                    {
                        BuildEngine = new BuildEngineStub(),
                        Source = tempSourceFile,
                        Transform = tempTransformFile,
                        Destination = fileToTransform
                    };

                    transformation.Execute();
                }
            }
        }
    }

    #endregion
}

You will need to pass it the droplocation in the work flow. 您需要在工作流程中传递droplocation。 When you add it the the work flow, right click on the activity, then go to properties, and paste "DropLocation" (VB Expression) into the property "BinaryLocation" 当您添加工作流程时,右键单击活动,然后转到属性,并将“DropLocation”(VB Expression)粘贴到属性“BinaryLocation”中

NOTE: You'll need to create a BuildEngineStub class that implements the IBuildEngine interface in order to use the MSBuild task. 注意:您需要创建一个实现IBuildEngine接口的BuildEngineStub类,以便使用MSBuild任务。 Here is what I used 这是我用的

public class BuildEngineStub : IBuildEngine
{
        #region IBuildEngine Members

        public bool BuildProjectFile(string projectFileName, string[] targetNames,
                                     IDictionary globalProperties,
                                     IDictionary targetOutputs)
        {
            throw new NotImplementedException();
        }

        public int ColumnNumberOfTaskNode
        {
            get { return 0; }
        }

        public bool ContinueOnError
        {
            get { return false; }
        }

        public int LineNumberOfTaskNode
        {
            get { return 0; }
        }

        public string ProjectFileOfTaskNode
        {
            get { return ""; }
        }

        public void LogCustomEvent(CustomBuildEventArgs e)
        {
            Console.WriteLine("Custom: {0}", e.Message);
        }

        public void LogErrorEvent(BuildErrorEventArgs e)
        {
            Console.WriteLine("Error: {0}", e.Message);
        }

        public void LogMessageEvent(BuildMessageEventArgs e)
        {
            Console.WriteLine("Message: {0}", e.Message);
        }

        public void LogWarningEvent(BuildWarningEventArgs e)
        {
            Console.WriteLine("Warning: {0}", e.Message);
        }

        #endregion
    }

Here's what I've been using. 这是我一直在使用的。 The current TransformXml task has a bug where it leaves files open. 当前的TransformXml任务有一个文件打开的错误。 Read more here . 在这里阅读更多。

You can call this task and deploy for each configuration you're working with. 您可以调用此任务并为您正在使用的每个配置进行部署。

<Target Name="TransformWebConfig">

    <PropertyGroup>
        <_tempSourceFile>$([System.IO.Path]::GetTempFileName())</_tempSourceFile>
        <_tempTransformFile>$([System.IO.Path]::GetTempFileName())</_tempTransformFile>
    </PropertyGroup>

    <Copy SourceFiles="$(_websiteDirectory)\Web.config" DestinationFiles="$(_tempSourceFile)"/>
    <Copy SourceFiles="$(_websiteDirectory)\Web.$(_transformConfiguration).config" DestinationFiles="$(_tempTransformFile)"/>

    <MSBuild.Community.Tasks.Attrib Files="$(_websiteDirectory)\Web.config" ReadOnly="false" />

    <TransformXml Source="$(_tempSourceFile)"
                  Transform="$(_tempTransformFile)"
                  Destination="$(_websiteDirectory)\Web.config"
                  StackTrace="false" />
</Target>

The Drop does not actually do any transforming. Drop实际上并没有进行任何转换。 What you need is to add /p:DeployOnBuild=True to the MSBuild Arguments. 您需要的是将/p:DeployOnBuild=True到MSBuild参数。

This will create a Package that can then be used to install the website either via command line or using the IIS Import Application wizard. 这将创建一个包,然后可以通过命令行或使用IIS导入应用程序向导来安装网站。

If what you are after is to directly publish more than one configuration that is a whole other story and that is how I stumbled onto this post. 如果您追求的是直接发布多个配置,这是另一个故事,这就是我偶然发现这篇文章的方式。

尽量不要设置构建平台 - 基本删除ItemToBuild中的“任何CPU”并选择MSBuild平台为“Auto”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM