Como publicar na Web com msbuild?

216

O Visual Studio 2010 possui um comando Publicar que permite publicar seu Projeto de Aplicativo da Web em um local do sistema de arquivos. Gostaria de fazer isso no meu servidor de compilação TeamCity, por isso preciso fazê-lo com o gerenciador de soluções ou o msbuild. Tentei usar o destino de publicação, mas acho que pode ser para o ClickOnce:

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

Basicamente, quero fazer exatamente o que um projeto de implantação da web faz, mas sem o suplemento. Preciso compilar o WAP, remover todos os arquivos desnecessários para execução, executar qualquer transformação web.config e copiar a saída para um local especificado.

Minha solução , com base na resposta de Jeff Siver

<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
fonte
possível duplicado: stackoverflow.com/questions/1162253/…
Steven Evers
@SnOrfus Atualmente, estou usando projetos de implantação da Web no VS 2008 (como mencionei na minha resposta a essa pergunta), mas gostaria de tentar automatizar o recurso Publicar do VS 2010.
jrummell
Esta questão parece útil stackoverflow.com/questions/1983575/…
jrummell
2
Apenas uma pequena alteração no seu script: você está usando $ (ProjectPath) para o script de deploy mas você realmente quer é $ (ProjectDir), caso contrário você acaba com .csproj \ obj
Troy caça
2
Começando com o VS2012, isso é muito mais fácil: stackoverflow.com/a/13947667/270348
RobSiklos

Respostas:

137

Eu consegui trabalhar principalmente sem um script msbuild personalizado. Aqui estão as definições de configuração relevantes do TeamCity:

Caminhos de artefato:% system.teamcity.build.workingDir% \ MyProject \ obj \ Debug \ Package \ PackageTmp 
Tipo de corredor: MSBuild (arquivos Runner for MSBuild) 
Caminho do arquivo de construção: MyProject \ MyProject.csproj 
Diretório de trabalho: o mesmo que o diretório de checkout 
Versão MSBuild: Microsoft .NET Framework 4.0 
Ferramentas do MSBuild 
Executar plataforma: x86 
Metas: Pacote 
Parâmetros de linha de comando para MSBuild.exe: / p: Configuration = Debug

Isso irá compilar, empacotar (com a transformação web.config) e salvar a saída como artefatos. A única coisa que falta é copiar a saída para um local especificado, mas isso pode ser feito em outra configuração de compilação do TeamCity com uma dependência de artefato ou com um script msbuild.

Atualizar

Aqui está um script msbuild que irá compilar, empacotar (com a transformação web.config) e copiar a saída no meu servidor intermediário

<?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>

Você também pode remover as propriedades SolutionName e ProjectName da marca PropertyGroup e passá-las para o msbuild.

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

Atualização 2

Como essa pergunta ainda recebe bastante tráfego, achei que valia a pena atualizar minha resposta com meu script atual que usa o Web Deploy (também conhecido como 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>

No TeamCity, tenho parâmetros nomeados env.Configuration, env.ProjectNamee env.DeployServiceUrl. O MSBuild runner possui o caminho do arquivo de compilação e os parâmetros são transmitidos automaticamente (você não precisa especificá-los nos parâmetros de linha de comando).

Você também pode executá-lo na linha de comando:

msbuild build.xml /p:Configuration=Staging;ProjectName=MyProject;DeployServiceUrl=http://staging-server/MSDeployAgentService
jrummell
fonte
2
obrigado - isso também funciona bem diretamente do powershell (desculpas pela formatação - nenhum retorno de carro nos comentários): & msbuild "$ solution" / p: "Configuration = $ configuration"; & msbuild "$ project" / t: Pacote / p: "Configuração = $ configuration; _PackageTempDir = $ outputfolder"
zcrar70 02-02
Tentei o exemplo da sua primeira atualização e parece que o Packagedestino também depende do 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.(mencionando que você escreve que sua segunda atualização usa o WebDeploy, o que pode implicar que a primeira ainda não usaria o WebDeploy.)
chiccodoro
@jrummell: quero implantar meu projeto da web do Visual Studio em um servidor Windows remoto do TeamCity. O que devo fazer. Eu sou um novato e não tenho idéia sobre o que fazer
Nevin Raj Victor
1
Consigo fazer com que isso funcione no TeamCity com projetos de aplicativos da Web, mas também tenho um PROJETO de site vinculado herdado que também preciso publicar (como um pacote) e depois usar o MSDeploy. Se eu publicar no VS2013, recebo um pacote de implantação, mas o MSBuild da linha cmd não cria um. Alguma ideia?
KnowHowSolutions
1
Não vejo nenhuma menção ao perfil de publicação. O perfil de publicação deve ser especificado para que a transformação web.config correta seja aplicada. Atualização: Deixa pra lá ... esse recurso foi introduzido 2 anos após esta postagem. Este ainda provavelmente funciona. A publicação posterior neste segmento mostra como publicar com um perfil de publicação na linha de comando.
Triynko
84

Usando os perfis de implantação introduzidos no VS 2012, você pode publicar com a seguinte linha de comando:

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

Para mais informações sobre os parâmetros, consulte isso .

Os valores para o /p:VisualStudioVersionparâmetro dependem da sua versão do Visual Studio. A Wikipedia possui uma tabela de lançamentos do Visual Studio e suas versões .

Chris
fonte
6
Usando o VS2012 .NET 3.5, isso não funcionou para implantar no sistema de arquivos. Simplesmente cria e não implementa.
Jay Sullivan
2
seu /p:VisualStudioVersion=11.0 salvou minha vida. Eu uso /p:VisualStudioVersion=12.0 para vs2013 e funciona bem.
Seyed Morteza Mousavi
Qual será o valor /p:VisualStudioVersion=?para o VS 2017?
Nishant
criou o script de compilação 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 ...... Mas ainda obtendo apenas DLLs, nem todos os arquivos como na pasta de publicação: (`
Nishant
@Nishant Para o VS 2017, use /p:VisualStudioVersion=15. Não tenho certeza se isso está relacionado ao seu problema de cópia de arquivo.
Chris
38

Eu vim com essa solução, funciona muito bem para mim:

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

O molho secreto é o destino _WPPCopyWebApplication.

Alexander Beletsky
fonte
1
O que é o _WPPCopyWebApplication e como posso usá-lo arquivo de configuração do MSBbuild xml /
#
4
Usando o VS2012 .NET 3.5, recebi o erro error MSB4057: The target "_WPPCopyWebApplication" does not exist in the project. Tirando essa parte levou a uma implantação sem implantar qualquer opinião
Jay Sullivan
Pode ser necessário chamá-lo com um /p:VisualStudioVersion=12.0 diferente, porque o build usa os destinos de c: \ arquivos de programas (x86) \ msbuild \ microsoft \ visualstudio \ VERSION \ Webapplication \ Microsoft.WebApplication.targets, então talvez esteja usando um versão mais antiga que não tem o destino correto.
Jim Wolff
@FRoZeN Tentei usar o MSBuild como 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. Isso me dá um erro MSBUILD : error MSB1008: Only one project can be specified. Switch: WebSite/New. Existe uma solução para isso?
Nevin Raj Victor
1
@NevinRajVictor esse erro provavelmente é porque você tem um espaço no valor DeployIisAppPath. Você precisará colocar o valor entre aspas. eg / p: DeployIisAppPath = "Site Padrão / Novo"
shiitake
27

Como não conheço o TeamCity, espero que isso funcione para você.

A melhor maneira que encontrei para fazer isso é com o MSDeploy.exe. Isso faz parte do projeto WebDeploy, executado pela Microsoft. Você pode baixar os bits aqui .

Com o WebDeploy, você executa a linha de comando

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

Isso faz o mesmo que o comando VS Publish, copiando apenas os bits necessários para a pasta de implantação.

Jeff Siver
fonte
Isso parece promissor. No entanto, parece que o Serviço de Gerenciamento está disponível apenas no Server 2008. Meu servidor de armazenamento temporário (onde desejo automatizar a implantação) está executando o Windows 7 Pro.
jrummell
2
Existem duas peças no produto. As partes integradas diretamente no IIS requerem o Server 2008. O componente de linha de comando não possui esse requisito; Eu o tenho em execução em uma caixa do Server 2003 usada nas implantações.
Jeff Siver
Eu fiz algumas leituras no MSDeploy. Eu o instalei e estou trabalhando no meu servidor de teste, obrigado! Posso executar o MSDeploy a partir de um script MSBuild?
jrummell
1
faz o mesmo que qual configuração do comando VS Publish? Qual método de publicação - sistema de arquivos ou outro? Ele usa o arquivo MyProject.Publish.xml para determinar quais arquivos copiar?
Anthony
1
Acabei de testar, mas não fez o mesmo que o VS Publish. Ele fez o mesmo que o XCopy, incluindo todos os arquivos de origem.
Louis Somers
13

Com o VisualStudio 2012, há uma maneira de lidar com o assunto sem publicar perfis. Você pode passar a pasta de saída usando parâmetros. Ele funciona com caminho absoluto e relativo no parâmetro 'publishUrl'. Você pode usar o VS100COMNTOOLS, mas precisa substituir o VisualStudioVersion para usar o destino 'WebPublish' %ProgramFiles%\MSBuild\Microsoft\VisualStudio\v11.0\WebApplications\Microsoft.WebApplication.targets. Com o VisualStudioVersion 10.0, este script será bem-sucedido sem saídas :)

Atualização: consegui usar esse método em um servidor de compilação com apenas o Windows SDK 7.1 instalado (sem o Visual Studio 2010 e 2012 em uma máquina). Mas eu tive que seguir estas etapas para fazê-lo funcionar:

  1. Atualize o Windows SDK 7.1 em uma máquina usando a resposta do Simmo ( https://stackoverflow.com/a/2907056/2164198 )
  2. Definindo a chave do Registro HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ VisualStudio \ SxS \ VS7 \ 10.0 para "C: \ Arquivos de programas \ Microsoft Visual Studio 10.0 \" (use seu caminho conforme apropriado)
  3. Copiando a pasta% ProgramFiles% \ MSBuild \ Microsoft \ VisualStudio \ v11.0 da minha máquina do desenvolvedor para criar o servidor

Roteiro:

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%
Ivan Samygin
fonte
Obrigado por esta solução - era isso que eu estava procurando: a opção WebPublish com a implantação do sistema de arquivos.
Woohoo
12

encontrou duas soluções diferentes que funcionavam de maneira ligeiramente diferente:

1. Esta solução é inspirada na resposta de alexanderb [link] . Infelizmente, não funcionou para nós - algumas dlls não foram copiadas para o OutDir. Descobrimos que a substituição ResolveReferencespelo Builddestino resolve o problema - agora todos os arquivos necessários são copiados no local do OutDir.

msbuild / target: Build; _WPPCopyWebApplication / p: Configuration = Release; OutDir = C: \ Tmp \ myApp \ MyApp.csproj
A desvantagem dessa solução foi o fato de o OutDir conter não apenas arquivos para publicação.

2. A primeira solução funciona bem, mas não como esperávamos. Queríamos ter a funcionalidade de publicação como está no Visual Studio IDE - ou seja, apenas os arquivos que devem ser publicados serão copiados no diretório Saída. Como já foi mencionado, a primeira solução copia muito mais arquivos no OutDir - o site para publicação é armazenado em_PublishedWebsites/{ProjectName} subpasta. O comando a seguir resolve isso - apenas os arquivos para publicação serão copiados para a pasta desejada. Então agora você tem um diretório que pode ser publicado diretamente - em comparação com a primeira solução, você economizará espaço no disco rígido.

msbuild / target: Build; PipelinePreDeployCopyAllFilesToOneFolder / p: Configuration = Release; _PackageTempDir = C: \ Tmp \ myApp \; AutoParameterizationWebConfigConnectionStrings = false MyApp.csproj
AutoParameterizationWebConfigConnectionStrings=falseO parâmetro garantirá que as cadeias de conexão não sejam tratadas como artefatos especiais e serão geradas corretamente - para obter mais informações, consulte o link .

Pavel Cermak
fonte
Sua opção nº 2 me ajudou a me livrar completamente do obsoleto _CopyWebApplication. Você resgatou meu Build-Server após a atualização para o VS 2015. Ótima pesquisa. Apreciativo.
it3xl
Sua opção 2 foi perfeita para o meu script de construção.
AnthonyVO 24/03
3

Você deve definir seus ambientes

  • <Nome do site>
  • <domínio>

e referência meu blog. (desculpe post foi coreano)

  • 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
Kim Ki Won
fonte
1

Este meu arquivo em lote

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
Alim İŞÇİ
fonte
5
Seria ótimo se você pudesse detalhar sua resposta. Como exatamente o seu arquivo em lotes resolve o problema do OP? Obrigado!
Luís Cruz
1

este é o meu lote de trabalho

publique meu site.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%

Observe que eu instalei o Visual Studio no servidor para poder executar MsBuild.exeporque as MsBuild.exepastas .Net Framework não funcionam.

Alper Ebicoglu
fonte
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 ...... Mas ainda estou recebendo apenas DLLs e não a estrutura de arquivos que eu quero. O que há de errado com isso? :(
Nishant
1

Você pode publicar a solução com o caminho desejado pelo código abaixo. Aqui PublishInDFolder é o nome que possui o caminho em que precisamos publicar (precisamos criar isso na foto abaixo)

Você pode criar um arquivo de publicação como este

Adicione abaixo de 2 linhas de código no arquivo em lotes (.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
fonte
0

Para gerar a saída de publicação, forneça mais um parâmetro. msbuild example.sln / p: publishprofile = nome do perfil / p: deployonbuild = true / p: configuration = debug / ou qualquer

Yashwant Mahawar
fonte