c# - Usar msbuild para ejecutar un perfil de publicación del sistema de archivos
visual-studio publish (5)
Encontré la respuesta aquí: http://www.digitallycreated.net/Blog/59/locally-publishing-a-vs2010-asp.net-web-application-using-msbuild
Visual Studio 2010 tiene excelentes nuevas funciones de publicación de aplicaciones web que le permiten publicar fácilmente su proyecto de aplicación web con un clic de un botón. Detrás de escena, la transformación de Web.config y la construcción de paquetes se realiza mediante un script masivo de MSBuild que se importa en su archivo de proyecto (se encuentra en: C: / Archivos de programa (x86) / MSBuild / Microsoft / VisualStudio / v10.0 / Web / Microsoft .Web.Publishing.targets). Desafortunadamente, el guión es enormemente complicado, desordenado e indocumentado (a parte de algunos comentarios mal escritos y casi inútiles en el archivo). Un gran diagrama de flujo de ese archivo y alguna documentación sobre cómo engancharlo sería agradable, pero parece que lamentablemente falta (o al menos no puedo encontrarlo).
Desafortunadamente, esto significa que realizar publicaciones a través de la línea de comandos es mucho más opaco de lo que debe ser. Me sorprendió la falta de documentación en esta área, porque en la actualidad muchas tiendas usan un servidor de integración continua y algunas incluso realizan una implementación automatizada (que las características de publicación VS2010 podrían ayudar mucho), así que habría pensado que esto ( ¡fácilmente!) habría sido un requisito bastante importante para la función.
De todos modos, después de hurgar en el archivo Microsoft.Web.Publishing.targets durante horas y golpear mi cabeza contra el muro de prueba y error, me las he arreglado para descubrir cómo Visual Studio parece realizar su magia con un clic en "Publicar en el sistema de archivos" y características de "Build Deployment Package". Entraré en un poco de secuencias de comandos de MSBuild, así que si no está familiarizado con MSBuild, le sugiero que consulte esta página MSDN del curso acelerado.
Publicar en el sistema de archivos
El cuadro de diálogo Publicar en sistema de archivos VS2010 Publicar en sistema de archivos me llevó un tiempo desactualizarme porque esperaba que se produjera algún uso sensato de MSBuild. En cambio, VS2010 hace algo bastante extraño: pide a MSBuild que realice una especie de medio despliegue que prepara los archivos de la aplicación web en la carpeta obj de su proyecto, luego parece hacer una copia manual de esos archivos (es decir, fuera de MSBuild) en su carpeta de publicación de destino. Este es realmente un comportamiento sorprendente porque MSBuild está diseñado para copiar archivos (y otras cosas relacionadas con la construcción), por lo que tendría sentido si todo el proceso fuera solo un objetivo MSBuild invocado por VS2010, no un objetivo sino una copia manual.
Esto significa que hacer esto a través de MSBuild en la línea de comandos no es tan simple como invocar el archivo de proyecto con un objetivo en particular y establecer algunas propiedades. Tendrá que hacer lo que VS2010 debería haber hecho: cree usted mismo un objetivo que realice la mitad del despliegue y luego copie los resultados en la carpeta de destino. Para editar su archivo de proyecto, haga clic derecho en el proyecto en VS2010 y haga clic en Descargar proyecto, luego haga clic con el botón secundario y haga clic en Editar. Desplácese hacia abajo hasta encontrar el elemento Importar que importa los destinos de la aplicación web (Microsoft.WebApplication.targets; este archivo importa el archivo Microsoft.Web.Publishing.targets mencionado anteriormente). Debajo de esta línea agregaremos nuestro nuevo objetivo, llamado PublishToFileSystem:
<Target Name="PublishToFileSystem"
DependsOnTargets="PipelinePreDeployCopyAllFilesToOneFolder">
<Error Condition="''$(PublishDestination)''==''''"
Text="The PublishDestination property must be set to the intended publishing destination." />
<MakeDir Condition="!Exists($(PublishDestination))"
Directories="$(PublishDestination)" />
<ItemGroup>
<PublishFiles Include="$(_PackageTempDir)/**/*.*" />
</ItemGroup>
<Copy SourceFiles="@(PublishFiles)"
DestinationFiles="@(PublishFiles->''$(PublishDestination)/%(RecursiveDir)%(Filename)%(Extension)'')"
SkipUnchangedFiles="True" />
</Target>
Este objetivo depende del destino PipelinePreDeployCopyAllFilesToOneFolder, que es a lo que VS2010 llama antes de realizar su copia manual. Algunas búsquedas en Microsoft.Web.Publishing.targets muestran que llamar a este destino hace que los archivos del proyecto se coloquen en el directorio especificado por la propiedad _PackageTempDir.
La primera tarea que llamamos en nuestro objetivo es la tarea Error, sobre la cual hemos colocado una condición que garantiza que la tarea solo ocurra si no se ha establecido la propiedad PublishDestination. Esto lo atrapará y producirá un error al compilar en caso de que haya olvidado especificar la propiedad PublishDestination. Luego llamamos a la tarea MakeDir para crear ese directorio PublishDestination si aún no existe.
Luego definimos un elemento llamado PublishFiles que representa todos los archivos encontrados en la carpeta _PackageTempDir. A continuación, se llama a la tarea Copiar, que copia todos esos archivos en la carpeta Destino de publicación. El atributo DestinationFiles en el elemento Copiar es un poco complejo; realiza una transformación de los elementos y convierte sus rutas en nuevas rutas enraizadas en la carpeta PublishDestination (consulte Metadatos bien conocidos para ver qué significan esos% () s).
Para llamar a este objetivo desde la línea de comandos, ahora podemos simplemente realizar este comando (obviamente cambiando el nombre y las propiedades del archivo del proyecto a su medida):
msbuild Website.csproj "/p:Platform=AnyCPU;Configuration=Release;PublishDestination=F:/Temp/Publish" /t:PublishToFileSystem
Tengo el proyecto ac # .Net 4.0 creado con VS2010 y al que se puede acceder ahora con VS2012.
Estoy intentando publicar solo los archivos necesarios desde este sitio web a una ubicación de destino (C: / builds / MyProject [Files])
Mi estructura de archivos: ./ProjectRoot/MyProject.csproj ./ProjectRoot/Properties/PublishProfiles/FileSystemDebug.pubxml
Estoy ejecutando lo siguiente a través de MSBuild:
C: / Windows / Microsoft.NET / Framework / v4.0.30319 / MSBuild.exe ./ProjectRoot/MyProject.csproj / p: DeployOnBuild = true /p:PublishProfile=./ProjectRoot/Properties/PublishProfiles/FileSystemDebug.pubxml
Aquí está el xml en FileSystemDebug.pubxml
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>FileSystem</WebPublishMethod>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<ExcludeApp_Data>False</ExcludeApp_Data>
<publishUrl>C:/builds/MyProject/</publishUrl>
<DeleteExistingFiles>True</DeleteExistingFiles>
</PropertyGroup>
</Project>
El comportamiento resultante es:
- un archivo zip se crea aquí: ./ProjectRoot/obj/Debug/Package/MyProject.zip
- No se implementa nada en
<publishUrl>C:/builds/MyProject/</publishUrl>
WTF - el archivo zip que se crea es un desayuno de cerdos y lleno de archivos que no son necesarios para la aplicación.
Cuando ejecuto este perfil de publicación a través de Visual Studio, se crea una carpeta en * C: / builds / MyProject * y contiene los artefactos exactos que quiero.
¿Cómo obtengo este resultado simple de msbuild?
FYI: tuve el mismo problema con Visual Studio 2015. Después de muchas horas intentando, ahora puedo hacer msbuild myproject.csproj /p:DeployOnBuild=true /p:PublishProfile=myprofile
.
Tuve que editar mi archivo .csproj para que funcione. Contenía una línea como esta:
<Import Project="$(MSBuildExtensionsPath32)/Microsoft/VisualStudio/v10.0/WebApplications/Microsoft.WebApplication.targets"
Condition="false" />
Cambié esta línea de la siguiente manera:
<Import Project="$(MSBuildExtensionsPath32)/Microsoft/VisualStudio/v14.0/WebApplications/Microsoft.WebApplication.targets" />
(Cambié 10.0 a 14.0, no estoy seguro de si esto era necesario. Pero definitivamente tuve que eliminar la parte de la condición).
Me parece que su perfil de publicación no se está utilizando y está realizando un empaque predeterminado. Los objetivos de Microsoft Web Publish hacen todo lo que está haciendo arriba, selecciona los objetivos correctos basados en la configuración.
Conseguí que el mío funcionara sin problemas desde el paso TeamCity MSBuild, pero especifiqué una ruta explícita al perfil, solo tienes que llamarlo por nombre sin .pubxml (por ejemplo, FileSystemDebug). Se encontrará siempre y cuando esté en la carpeta estándar, que es la tuya.
Ejemplo:
C:/Windows/Microsoft.NET/Framework/v4.0.30319/MSBuild.exe ./ProjectRoot/MyProject.csproj /p:DeployOnBuild=true /p:PublishProfile=FileSystemDebug
Tenga en cuenta que esto se hizo utilizando las versiones de Visual Studio 2012 de los destinos de Microsoft Web Publish, que normalmente se encuentran en "C: / Archivos de programa (x86) / MSBuild / Microsoft / VisualStudio / v11.0 / Web". Consulte la carpeta de implementación para los tipos de implementación específicos objetivos que se utilizan
Primero compruebe la versión de Visual Studio de la PC desarrolladora que puede publicar la solución (proyecto). como se muestra es para VS 2013
/p:VisualStudioVersion=12.0
agregue la línea de comando anterior para especificar qué tipo de versión de estudio visual debe construir el proyecto. Como respuestas anteriores, esto podría suceder cuando intentamos publicar solo un proyecto, no toda la solución.
Todavía tenía problemas después de probar todas las respuestas anteriores (uso Visual Studio 2013). No se copió nada en la carpeta de publicación.
El problema es que si ejecuto MSBuild con un proyecto individual en lugar de una solución, tengo que poner un parámetro adicional que especifique la versión de Visual Studio:
/p:VisualStudioVersion=12.0
12.0
es para VS2013, reemplace con la versión que usa. Una vez que agregué este parámetro, simplemente funcionó.
La línea de comando completa se ve así:
MSBuild C:/PathToMyProject/MyProject.csproj /p:DeployOnBuild=true /p:PublishProfile=MyPublishProfile /p:VisualStudioVersion=12.0
Lo he encontrado aquí:
http://www.asp.net/mvc/overview/deployment/visual-studio-web-deployment/command-line-deployment
Ellos dicen:
Si especifica un proyecto individual en lugar de una solución, debe agregar un parámetro que especifique la versión de Visual Studio.