.net - MsBuild y MsDeploy con mĂșltiples entornos
asp.net-mvc-2 package (2)
¿Existen buenos patrones para asignar configuraciones de soluciones a entornos y usar MsDeploy para empaquetar por entorno?
Versión más corta: tome este archivo e intente cambiar el archivo .msbuild para que se cree un paquete.
Detalles
Tengo una solución con una gran cantidad de bibliotecas y una aplicación ASP.NET MVC. Dirijo la compilación con un archivo msbuild que llama a la solución principal y luego hace otras cosas. Quiero usar el nuevo paquete msdeploy para preparar un archivo .zip para su posterior distribución, pero tengo varias dificultades.
Mi solución tiene 4 configuraciones: Local
, Dev
, Test
y Prod
, que coinciden con los entornos a los que quiero asignarme. En esa solución, todas las bibliotecas tienen modos de Debug
y Release
como de costumbre. Por ejemplo, en el modo de solución Local
, todas las bibliotecas compilan en modo Debug
. Entonces, la aplicación principal tiene entornos coincidentes con la solución, de modo que pueda tener Web.Dev.config
y demás, lo que parece ser la forma natural de usar las cosas.
Si paquete así:
<Target Name="BuildWebPackage">
<MSBuild Projects="../Publisher/Site/Site.vbproj"
Targets="Package"/>
</Target>
Me sale un problema donde la Configuration=Local
se asigna incorrectamente a los proyectos de la biblioteca a los que Site.vbproj
referencia Site.vbproj
, y no puede compilarlos.
Veo dos soluciones posibles: una no puedo trabajar bien y la otra es extremadamente fea.
Intento 1
Intento llamar al objetivo del Package
a través de la solución (en este ejemplo, "Aplicaciones" es la carpeta de la solución en la que se encuentra el proyecto del Sitio ... He simplificado las cosas para esta publicación porque en realidad hay varias aplicaciones en la solución. )
<Target Name="BuildWebPackage">
<MSBuild Projects="../Publisher/Publisher.sln"
Targets="Applications/Site:Package"/>
</Target>
Creo que esta SolutionFolder/ProjectName:Target
sintaxis de SolutionFolder/ProjectName:Target
es cómo hacer esto, porque :Clean
ejecuta ... sin embargo, esto arroja
error MSB4057: The target "Applications/Site:Package" does not exist in the project.
Intento 2
Ahora, para la solución fea: funciona si modifico TODAS mis bibliotecas para tener 4 configuraciones adicionales para esas 4 configuraciones de solución. Sin embargo, esto es feo y realmente un mal plan si quiero co-desarrollar una biblioteca compartida más tarde con un proyecto que tiene diferentes entornos. Además, esos entornos no tienen nada que ver con la biblioteca y solo tienen sentido en el contexto de las aplicaciones de nivel superior que usan las bibliotecas. Sabe mal.
¿Huh?
Me gusta tener los múltiples entornos en la solución, y el nuevo y sofisticado reemplazo de Web.config, pero no sé cómo llamar a la tarea del Package
msdeploy en esta situación para poder construir el paquete en TeamCity.
(Tenga en cuenta que probablemente NO deseo llamar a la línea de comandos de msdeploy, porque se usa para convertir una aplicación IIS en un paquete. No es lo que estoy haciendo aquí).
Muestra
Una vez más, he quedado completamente perplejo aquí, así que si quieres ayudar a experimentar, he reunido esta solución de muestra .
El primer intento falló porque el objetivo del paquete no existe en el archivo de la solución. Al usar MSBuild en un archivo de solución, se crea un proyecto temporal de MSBuild ( SamplePackage.sln.metaproj ); este archivo de proyecto contiene solo algunos objetivos ( compilar , limpiar , reconstruir , publicar , ...)
Solución: las propiedades DeployOnBuild & DeployTarget
Una forma de hacer lo que desea es usar la propiedad DeployOnBuild de esta manera:
<PropertyGroup Condition="''$(Configuration)'' == ''''">
<Platform>Any Cpu</Platform>
<Configuration>Dev</Configuration>
<PackageLocation>$(MSBuildProjectDirectory)/package.zip</PackageLocation>
</PropertyGroup>
<Target Name="Build">
<MSBuild Projects="SamplePackage.sln"
Targets="Build"/>
</Target>
<Target Name="BuildWebPackage">
<MSBuild Projects="SamplePackage.sln"
Properties="Platform=$(Platform);
Configuration=$(Configuration);
DeployOnBuild=true;
DeployTarget=Package;
PackageLocation=$(PackageLocation);"/>
</Target>
- DeployOnBuild = true : la implementación se debe realizar cuando se llama Build
- DeployTarget = Paquete : para la implementación crea un paquete
- PackageLocation : indica la ruta de archivo del archivo del paquete
Enlaces adicionales:
He hecho algo similar que puede ser útil. En un proyecto reciente, teníamos entornos ''Dev'', ''Test'' y ''Prod''.
Agregué configuraciones de solución para cada uno de estos ... ej.
- Release-Dev
- Prueba de lanzamiento
- Release-Prod
Para la mayoría de los proyectos en la solución, estas configuraciones solo estaban vinculadas a la versión normal de ''Lanzamiento'', pero cuando era apropiado, algunos proyectos tenían distintas configuraciones de compilación ''Release-Test'' donde podría haber # if / # endif cosas en el código.
Esto también tendría sentido para permitir la personalización de su configuración de msdeploy por configuración también.
Respecto al objetivo de msbuild. El destino se refiere al nombre de un elemento. por ejemplo, puede llamar a msbuild con / t: BuildWebPackage para su ejemplo anterior.