Подтвердить что ты не робот

TFS Build не преобразует web.config, как ожидалось

Цель состоит в том, чтобы создавать и развертывать TFS 2+ разных конфигураций, а файлы преобразования web.config включают в себя предназначенный контент в своем выпуске. Это в проекте ASP.NET MVC.

alt text

Web.Debug.Config - см. в PasteBin.
Web.Release.Config - см. В PasteBin

У 2 преобразованных конфигурационных файлов установлено значение Build Action равным None. Это было изменено, поскольку в развертывание включены все 3 файла конфигурации. *. Config.

TFS правильно настроена для создания и развертывания обеих конфигураций. Он разворачивается в 2 места падения, как ожидалось. Аргументы MSBuild не определены в определении сборки.

alt text

Проблема. 2 встроенных и развернутых веб-сайта имеют один и тот же файл web.config. В основном это как будто преобразованные файлы не существовали.

Ожидаемый: указанные изменения (xdt:Transform="Replace" и xdt:Transform="Remove") будут присутствовать в файлах web.config.

Как вы можете настроить свой проект или TFS для обеспечения преобразования преобразований web.config, а их выходы развернуты в правильные места развертывания? Что еще я могу проверить/изменить?

  • Подтвердили, что преобразования хороши - Учебник Vishal Joshit с MSBuild в командной строке выводит правильные преобразования!
  • Никаких изменений в .csproj для каких-либо пост-сборки или развертывания не было.
  • Используются ли какие-либо атрибуты xdt неправильно или отсутствуют?
  • В определении сборки отсутствуют аргументы MSBuild.
  • Правильно ли установлены правила сборки Web.config?
  • Мы не используем пакеты веб-развертывания или что-то еще. Просто ожидая xcopy этих выходов к их различным местоположениям веб-серверов позднее.

Если мне не хватает какой-либо важной информации, оставьте комментарий, и я включу любую более важную информацию!

4b9b3361

Ответ 1

Раньше я делал что-то похожее на другие ответы. Тем не менее, я просто нашел то, что кажется лучшим решением этой проблемы. Просто добавьте "/p: UseWPP_CopyWebApplication = true/p: PipelineDependsOnBuild = false" к вашим аргументам MSBuild. Я просто попробовал это на одной из моих сборников TFS, и все работает отлично.

Я нашел этот замечательный совет здесь: http://www.andygeldman.com/index.php/2011/10/web-and-app-config-transformations-with-tfs-build.

Ответ 2

Команда TFS Team Build 2010 автоматически не преобразует ваши Web.configs. Чтобы выполнить это, вам нужно добавить пользовательский рабочий процесс к шаблону процесса сборки.

У Эдвальда Хофмана есть хороший блог, в котором объясняется, как изменить TFS 2010 Build Process Templates, поэтому я не буду углубляться в это.

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

После того, как вы выясните, как добавить пользовательские действия к шаблону процесса сборки, добавьте в свой рабочий процесс следующие действия. Я добавил активность после "Drop Plles to Drop Location". Он использует сборку 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
    }

Ответ 3

Вот что я использовал. Текущая задача 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

Падение фактически не преобразуется. Вам нужно добавить /p:DeployOnBuild=True в аргументы MSBuild.

Это создаст пакет, который затем можно будет использовать для установки веб-сайта либо через командную строку, либо с помощью мастера импорта приложений IIS.

Если вам нужно опубликовать более чем одну конфигурацию, это целая другая история, и именно так я наткнулся на этот пост.

Ответ 5

Попытайтесь не устанавливать платформу сборки - в основном удалить "Любой процессор" в ItemToBuild и выбрать платформу MSBuild как "Авто"