2011-01-20 23 views
28

目標是讓TFS構建和部署2+個不同的配置,並讓web.config轉換文件在其輸出中包含預期的內容。這在ASP.NET MVC項目中。TFS不按預期方式構建轉換web.config

alt text

Web.Debug.Config - see on PasteBin
Web.Release.Config - see on PasteBin

的2個轉化配置文件有其生成操作設置爲無。這已被修改,因爲所有3個web。*。config文件都包含在部署中。

正確配置TFS以構建和部署兩種配置。如預期的那樣,它部署到2個丟棄位置。在構建定義中沒有指定MSBuild參數。

alt text

問題:2.構建和部署Web站點具有相同的web.config文件。基本上就好像轉換後的文件不存在一樣。

預計:指定的更改(xdt:Transform="Replace"xdt:Transform="Remove")將出現在web.config文件中。

如何配置項目或TFS以確保處理web.config轉換並將其輸出部署到正確的部署位置?我還能檢查/修改什麼?

  • 已確認轉換效果不錯 - Vishal's Joshit's tutorial with the MSBuild on the command line輸出正確轉換!
  • 對於任何後期構建或部署,.csproj都沒有進行任何修改。
  • 是否有任何xdt屬性被濫用或丟失?
  • 在構建定義中沒有指定MSBuild參數。
  • web.config構建操作是否設置正確?
  • 我們沒有使用網絡部署包或任何東西。只是希望在稍後的日期將這些輸出複製到他們的各種網絡服務器位置。

如果我錯過了任何重要信息,請留下評論,我會加入更多相關信息!

回答

4

這是我一直在使用的。目前的TransformXml任務有一個文件打開的bug。閱讀更多here

您可以調用此任務並針對您正在使用的每個配置進行部署。

<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> 
+0

感謝您的支持。在這個階段我有點困惑; XML的這個片段放在哪裏?任何其他修改的TFS構建定義,以適應? –

+0

你對MSBuild的熟悉程度如何?您可以將此目標放置在您的構建定義中,也可以從「BeforeDropBuild」目標中調用它。 – Danny

+0

-1:他爲什麼要用這個?他正在使用TFS 2010. –

8

TFS Team Build 2010不會自動轉換您的Web.configs。您需要將自定義工作流程活動添加到構建流程模板才能完成此任務。

Edwald Hofman有一個很好的博客,解釋瞭如何修改TFS 2010構建過程模板,所以我不會在這裏深入討論。

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

後你弄清楚如何自定義活動添加到您的構建過程的模板,添加以下活動爲您的工作流程,我添加了活動之後「文件拖放到放置位置」。它利用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 
} 

您需要將它傳遞droplocation的工作流程。當您將其添加到工作流程中時,右鍵單擊該活動,然後轉到屬性,然後將「DropLocation」(VB表達式)粘貼到屬性「BinaryLocation」中。注意:您需要創建一個BuildEngineStub類實現IBuildEngine接口以使用MSBuild任務。這是我用的

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 
    } 
+1

其他選項是一個好得多的方法,並且更容易設置 –

+5

不贊同。我寧願將這個改變改爲我的構建過程模板一次(對於所有使用的解決方案),而不是編輯我創建的每個.proj文件或構建定義。 – Danny

+1

Hrm,好點,從來沒有想過......不可否認,我是通過TFS和構建模板構建新手的,但這一切似乎都很令人沮喪。似乎我們不得不離開我們的方式去開發/維​​護腳本來實現已經存在於msbuild中的功能。 –

0

Drop實際上並沒有做任何轉換。您需要將/p:DeployOnBuild=True添加到MSBuild參數中。

這將創建一個包,然後可以通過命令行或使用IIS導入應用程序嚮導來安裝網站。

如果你之後是直接發佈多個配置,這是一個整體的其他故事,那就是我偶然發現這篇文章。

0

儘量不要設置構建平臺 - 在ItemToBuild basicly刪除「任何CPU」,然後選擇的MSBuild平臺爲「自動」

19

以前我一直在做類似的其他答案的東西。但是,我剛發現似乎是解決這個問題的更好方法。只需在你的MSBuild參數中添加「/ p:UseWPP_CopyWebApplication = true/p:PipelineDependsOnBuild = false」即可。我剛剛在我的一個TFS構建中嘗試了這一點,它工作得很好。

我在這裏發現了這個偉大的小費:http://www.andygeldman.com/index.php/2011/10/web-and-app-config-transformations-with-tfs-build

+1

更簡單的解決方案!即使在設置TFS構建以構建多個配置(調試和發佈都轉換得很好)時也能完美工作 – Shawson

+0

正是我需要的!謝謝你的提示。 –

相關問題