Каков наилучший способ заставить TFS выводить каждый проект в свой собственный каталог?
я помещаю большую кодовую базу в Team Foundation Server. Я хотел бы, чтобы процесс сборки создал "готовую к развертыванию" сборку наших проектов.
обычный способ, которым мы это делаем, заключается в том, чтобы каждый вывод проекта был в своей собственной папке. Так, например, мы заканчиваем с чем-то вроде
C:project1
assembly1.dll
assembly2.dll
project1.exe
project1.exe.config
C:project2
assembly2.dll
assembly3.dll
project2.exe
project2.exe.config
C:project3
assembly1.dll
assembly3.dll
project3.exe
project3.exe.config
который является то, как нам это нравится.
TFS, однако, похоже, хочет вставить все в один и тот же каталог.
C:output
assembly1.dll
assembly2.dll
assembly3.dll
project1.exe
project1.exe.config
project2.exe
project2.exe.config
project3.exe
project3.exe.config
, которые, хотя это экономит некоторое количество дискового пространства (сборки есть только один раз каждый) не так, как мы этого хотим.
каков наилучший способ указать, где TFS / MSBuild должен поместить выходные файлы? Нужно ли мне редактировать файлы sln / csproj индивидуально, чтобы достичь этого, или я могу сделать это в TFSBuild.файл proj? (т. е. в MSBuild файл)
11 ответов:
Я только что написал в блоге другой метод здесь:
http://mikehadlow.blogspot.com/2009/06/tfs-build-publishedwebsites-for-exe-and.html но если вы не можете потрудиться перейти по ссылке, вот она в полном объеме:
обычно рекомендуется собирать весь код под контролем вашей команды в одном uber-решении, как описано в этом шаблоне и практике PDF, Team Development with TFS Guide. Если вы затем настроите сервер сборки TFS для создания этого решение, это поведение по умолчанию-поместить вывод сборки в одну папку "Release".
любые проекты веб-приложений в вашем решении также будут выведены в папку с именем _PublishedWebsites\. Это очень приятно, потому что это означает, что вы можете просто программы развертывания веб-приложения.
к сожалению, нет аналогичного поведения по умолчанию для других типов проектов, таких как WinForms, консоль или библиотека. Было бы очень хорошо, если мы могли бы _publishedapplications\ sub папка с выводом любого выбранного проекта(ов). К счастью, это не так сложно сделать.
способ работы _PublishedWebsites довольно прост. Если вы посмотрите на файл проекта вашего веб-приложения, вы заметите импорт внизу:
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" />на моей машине свойство MSBuildExtensionsPath имеет значение C:\Program файлы\MSBuild, если мы откроем Microsoft.Значение webapplication.целевой файл мы видим, что это довольно простой MSBuild файл, который распознает, когда сборка не является сборкой рабочего стола, т. е. это сборка TFS, и копирует вывод в:
$(OutDir)_PublishedWebsites$(MSBuildProjectName)Я просто скопировал Micrsoft.Значение webapplication.целевой файл, поместите его в систему управления версиями с относительным путем от моих файлов проекта и изменил _PublishedWebsites на _PublishedApplications и переименовал файл CI.исполняемый.цели. Для каждого проекта, который я хочу вывести в _PublishedApplications, я просто добавил этот импорт в нижней части проекта файл:
<Import Project="<your relative path>\CI.exe.targets" />вы можете редактировать CI.исполняемый.цели (или как вы хотите это назвать), чтобы сделать ваши ставки. В моем случае единственным изменением до сих пор является добавление нескольких строк для копирования приложения.конфигурационный файл:
<Copy SourceFiles="$(OutDir)$(TargetFileName).config" DestinationFolder="$(WebProjectOutputDir)\bin" SkipUnchangedFiles="true" />есть много вещей, в Microsoft.Значение webapplication.целей, относящиеся только к веб-приложениям и могут быть удалены для других типов проектов, но я оставлю это в качестве упражнения для читателя.
TFS 2012+
мне нравится это решение...
редактировать определение построения. В разделе процесс установите
MSBuild argumentsдо
/p:GenerateProjectSpecificOutputFolder=trueтакой:
по умолчанию каждый файл проекта (*.csproj,*.vbproj и т. д.) задает выходной каталог по умолчанию (обычно это bin\Debug, bin\Release и т. д.). Team Build фактически переопределяет это, чтобы вы не зависели от того, какие свойства разработчик устанавливает в файле проекта, но также и чтобы Team Build могла делать предположения о том, где расположены выходные данные.
самый простой способ переопределить это поведение-установить CustomizableOutDir в true в группе элементов Solutions Tobuild как показано здесь:
<ItemGroup> <SolutionToBuild Include="$(BuildProjectFolderPath)\path\MySolution.sln" /> <Properties>CustomizableOutDir=true</Properties> </SolutionToBuild> </ItemGroup>это сделает структуру папок drop примерно соответствовать тому, что вы получите локально, если вы построили решение.
этот метод определенно предпочтительнее, чем переопределение основных * целей, которые могут вызвать проблемы с обновлением.
для каждого узла Solutions Tobuild задайте свойству OutDir значение $(OutDir)\SubFolder
Например:<ItemGroup> <SolutionToBuild Include="Project1.sln" > <Properties>OutDir=$(OutDir)\Project1\</Properties> </SolutionToBuild> <SolutionToBuild Include="Project2.sln" > <Properties>OutDir=$(OutDir)\Project2\</Properties> </SolutionToBuild> <SolutionToBuild Include="Project3.sln" > <Properties>OutDir=$(OutDir)\Project3\</Properties> </SolutionToBuild> <ItemGroup>(это работает в TF2008, но не TF2005.)
Я немного опоздал на вечеринку, отвечая на этот вопрос, но есть очень простой способ реализовать ответ Майка Хэдлоуза. Кто-то написал пакет nuget, который делает именно то, о чем говорит Майк. Вы можете найти его здесь: http://www.nuget.org/packages/PublishedApplications
обновление для TFS 2010 (и предстоящего TFS 2012). Джейсон Стэнгрум написал хороший пост в блоге с изложением того, как это сделать.
http://blog.codeassassin.com/2012/02/03/override-the-tfs-team-build-outdir-property/
(ссылка выше умерла... привязка к кэшированным версия)
переопределить свойство TFS Team Build OutDir
обновление: С .NET 4.5 есть более простой способ.
очень распространенная жалоба от пользователей системы сборки Team Foundation Server заключается в том, что она изменяет структуру папок выходных данных проекта. По умолчанию Visual Studio помещает все файлы в соответствующую папку /bin/ или /bin// каждого проекта, но Team Build просто использует плоскую структуру папок, помещая все файлы в корневую папку drop или, опять же, подпапку // в папку drop, при этом все выходные данные проекта смешиваются вместе.
кроме того, поскольку Team Build достигает этого, устанавливая свойство OutDir через MSBuild.exe командной строки в сочетании с в MSBuild по приоритет свойства это значение не может быть легко изменено из самого MSBuild и популярным решением является изменить шаблон процесса сборки *.xaml-файл для использования другого имени свойства. Но я предпочитаю не трогать рабочий процесс без крайней необходимости.
вместо этого я использую как решение перед Target, так и встроенные функции задачи MSBuild v4 для переопределения реализации по умолчанию задачи MSBuild, используемой для построения отдельных проектов в решение. В моей альтернативной реализации я предотвращаю передачу свойства OutDir, и я прохожу через свойство PreferredOutDir вместо этого, которое отдельные проекты могут использовать при желании.
первая часть, заменяющая свойство OutDir на свойство PreferredOutDir на уровне решения, достигается простым добавлением нового файла в каталог, в котором находится файл решения. Этот новый файл должен быть назван по образцу "раньше..ФСЛ.цели", например, для файла решения под названием " Foo.sln "тогда новый файл будет" раньше.Foo.ФСЛ.контрольные цели." Содержимое этого нового файла должно выглядеть так. Убедитесь, что этот новый файл возвращается в систему управления версиями.
вторая часть, позволяющая каждому проекту управлять своей структурой выходных папок, - это просто вопрос добавления строки в проект *.csproj или *.vbproj файл (в зависимости от языка). Найдите первый элемент внутри файла проекта, который не имеет Атрибут Condition указан, и найдите соответствующий закрывающий тег для этого элемента. Непосредственно над закрывающим тегом добавьте строку примерно так:
<OutDir Condition=" '$(PreferredOutDir)' != '' ">$(PreferredOutDir)$(MSBuildProjectName)\</OutDir>в этом примере проект будет выводиться в папку перетаскивания Team Build под подпапкой с именем того же файла проекта (без имени .расширением csproj). Вы можете выбрать другой шаблон. Кроме того, веб-проекты обычно создают свою собственную выходную папку под _PublishedWebSites подпапка папки перетаскивания Team Build, чтобы поддерживать это поведение, просто установите свойство OutDir равным свойству PreferredOutDir точно.
вы можете проверить, работали ли ваши изменения на вашем локальном компьютере перед проверкой, просто запустив MSBuild из командной строки и указав свойство OutDir так же, как это делает Team Build, например:
msbuild Foo.sln /p:OutDir=c:\TestDropFolder\
для тех, кому интересно, как это работает с TFS 2010,этой сообщение имеет несколько ответов, из которых связанный один работал очень хорошо для меня.
У вас может быть один buildscript для каждого проекта, который будет делать именно то, что вы хотите. Просто создайте новый файл TFSBuild, добавьте проекты, которые вы хотите построить в itemgroup(в том порядке, в котором вы хотите их построить), установите, где вы хотите, чтобы выход был. Это делается путем переопределения - свойство в файле TFSBuild.
но я также согласен с предыдущим плакатом - почему бы вам просто не запустить с одним скриптом сборки и добавить zip-задачу в конце? Поддержание buildscript для каждого проект добавляет накладные расходы на обслуживание...
слинг это в propertygroup:
<CustomizableOutDir>true</CustomizableOutDir>он переопределит глобальное свойство CustomizableOutDir, которое по умолчанию имеет значение False. Установка этого параметра в свойствах Solutions Tobuild не будет работать.
это достигается путем переопределения целевой реализации CoreDropBuild по умолчанию.
в TFSBuild.файл proj (по умолчанию хранится в TeamBuildTypes/) добавьте следующую цель:
<!-- Override default implementation --> <Target Name="CoreDropBuild" Condition=" '$(SkipDropBuild)'!='true' and '$(IsDesktopBuild)'!='true' " DependsOnTargets="$(CoreDropBuildDependsOn)"> ... </Target>в этой цели вы можете управлять выводом, как вы хотите. По умолчанию просто копирует все из $(BinariesRoot)\$(Типпостроения) до $(это)\$(строительный номер).
Я обычно использую Microsoft.ШУРС.Задачи проекта для возможности копирования файлов.
Простое Решение:
замените все узлы
на . Это, конечно, будет работать только для публикуемых проектов (например, веб-проектов и приложений), а не для библиотечных проектов. Так Просто:)

Comments