代码之家  ›  专栏  ›  技术社区  ›  grenade

TFS 2010或msbuild中的触发器配置转换

  •  16
  • grenade  · 技术社区  · 15 年前

    我正试图利用 configuration transformations

    我需要一种方法来告诉TFS构建代理执行转换。我有点希望它在发现配置转换文件(web.qa-release.config、web.production-release.config等)后能够工作。但事实并非如此。

    我有一个TFS构建定义,用于构建正确的配置(qa版本、生产版本等),我有一些特定的.proj文件,这些文件在这些定义中构建,并且包含一些特定于环境的参数,例如:

    <PropertyGroup Condition=" '$(Configuration)'=='production-release' ">
        <TargetHost Condition=" '$(TargetHost)'=='' ">qa.web</TargetHost>
        ...
    </PropertyGroup>
    <PropertyGroup Condition=" '$(Configuration)'=='qa-release' ">
        <TargetHost Condition=" '$(TargetHost)'=='' ">production.web</TargetHost>
        ...
    </PropertyGroup>
    

    我从输出中知道正在构建正确的配置。现在我只需要学习如何触发配置转换。是否有一些hocus pocus可以添加到构建中的final.proj中,以启动转换并吹走单个转换文件?

    6 回复  |  直到 15 年前
        1
  •  1
  •   Wallace Breza    14 年前

    您需要做的只是设置在TFS构建定义中应该使用的配置。

    1. Goto团队探索者>建立
    2. 编辑生成定义(或创建新的)

    在我的例子中,我专门为CI设置了一个配置,然后执行正确的web.config转换。确保您已经添加了“CI”转换文件,并且应该准备就绪。

        2
  •  11
  •   Community SushiHangover    4 年前

    <Target Name="AfterBuild" Condition="$(IsAutoBuild)=='True'"> 
      <ItemGroup> 
             <DeleteAfterBuild Include="$(WebProjectOutputDir)\Web.*.config" /> 
      </ItemGroup> 
      <TransformXml Source="Web.config" Transform="$(ProjectConfigTransformFileName)" Destination="$(WebProjectOutputDir)\Web.config"/> 
      <Delete Files="@(DeleteAfterBuild)" />
    </Target> 
    

    那你只需要加上 /p:IsAutoBuild="True"

    这将迫使TFS 2010在TFS进行构建时在web.config上进行转换。

    有关更多详细信息,请访问 Kevin Daly's Blog .

        3
  •  6
  •   Rohan Singh    14 年前

    首先,将此导入添加到TFSBuild.proj:

    <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
    

    <Target Name="BeforeDropBuild">
      <TransformXml Source="$(SolutionRoot)\MySite\Web.config"
        Transform="$(SolutionRoot)\MySite\Web.QA.config"
        Destination="$(OutDir)\_PublishedWebsites\MySite\Web.QA.config.transformed" />
    </Target>
    

    然后,您可以将Web.QA.config.transformed复制到需要的任何地方。

        4
  •  6
  •   ShadowChaser    13 年前

    默认情况下,对于命令行和TFS生成,在Visual Studio 2010中添加到网站项目的web.config转换功能被禁用。

    有两种相对简单的解决方案:

    :编辑生成定义并将以下内容添加到“MSBuild Arguments”字段:

    /p:UseWPP_CopyWebApplication=true /p:PipelineDependsOnBuild=false
    

    选择2

    <?xml version="1.0" encoding="utf-8"?>
    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <PropertyGroup>
        <UseWPP_CopyWebApplication>True</UseWPP_CopyWebApplication>
        <PipelineDependsOnBuild>False</PipelineDependsOnBuild>
      </PropertyGroup>
    </Project>
    

    右键单击您的网站并选择“卸载项目”。在卸载的项目上单击鼠标右键,然后选择“编辑”。滚动到项目文件的底部并查找以下行:

    <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
    <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
    

    这些线是连接C#和Web项目构建过程的地方。立即向自定义生成扩展名(目标文件)插入导入 之前 CSharp导入:

    <Import Project="ProjectName.custom.targets"/>
    <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
    <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
    

    我还建议查看“wpp目标”-如果您使用特定名称“ProjectName.wpp.targets”命名另一个MSBuild文件,则可以控制整个网站发布过程。在复制发布的网站输出时,我们使用它删除-vsdoc javascript文档文件:

    <ItemGroup>
      <ExcludeFromPackageFiles Include="Scripts\**\*-vsdoc.js;Resources\Scripts\**\-vsdoc.js">
        <FromTarget>Project</FromTarget>
      </ExcludeFromPackageFiles>
    </ItemGroup>
    

    综上所述,您最好将生产web.configs完全从构建中删除。我们将转换直接放在生产部署机器上,并在部署应用程序时使用powershell进行转换。

        5
  •  5
  •   captain numerica    13 年前

    这里有一个更简单的答案。:)

    http://social.msdn.microsoft.com/Forums/en-US/tfsbuild/thread/d5c6cc7b-fbb1-4299-a8af-ef602bad8898/

    从链接(如果它被移动/404/etc):

    下面是我如何解决这个问题的。钥匙 要在上编辑*.csproj文件 网站,并将以下内容添加到 结束上面的评论)。这是给你的 我们的网站建设项目团队

    <Target Name="AfterBuild">
        <TransformXml Condition="Exists('$(OutDir)\_PublishedWebsites\$(TargetName)')"
                      Source="Web.config"
                      Transform="$(ProjectConfigTransformFileName)"
                      Destination="$(OutDir)\_PublishedWebsites\$(TargetName)\Web.config" />
    </Target>
    

    要保留web.debug.config, web.release.config等。。。从存在 发布请确保设置“生成” 每个配置转换 web.config应该有一个“Build”

    编辑csproj文件的一种简单方法 适用于Visual Studio 2010“或 “生产力电动工具”扩展 到Visual Studio 2010,可从 VisualStudioGallery。一旦 单击解决方案中的项目 然后选择“卸载项目”。那你呢 可以再次右键单击并选择 “编辑…”编辑csproj文件XML 直接的。那么当你做得恰到好处的时候 项目”。

        6
  •  1
  •   gislikonrad    13 年前

    要在工作流中执行此操作,必须创建自定义活动。这方面有一篇很好的文章 here

    .Net 4 )和参考 Microsoft.Build.Framework 来自GAC,然后 从…起 (%程序文件(x86)%。

    首先,有一个存根:

    internal class BuildEngineStub : IBuildEngine
    {
        public bool BuildProjectFile(string projectFileName, string[] targetNames, System.Collections.IDictionary globalProperties, System.Collections.IDictionary targetOutputs)
        {
            throw new NotImplementedException();
        }
    
        public int ColumnNumberOfTaskNode
        {
            get { throw new NotImplementedException(); }
        }
    
        public bool ContinueOnError
        {
            get { throw new NotImplementedException(); }
        }
    
        public int LineNumberOfTaskNode
        {
            get { throw new NotImplementedException(); }
        }
    
        public void LogCustomEvent(CustomBuildEventArgs e)
        {
        }
    
        public void LogErrorEvent(BuildErrorEventArgs e)
        {
        }
    
        public void LogMessageEvent(BuildMessageEventArgs e)
        {
        }
    
        public void LogWarningEvent(BuildWarningEventArgs e)
        {
        }
    
        public string ProjectFileOfTaskNode
        {
            get { throw new NotImplementedException(); }
        }
    }
    

    [BuildActivity(HostEnvironmentOption.Agent)]
    public sealed class WebConfigTransform : CodeActivity
    {
        private const string WEB_CONFIG = "Web.config";
        private const string WEB_CONFIG_TRANSFORM_FORMAT = "Web.{0}.config";
    
        private IBuildEngine _buildEngine { get { return new BuildEngineStub(); } }
    
        [RequiredArgument]
        public InArgument<string> TransformationName { get; set; }
        [RequiredArgument]
        public InArgument<string> SourceFolder { get; set; }
        [RequiredArgument]
        public InArgument<string> DestinationFolder { get; set; }
    
        protected override void Execute(CodeActivityContext context)
        {
            var transformationName = context.GetValue(this.TransformationName);
            var sourceFolder = context.GetValue(this.SourceFolder);
            var destinationFolder = context.GetValue(this.DestinationFolder);
    
            var source = Path.Combine(sourceFolder, WEB_CONFIG);
            var destination = Path.Combine(destinationFolder, WEB_CONFIG);
            var destinationbackup = string.Format("{0}.bak", destination);
            var transform = Path.Combine(sourceFolder, string.Format(WEB_CONFIG_TRANSFORM_FORMAT, transformationName));
    
            if(!File.Exists(source))
                throw new ArgumentException("Web.config file doesn't exist in SourceFolder");
            if (!File.Exists(transform))
                throw new ArgumentException("Web.config transformation doesn't exist in SourceFolder");
            if (File.Exists(destination))
            {
                File.Copy(destination, destinationbackup);
                File.Delete(destination);
            }
    
            var transformation = new TransformXml();
            transformation.Source = new TaskItem(source);
            transformation.Destination = new TaskItem(destination);
            transformation.Transform = new TaskItem(transform);
            transformation.BuildEngine = _buildEngine;
    
            if (transformation.Execute())
            {
                File.Delete(destinationbackup);
            }
            else
            {
                File.Copy(destinationbackup, destination);
                File.Delete(destinationbackup);
            }
        }
    }
    

    原因是什么 建筑引擎主题 转换XML

    你唯一需要注意的是 函数将锁定源配置文件,直到生成过程完成。