Visual Studio 2010有一个发布命令,允许您将Web应用程序项目发布到文件系统位置。我想在我的TeamCity构建服务器上做这件事,所以我需要用解决方案运行器或msbuild来做。我尝试使用Publish目标,但我认为这可能是为ClickOnce:
msbuild Project.csproj /t:Publish /p:Configuration=Deploy
我基本上想要做一个web部署项目所做的事情,但是没有外接程序。我需要它来编译WAP,删除任何不必要的执行文件,执行任何web。配置转换,并将输出复制到指定的位置。
我的解决方案,基于杰夫·西尔弗的回答
<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>
我得到了它大部分工作没有自定义msbuild脚本。以下是相关的TeamCity构建配置设置:
Artifact paths: %system.teamcity.build.workingDir%\MyProject\obj\Debug\Package\PackageTmp
Type of runner: MSBuild (Runner for MSBuild files)
Build file path: MyProject\MyProject.csproj
Working directory: same as checkout directory
MSBuild version: Microsoft .NET Framework 4.0
MSBuild ToolsVersion: 4.0
Run platform: x86
Targets: Package
Command line parameters to MSBuild.exe: /p:Configuration=Debug
这将编译,打包(与web。配置转换),并将输出保存为工件。唯一缺少的是将输出复制到指定的位置,但这可以在另一个TeamCity构建配置中使用工件依赖项或使用msbuild脚本完成。
更新
这是一个msbuild脚本,将编译,打包(与web。配置转换),并将输出复制到登台服务器
<?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>
您还可以从PropertyGroup标签中删除SolutionName和ProjectName属性,并将它们传递给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的参数。配置,env。ProjectName和env.DeployServiceUrl。MSBuild运行器具有构建文件路径,并且自动传递参数(您不必在命令行参数中指定它们)。
你也可以从命令行运行它:
msbuild build.xml /p:Configuration=Staging;ProjectName=MyProject;DeployServiceUrl=http://staging-server/MSDeployAgentService
在VisualStudio 2012中,有一种方法可以在不发布配置文件的情况下处理subj。您可以使用参数传递输出文件夹。它既适用于'publishUrl'参数中的绝对路径,也适用于相对路径。你可以使用VS100COMNTOOLS,但是你需要覆盖VisualStudioVersion来使用%ProgramFiles%\MSBuild\Microsoft\VisualStudio\v11.0\WebApplications\Microsoft. webapplication .targets中的目标'WebPublish'。在VisualStudioVersion 10.0中,这个脚本将成功,没有输出:)
更新:我已经在只安装了Windows SDK 7.1的构建服务器上使用了这个方法(机器上没有Visual Studio 2010和2012)。但我必须遵循以下步骤才能让它起作用:
使用Simmo answer (https://stackoverflow.com/a/2907056/2164198)让Windows SDK 7.1在机器上运行
将注册表键HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\SxS\VS7\10.0设置为“C:\Program Files\Microsoft VisualStudio 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。我们发现用Build target替换ResolveReferences可以解决这个问题——现在所有必要的文件都被复制到OutDir位置。
msbuild /target:Build;_WPPCopyWebApplication /p:Configuration=Release;OutDir=C:\Tmp\myApp\ myApp .csproj
这种解决方案的缺点是OutDir不仅包含要发布的文件。
2. The first solution works well but not as we expected. We wanted to have the publish functionality as it is in Visual Studio IDE - i.e. only the files which should be published will be copied into the Output directory. As it has been already mentioned first solution copies much more files into the OutDir - the website for publish is then stored in _PublishedWebsites/{ProjectName} subfolder. The following command solves this - only the files for publish will be copied to desired folder. So now you have directory which can be directly published - in comparison with the first solution you will save some space on hard drive.
msbuild /target:Build;PipelinePreDeployCopyAllFilesToOneFolder /p:Configuration=Release;_PackageTempDir=C:\Tmp\myApp\;AutoParameterizationWebConfigConnectionStrings=false MyApp.csproj
AutoParameterizationWebConfigConnectionStrings=false parameter will guarantee that connection strings will not be handled as special artifacts and will be correctly generated - for more information see link.
可以使用此命令发布带有发布配置文件的web应用程序。
msbuild SolutionName.sln /p:DeployOnBuild=true /p:PublishProfile=PublishProfileName
这个发布概要文件示例可以创建一个版本号在网络路径中的AssemblyInfo.cs file中的发布zip文件(使用PowerShell命令创建zip文件并删除其他发布文件是可选的)。
<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>