Как публиковать веб с помощью msbuild?
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=""$(ProjectPath)\obj\$(Configuration)\Package\$(ProjectName).deploy.cmd" /y /m:$(DeployServer) -enableRule:DoNotDeleteRule"
ContinueOnError="false" />
</Target>
12 ответов
Я получил это в основном работает без специального скрипта 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
Используя профили развертывания, представленные в VS 2012, вы можете опубликовать их с помощью следующей командной строки:
msbuild MyProject.csproj /p:DeployOnBuild=true /p:PublishProfile=<profile-name> /p:Password=<insert-password> /p:VisualStudioVersion=11.0
Для получения дополнительной информации о параметрах см. Это.
Я придумал такое решение, прекрасно работает для меня:
msbuild /t:ResolveReferences;_WPPCopyWebApplication /p:BuildingProject=true;OutDir=C:\Temp\build\ Test.csproj
Секретный соус - цель _WPPCopyWebApplication.
Я не знаю TeamCity, поэтому надеюсь, что это сработает для вас.
Лучший способ, который я нашел, это сделать с помощью MSDeploy.exe. Это часть проекта WebDeploy, выполняемого Microsoft. Вы можете скачать биты здесь.
С WebDeploy вы запускаете командную строку
msdeploy.exe -verb:sync -source:contentPath=c:\webApp -dest:contentPath=c:\DeployedWebApp
Это делает то же самое, что и команда VS Publish, копируя только необходимые биты в папку развертывания.
В 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). Но я должен был выполнить следующие шаги, чтобы заставить это работать:
- Сделайте Windows SDK 7.1 текущей на компьютере, используя ответ Simmo ( /questions/23079416/pri-zapuske-msbuild-ne-udaetsya-prochitat-sdktoolspath/23079437#23079437)
- Установка ключа реестра HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\SxS\VS7\10.0 в "C:\Program Files\Microsoft Visual Studio 10.0\" (используйте соответствующий путь)
- Копирование папки%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%
Нашел два разных решения, которые работали немного по-другому:
1. Это решение основано на ответе alexanderb [ссылка]. К сожалению, у нас это не сработало - некоторые DLL не были скопированы в OutDir. Мы выяснили, что замена ResolveReferences
с Build
Цель решает проблему - теперь все необходимые файлы копируются в папку 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
Параметр гарантирует, что строки подключения не будут обрабатываться как специальные артефакты и будут сгенерированы правильно - для получения дополнительной информации см. ссылку.
Это моя рабочая партия
публиковать-мой-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 папки не работают.
Вы должны установить свою среду
- <Имя веб-сайта>
- <домен>
и ссылка на мой блог.(извините, пост был корейский)
- http://xyz37.blog.me/50124665657
http://blog.naver.com/PostSearchList.nhn?SearchText=webdeploy&blogId=xyz37&x=25&y=7
@ECHO OFF :: http://stackru.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
Вы можете опубликовать решение с желаемым путем с помощью кода ниже, здесь 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
Это мой командный файл
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
Для генерации выходных данных публикации предоставьте еще один параметр. msbuild example.sln /p:publishprofile= имя профиля /p:deployonbuild=true /p:configuration=debug/ или любой
вы можете использовать эту команду для публикации веб-приложений с помощью профилей публикации.
msbuild SolutionName.sln /p:DeployOnBuild=true /p:PublishProfile=PublishProfileName
В этом образце профиля публикации можно создать ZIP-файл выпуска с номером версии, который находится в файле AssemblyInfo.cs по сетевому пути (создание ZIP-файла и удаление других опубликованных файлов с помощью команды PowerShell необязательно).
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<Major>0</Major>
<Minor>1</Minor>
<Build>2</Build>
<Publish>C:\</Publish>
<publishUrl>$(Publish)</publishUrl>
<DeleteExistingFiles>True</DeleteExistingFiles>
</PropertyGroup>
<Target Name="GetBuildUrl">
<PropertyGroup> <In>$([System.IO.File]::ReadAllText('$(MSBuildProjectDirectory)\Properties\AssemblyInfo.cs'))</In>
<TargetPath>\\NetworkPath\ProjectName</TargetPath>
<Pattern>^\s*\[assembly: AssemblyVersion\(\D*(\d+)\.(\d+)\.(\d+)\.(\d+)</Pattern>
<Major>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern), System.Text.RegularExpressions.RegexOptions.Multiline).Groups[1].Value)</Major>
<Minor>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern), System.Text.RegularExpressions.RegexOptions.Multiline).Groups[2].Value)</Minor>
<Build>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern), System.Text.RegularExpressions.RegexOptions.Multiline).Groups[3].Value)</Build>
<Sub>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern), System.Text.RegularExpressions.RegexOptions.Multiline).Groups[4].Value)</Sub>
<Publish>$(TargetPath)\$(Major).$(Minor).$(Build).$(Sub)\</Publish>
<publishUrl Condition=" '$(Publish)' != '' ">$(Publish)</publishUrl>
<publishUrl Condition=" '$(Publish)' == '' and '$(LastUsedBuildConfiguration)'!='' ">$(LastUsedBuildConfiguration)</publishUrl>
</PropertyGroup>
</Target>
<Target Name="BeforeBuild" DependsOnTargets="GetBuildUrl">
<Message Importance="High" Text="|" />
<Message Importance="High" Text=" ================================================================================================" />
<Message Importance="High" Text=" BUILD INFO " />
<Message Importance="High" Text=" Version [$(Major).$(Minor).$(Build)] found in [$(MSBuildProjectDirectory)\Properties\AssemblyInfo.cs] " />
<Message Importance="High" Text=" Build will be saved to [$(publishUrl)] " />
<Message Importance="High" Text=" =================================================================================================" />
<Message Importance="High" Text="|" />
</Target>
<Target Name="Zip" BeforeTargets="AfterBuild">
<Exec Command="PowerShell -command Compress-Archive -Path $(Publish) -DestinationPath $(Publish)Release.zip" />
<Exec Command="PowerShell -command Remove-Item -Recurse -Force $(Publish) -Exclude Release.zip" />
</Target>
</Project>