web-dev-qa-db-ja.com

TFSビルドがweb.configを期待どおりに変換しない

目標は、TFSで2つ以上の異なる構成をビルドおよびデプロイし、web.config変換ファイルに目的のコンテンツを出力に含めることです。これはASP.NETMVCプロジェクトにあります。

alt text

Web.Debug.Config -- Pastebinを参照
Web.Release.Config -- Pastebinを参照

変換された2つの構成ファイルのビルドアクションはNoneに設定されています。 3つのweb。*。configファイルすべてがデプロイメントに含まれていたため、これは変更されました。

TFSは、両方の構成を構築および展開するように正しく構成されています。期待どおりに2つのドロップ場所に展開されます。ビルド定義で指定されたMSBuild引数はありません。

alt text

問題:構築およびデプロイされた2つのWebサイトに同じweb.configファイルがあります。基本的には、変換されたファイルが存在しなかったかのようです。

期待される:指定された変更(xdt:Transform="Replace"およびxdt:Transform="Remove")はweb.configファイルに存在します。

プロジェクトまたはTFSを構成して、web.config変換が処理され、それらの出力が正しい展開場所に展開されるようにするにはどうすればよいですか?他に何をチェック/変更できますか?

  • 変換が適切であることを確認しました--- コマンドラインにMSBuildを使用したVishalのJoshitのチュートリアル 正しい変換を出力します!
  • ビルド後または展開のために.csprojに変更は加えられていません。
  • xdt属性が誤用されているか、欠落していますか?
  • ビルド定義で指定されたMSBuild引数はありません。
  • Web.configビルドアクションは正しく設定されていますか?
  • Webデプロイメントパッケージなどは使用していません。後日、これらの出力をさまざまなWebサーバーの場所にxcopyすることを期待しているだけです。

重要な情報が不足している場合は、コメントを残してください。関連する情報があれば追加します。

30
p.campbell

以前、私は他の答えと同じようなことをしていました。しかし、私はこの問題のより良い解決策と思われるものを見つけました。 MSBuild引数に「/ p:UseWPP_CopyWebApplication = true/p:PipelineDependsOnBuild = false」を追加するだけです。 TFSビルドの1つでこれを試してみましたが、問題なく動作します。

私はここでこの素晴らしいヒントを見つけました: http://www.andygeldman.com/index.php/2011/10/web-and-app-config-transformations-with-tfs-build

21
Bart Sipes

TFS Team Build 2010は、Web.configを自動的に変換しません。これを実現するには、ビルドプロセステンプレートにカスタムワークフローアクティビティを追加する必要があります。

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」(VB式)をプロパティ「BinaryLocation」に貼り付けます。

注:MSBuildタスクを使用するには、IBuildEngineインターフェイスを実装するBuildEngineStubクラスを作成する必要があります。これが私が使ったものです

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
    }
8
Danny

これが私が使ってきたものです。現在のTransformXmlタスクには、ファイルを開いたままにするバグがあります。続きを読む ここ

このタスクを呼び出して、作業している構成ごとにデプロイできます。

<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>
4
Danny

ビルドプラットフォームを設定しないようにしてください。基本的に、ItemToBuildの「AnyCPU」を削除し、MSBuildプラットフォームを「Auto」として選択します。

0
ZERO

ドロップは実際には変換を行いません。必要なのは、MSBuild引数に/p:DeployOnBuild=Trueを追加することです。

これにより、コマンドラインまたはIISアプリケーションのインポートウィザード)を使用してWebサイトをインストールするために使用できるパッケージが作成されます。

あなたが求めているのが、まったく別の話である複数の構成を直接公開することである場合、それが私がこの投稿に出くわした方法です。

0
Kn0wit