Как опубликовать веб с помощью msbuild?

216

Visual Studio 2010 имеет команду «Опубликовать», которая позволяет опубликовать проект веб-приложения в расположении файловой системы. Я хотел бы сделать это на моем сервере сборки TeamCity, поэтому мне нужно сделать это с помощью решения Runner или msbuild. Я попытался использовать цель публикации, но я думаю, что это может быть для ClickOnce:

msbuild Project.csproj /t:Publish /p:Configuration=Deploy

Я в основном хочу сделать именно то, что делает проект веб-развертывания, но без надстройки. Мне нужно, чтобы он скомпилировал WAP, удалил все файлы, ненужные для выполнения, выполнил любые преобразования web.config и скопировал вывод в указанное место.

Мое решение , основанное на ответе Джеффа Сивера

<Target Name="Deploy">
    <MSBuild Projects="$(SolutionFile)" 
             Properties="Configuration=$(Configuration);DeployOnBuild=true;DeployTarget=Package" 
             ContinueOnError="false" />
    <Exec Command="&quot;$(ProjectPath)\obj\$(Configuration)\Package\$(ProjectName).deploy.cmd&quot; /y /m:$(DeployServer) -enableRule:DoNotDeleteRule" 
          ContinueOnError="false" />
</Target>
jrummell
источник
возможный дубликат: stackoverflow.com/questions/1162253/…
Стивен Эверс
@SnOrfus В настоящее время я использую проекты веб-развертывания в VS 2008 (как я уже упоминал в своем ответе на этот вопрос), но вместо этого я хотел бы попробовать автоматизировать функцию публикации в VS 2010.
jrummell
Этот вопрос выглядит полезным stackoverflow.com/questions/1983575/…
jrummell
2
Только одна небольшая поправка к вашему сценарию: вы используете $ (ProjectPath) для сценария развертывания, но вы действительно хотите использовать $ (ProjectDir), в противном случае вы получите .csproj \ obj
Troy Hunt
2
Начиная с VS2012, это намного проще: stackoverflow.com/a/13947667/270348
RobSiklos

Ответы:

136

Я получил это в основном работает без специального сценария msbuild. Вот соответствующие параметры конфигурации сборки TeamCity:

Пути артефактов:% system.teamcity.build.workingDir% \ MyProject \ obj \ Debug \ Package \ PackageTmp 
Тип бегуна: MSBuild (Бегунок для файлов MSBuild) 
Путь к файлу сборки: MyProject \ MyProject.csproj 
Рабочий каталог: так же, как каталог 
Версия MSBuild: Microsoft .NET Framework 4.0 
MSBuild Tools Версия: 4.0 
Запустите платформу: x86 
Цели: Пакет 
Параметры командной строки для MSBuild.exe: / p: Configuration = Debug

Это скомпилирует, упакует (с преобразованием web.config) и сохранит вывод как артефакты. Единственное, чего не хватает, это скопировать вывод в указанное место, но это можно сделать либо в другой конфигурации сборки TeamCity с зависимостью артефакта, либо с помощью сценария msbuild.

Обновить

Вот скрипт msbuild, который скомпилирует, упакует (с преобразованием web.config) и скопирует вывод на мой промежуточный сервер

<?xml version="1.0" encoding="utf-8" ?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
        <SolutionName>MySolution</SolutionName>
        <SolutionFile>$(SolutionName).sln</SolutionFile>
        <ProjectName>MyProject</ProjectName>
        <ProjectFile>$(ProjectName)\$(ProjectName).csproj</ProjectFile>
    </PropertyGroup>

    <Target Name="Build" DependsOnTargets="BuildPackage;CopyOutput" />

    <Target Name="BuildPackage">
        <MSBuild Projects="$(SolutionFile)" ContinueOnError="false" Targets="Rebuild" Properties="Configuration=$(Configuration)" />
        <MSBuild Projects="$(ProjectFile)" ContinueOnError="false" Targets="Package" Properties="Configuration=$(Configuration)" />
    </Target>

    <Target Name="CopyOutput">
        <ItemGroup>
            <PackagedFiles Include="$(ProjectName)\obj\$(Configuration)\Package\PackageTmp\**\*.*"/>
        </ItemGroup>
        <Copy SourceFiles="@(PackagedFiles)" DestinationFiles="@(PackagedFiles->'\\build02\wwwroot\$(ProjectName)\$(Configuration)\%(RecursiveDir)%(Filename)%(Extension)')"/>
    </Target>
</Project>

Вы также можете удалить свойства SolutionName и ProjectName из тега PropertyGroup и передать их в msbuild.

msbuild build.xml /p:Configuration=Deploy;SolutionName=MySolution;ProjectName=MyProject

Обновление 2

Поскольку этот вопрос все еще получает много трафика, я подумал, что стоит обновить мой ответ с помощью моего текущего сценария, который использует Web Deploy (также известный как MSDeploy).

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build" ToolsVersion="4.0">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
    <ProjectFile Condition=" '$(ProjectFile)' == '' ">$(ProjectName)\$(ProjectName).csproj</ProjectFile>
    <DeployServiceUrl Condition=" '$(DeployServiceUrl)' == '' ">http://staging-server/MSDeployAgentService</DeployServiceUrl>
  </PropertyGroup>

  <Target Name="VerifyProperties">
    <!-- Verify that we have values for all required properties -->
    <Error Condition=" '$(ProjectName)' == '' " Text="ProjectName is required." />
  </Target>

  <Target Name="Build" DependsOnTargets="VerifyProperties">
    <!-- Deploy using windows authentication -->
    <MSBuild Projects="$(ProjectFile)"
             Properties="Configuration=$(Configuration);
                             MvcBuildViews=False;
                             DeployOnBuild=true;
                             DeployTarget=MSDeployPublish;
                             CreatePackageOnPublish=True;
                             AllowUntrustedCertificate=True;
                             MSDeployPublishMethod=RemoteAgent;
                             MsDeployServiceUrl=$(DeployServiceUrl);
                             SkipExtraFilesOnServer=True;
                             UserName=;
                             Password=;"
             ContinueOnError="false" />
  </Target>
</Project>

В TeamCity у меня есть параметры env.Configuration, env.ProjectNameиenv.DeployServiceUrl . У бегуна MSBuild есть путь к файлу сборки, и параметры передаются автоматически (их не нужно указывать в параметрах командной строки).

Вы также можете запустить его из командной строки:

msbuild build.xml /p:Configuration=Staging;ProjectName=MyProject;DeployServiceUrl=http://staging-server/MSDeployAgentService
jrummell
источник
2
спасибо - это также хорошо работает напрямую из powershell (извиняюсь за форматирование - в комментариях нет переноса): & msbuild "$ solution" / p: "Configuration = $ configuration"; & msbuild "$ project" / t: Package / p: "Configuration = $ configuration; _PackageTempDir = $ outputfolder"
zcrar70
Я попробовал пример из вашего первого Обновления, и кажется, что Packageцель также зависит от WebDeploy: error : Package/Publish task Microsoft.Web.Publishing.Tasks.IsCleanMSDeployPackageNeeded failed to load Web Deploy assemblies. Microsoft Web Deploy is not correctly installed on this machine.(Упомяну его, поскольку вы пишете, что ваше второе обновление использует WebDeploy, что может означать, что первое еще не будет использовать WebDeploy.)
chiccodoro
@jrummell: я хочу развернуть свой веб-проект Visual Studio на удаленном сервере Windows из TeamCity. Что я должен делать. Я новичок и понятия не имею, что делать
Невин Радж Виктор
1
Я могу заставить это работать в TeamCity с проектами веб-приложений, но у меня также есть устаревший веб-сайт ПРОЕКТ, который мне также нужно опубликовать (как пакет), а затем использовать MSDeploy. Если я публикую в VS2013, я получаю пакет развертывания, но MSBuild из строки cmd не создает его. Есть предположения?
KnowHowSolutions
1
Я не вижу упоминания об этом профиле публикации. Необходимо указать профиль публикации, чтобы было применено правильное преобразование web.config. Обновление: Nevermind ... эта функция была введена через 2 года после этого поста. Этот еще, вероятно, работает. Позже пост в этой теме показывает, как публиковать с профилем публикации из командной строки.
Трийнко
84

Используя профили развертывания, представленные в VS 2012, вы можете опубликовать их с помощью следующей командной строки:

msbuild MyProject.csproj /p:DeployOnBuild=true /p:PublishProfile=<profile-name> /p:Password=<insert-password> /p:VisualStudioVersion=11.0

Для получения дополнительной информации о параметрах см. Это .

Значения /p:VisualStudioVersionпараметра зависят от вашей версии Visual Studio. В Википедии есть таблица выпусков Visual Studio и их версий .

Крис
источник
6
В VS2012 .NET 3.5 это не сработало для развертывания в файловой системе. Он просто создает и не развертывает.
Джей Салливан
2
ваш /p:VisualStudioVersion=11.0 спас мне жизнь. Я использую /p:VisualStudioVersion=12.0 для vs2013, и он отлично работает.
Сейед Мортеза Мусави
Какое значение будет иметь /p:VisualStudioVersion=?VS VS?
Nishant
создал скрипт сборки msbuild test.sln /p:DeployOnBuild=True /p:DeployDefaultTarget=WebPublish /p:WebPublishMethod=FileSystem /p:DeleteExistingFiles=True /p:publishUrl=.\build_output1\pub /p:PublishProfile=FolderProfile /p:VisualStudioVersion=11.0 /p:outdir=.\build_output1 ...... Но все равно получаю только DLL, а не все файлы, как в папке publish: (`
Nishant
@Nishant Для VS 2017, используйте /p:VisualStudioVersion=15. Я не уверен, связано ли это с вашей проблемой копирования файлов.
Крис
38

Я придумал такое решение, прекрасно работает для меня:

msbuild /t:ResolveReferences;_WPPCopyWebApplication /p:BuildingProject=true;OutDir=C:\Temp\build\ Test.csproj

Секретный соус - цель _WPPCopyWebApplication.

Александр Белецкий
источник
1
Что такое _WPPCopyWebApplication и как я могу его использовать MSBbuild xml config file /
Johnny_D
4
Используя VS2012 .NET 3.5, я получил ошибку error MSB4057: The target "_WPPCopyWebApplication" does not exist in the project. Изъятие этой части привело к развертыванию без развертывания каких-либо представлений
Джей Салливан,
Вам может потребоваться вызвать его с другой /p:VisualStudioVersion=12.0, потому что сборка использует цели из c: \ program files (x86) \ msbuild \ microsoft \ visualstudio \ VERSION \ Webapplication \ Microsoft.WebApplication.targets, поэтому, возможно, она использует более старая версия, у которой нет правильной цели.
Джим Вольф
@FRoZeN Я пытался использовать MSBuild как MSBuild.exe C:\BuildAgent\work\4c7b8ac8bc7d723e\WebService.sln /p:Configuration=Release /p:OutputPath=bin /p:DeployOnBuild=True /p:DeployTarget=MSDeployPublish /p:MsDeployServiceUrl=https://204.158.674.5/msdeploy.axd /p:username=Admin /p:password=Password#321 /p:AllowUntrustedCertificate=True /p:DeployIisAppPath=Default WebSite/New /p:MSDeployPublishMethod=WMSVC. Это дает мне ошибку MSBUILD : error MSB1008: Only one project can be specified. Switch: WebSite/New. Есть ли решение для этого?
Невин Радж Виктор
1
@NevinRajVictor эта ошибка вероятна, потому что у вас есть пробел в значении DeployIisAppPath. Вам нужно будет поставить значение в кавычках. Например, / p: DeployIisAppPath = "Веб-сайт по умолчанию / новый"
шиитаке
27

Я не знаю TeamCity, поэтому надеюсь, что это сработает для вас.

Лучший способ сделать это - MSDeploy.exe. Это часть проекта WebDeploy, выполняемого Microsoft. Вы можете скачать биты здесь .

С WebDeploy вы запускаете командную строку

msdeploy.exe -verb:sync -source:contentPath=c:\webApp -dest:contentPath=c:\DeployedWebApp

Это делает то же самое, что и команда VS Publish, копируя только необходимые биты в папку развертывания.

Джефф Сивер
источник
Это выглядит многообещающе. Однако похоже, что служба управления доступна только на Server 2008. Мой промежуточный сервер (на котором я хочу автоматизировать развертывание) работает под управлением Windows 7 Pro.
jrummell
2
Есть две части к продукту. Для частей, которые интегрируются прямо в IIS, требуется Server 2008. Компонент командной строки не имеет этого требования; Он работает на сервере Server 2003, который я использую для развертываний.
Джефф Сивер
Я немного читал на MSDeploy. Я установил его и работал на моем промежуточном сервере, спасибо! Могу ли я запустить MSDeploy из скрипта MSBuild?
jrummell
1
делает то же самое, что и какая конфигурация команды VS Publish? Какой метод публикации - файловая система или другой? Использует ли он файл MyProject.Publish.xml, чтобы определить, какие файлы копировать?
Энтони
1
Я просто дал ему шанс, но он не сделал то же самое, что VS Publish. Он сделал то же самое, что и XCopy, включая все исходные файлы.
Луи Сомерс
13

В VisualStudio 2012 есть способ обработки subj без публикации профилей. Вы можете передать выходную папку, используя параметры. Работает как с абсолютным, так и с относительным путем в параметре publishUrl. Вы можете использовать VS100COMNTOOLS, однако вам нужно переопределить VisualStudioVersion, чтобы использовать целевой «WebPublish» из %ProgramFiles%\MSBuild\Microsoft\VisualStudio\v11.0\WebApplications\Microsoft.WebApplication.targets. С VisualStudioVersion 10.0 этот сценарий будет успешным без выходных данных :)

Обновление: мне удалось использовать этот метод на сервере сборки, на котором установлена ​​только Windows SDK 7.1 (без Visual Studio 2010 и 2012 на компьютере). Но я должен был выполнить следующие шаги, чтобы заставить это работать:

  1. Сделайте Windows SDK 7.1 актуальным на компьютере с помощью ответа Simmo ( https://stackoverflow.com/a/2907056/2164198 )
  2. Установка ключа реестра HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ VisualStudio \ SxS \ VS7 \ 10.0 в "C: \ Program Files \ Microsoft Visual Studio 10.0 \" (используйте соответствующий путь)
  3. Копирование папки% ProgramFiles% \ MSBuild \ Microsoft \ VisualStudio \ v11.0 с компьютера разработчика на сервер сборки

Автор сценария:

set WORK_DIR=%~dp0
pushd %WORK_DIR%
set OUTPUTS=%WORK_DIR%..\Outputs
set CONFIG=%~1
if "%CONFIG%"=="" set CONFIG=Release
set VSTOOLS="%VS100COMNTOOLS%"
if %VSTOOLS%=="" set "PATH=%PATH%;%WINDIR%\Microsoft.NET\Framework\v4.0.30319" && goto skipvsinit
call "%VSTOOLS:~1,-1%vsvars32.bat"
if errorlevel 1 goto end
:skipvsinit
msbuild.exe Project.csproj /t:WebPublish /p:Configuration=%CONFIG% /p:VisualStudioVersion=11.0 /p:WebPublishMethod=FileSystem /p:publishUrl=%OUTPUTS%\Project
if errorlevel 1 goto end
:end
popd
exit /b %ERRORLEVEL%
Иван Самыгин
источник
Спасибо за это решение - это то, что я искал: вариант WebPublish с развертыванием файловой системы.
Woohoo
12

нашел два разных решения, которые работали немного по-другому:

1. Это решение основано на ответе alexanderb [ссылка] . К сожалению, у нас это не сработало - некоторые DLL не были скопированы в OutDir. Мы обнаружили, что замена ResolveReferencesна Buildtarget решает проблему - теперь все необходимые файлы копируются в папку OutDir.

msbuild / target: Build; _WPPCopyWebApplication / p: Configuration = Release; OutDir = C: \ Tmp \ myApp \ MyApp.csproj
Недостатком этого решения был тот факт, что OutDir содержал не только файлы для публикации.

2. Первое решение работает хорошо, но не так, как мы ожидали. Мы хотели, чтобы функциональность публикации была такой же, как в Visual Studio IDE - то есть только файлы, которые должны быть опубликованы, будут скопированы в выходной каталог. Как уже упоминалось, первое решение копирует гораздо больше файлов в OutDir - веб-сайт для публикации затем сохраняется в _PublishedWebsites/{ProjectName}подпапке. Следующая команда решает эту проблему - только файлы для публикации будут скопированы в нужную папку. Теперь у вас есть каталог, который можно публиковать напрямую - по сравнению с первым решением вы сэкономите место на жестком диске.

msbuild / target: Build; PipelinePreDeployCopyAllFilesToOneFolder / p: Configuration = Release; _PackageTempDir = C: \ Tmp \ myApp \; AutoParameterizationWebConfigConnectionStrings = false MyApp.csproj
AutoParameterizationWebConfigConnectionStrings=falseПараметр гарантирует, что строки подключения не будут обрабатываться как специальные артефакты и будут генерироваться правильно - для получения дополнительной информации см. ссылку .

Павел Чермак
источник
Ваш вариант № 2 помог мне легко избавиться от устаревшего _CopyWebApplication. Вы спасли мой Build-Server после обновления до VS 2015. Отличное исследование. Благодарные.
it3xl
Ваш вариант №2 идеально подходит для моего сценария сборки.
AnthonyVO
3

Вы должны установить свою среду

  • <Имя веб-сайта>
  • <домен>

и ссылаться на мой блог. (извините, пост был корейский)

  • http://xyz37.blog.me/50124665657
  • http://blog.naver.com/PostSearchList.nhn?SearchText=webdeploy&blogId=xyz37&x=25&y=7

    @ECHO OFF
    :: http://stackoverflow.com/questions/5598668/valid-parameters-for-msdeploy-via-msbuild
    ::-DeployOnBuild -True
    :: -False
    :: 
    ::-DeployTarget -MsDeployPublish
    :: -Package
    :: 
    ::-Configuration -Name of a valid solution configuration
    :: 
    ::-CreatePackageOnPublish -True
    :: -False
    :: 
    ::-DeployIisAppPath -<Web Site Name>/<Folder>
    :: 
    ::-MsDeployServiceUrl -Location of MSDeploy installation you want to use
    :: 
    ::-MsDeployPublishMethod -WMSVC (Web Management Service)
    :: -RemoteAgent
    :: 
    ::-AllowUntrustedCertificate (used with self-signed SSL certificates) -True
    :: -False
    :: 
    ::-UserName
    ::-Password
    SETLOCAL
    
    IF EXIST "%SystemRoot%\Microsoft.NET\Framework\v2.0.50727" SET FXPath="%SystemRoot%\Microsoft.NET\Framework\v2.0.50727"
    IF EXIST "%SystemRoot%\Microsoft.NET\Framework\v3.5" SET FXPath="%SystemRoot%\Microsoft.NET\Framework\v3.5"
    IF EXIST "%SystemRoot%\Microsoft.NET\Framework\v4.0.30319" SET FXPath="%SystemRoot%\Microsoft.NET\Framework\v4.0.30319"
    
    SET targetFile=<web site fullPath ie. .\trunk\WebServer\WebServer.csproj
    SET configuration=Release
    SET msDeployServiceUrl=https://<domain>:8172/MsDeploy.axd
    SET msDeploySite="<WebSite name>"
    SET userName="WebDeploy"
    SET password=%USERNAME%
    SET platform=AnyCPU
    SET msbuild=%FXPath%\MSBuild.exe /MaxCpuCount:%NUMBER_OF_PROCESSORS% /clp:ShowCommandLine
    
    %MSBuild% %targetFile% /p:configuration=%configuration%;Platform=%platform% /p:DeployOnBuild=True /p:DeployTarget=MsDeployPublish /p:CreatePackageOnPublish=False /p:DeployIISAppPath=%msDeploySite% /p:MSDeployPublishMethod=WMSVC /p:MsDeployServiceUrl=%msDeployServiceUrl% /p:AllowUntrustedCertificate=True /p:UserName=%USERNAME% /p:Password=%password% /p:SkipExtraFilesOnServer=True /p:VisualStudioVersion=12.0
    
    IF NOT "%ERRORLEVEL%"=="0" PAUSE 
    ENDLOCAL
Ким Ки Вон
источник
1

Это мой командный файл

C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe C:\Projects\testPublish\testPublish.csproj  /p:DeployOnBuild=true /property:Configuration=Release
if exist "C:\PublishDirectory" rd /q /s "C:\PublishDirectory"
C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_compiler.exe -v / -p C:\Projects\testPublish\obj\Release\Package\PackageTmp -c C:\PublishDirectory
cd C:\PublishDirectory\bin 
del *.xml
del *.pdb
Алим Иси
источник
5
Было бы здорово, если бы вы могли детализировать свой ответ. Как именно ваш командный файл решает проблему ОП? Спасибо!
Луис Крус
1

это моя рабочая партия

публиковать-мой-website.bat

SET MSBUILD_PATH="C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin"
SET PUBLISH_DIRECTORY="C:\MyWebsitePublished"
SET PROJECT="D:\Github\MyWebSite.csproj"


cd /d %MSBUILD_PATH%
MSBuild %PROJECT%  /p:DeployOnBuild=True /p:DeployDefaultTarget=WebPublish /p:WebPublishMethod=FileSystem /p:DeleteExistingFiles=True /p:publishUrl=%PUBLISH_DIRECTORY%

Обратите внимание, что я установил Visual Studio на сервере для возможности запуска, MsBuild.exeпотому что MsBuild.exeпапки в .Net Framework не работают.

Альпер Эбикоглу
источник
msbuild test.sln /p:DeployOnBuild=True /p:DeployDefaultTarget=WebPublish /p:WebPublishMethod=FileSystem /p:DeleteExistingFiles=True /p:publishUrl=.\build_output1\pub /p:PublishProfile=FolderProfile /p:VisualStudioVersion=11.0 /p:outdir=.\build_output1 ...... Но все равно получаю только DLL, а не структуру файлов, которую я хочу. Что с этим не так? :(
Nishant
1

Вы можете опубликовать решение с желаемым путем с помощью кода ниже. Здесь PublishInDFolder - это имя, путь к которому нам нужно опубликовать (нам нужно создать его на рисунке ниже)

Вы можете создать файл публикации, как это

Добавьте ниже 2 строки кода в пакетный файл (.bat)

@echo OFF 
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\Tools\VsMSBuildCmd.bat"
MSBuild.exe  D:\\Solution\\DataLink.sln /p:DeployOnBuild=true /p:PublishProfile=PublishInDFolder
pause
Pradeep Sk
источник
0

Для генерации выходных данных публикации предоставьте еще один параметр. msbuild example.sln / p: publishprofile = имя профиля / p: deployonbuild = true / p: конфигурация = отладка / или любая

Яшвант Махавар
источник