TFS Build не преобразует web.config, как ожидалось - PullRequest
29 голосов
/ 20 января 2011

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

alt text

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

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

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

alt text

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

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

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

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

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

Ответы [ 5 ]

20 голосов
/ 30 октября 2012

Раньше я делал что-то похожее на другие ответы. Тем не менее, я просто нашел то, что кажется лучшим решением этой проблемы. Просто добавьте «/ 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.

8 голосов
/ 06 сентября 2011

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 Expression) в свойство «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
    }
4 голосов
/ 20 января 2011

Вот что я использовал. В текущей задаче 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>
0 голосов
/ 23 марта 2012

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

0 голосов
/ 24 января 2012

Дроп на самом деле не делает никаких преобразований.Вам нужно добавить /p:DeployOnBuild=True в аргументы MSBuild.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...