web-dev-qa-db-fra.com

Publiez un projet Web à partir d'une solution avec msbuild

J'essaie de déployer l'un des projets Web de ma solution sur un serveur. J'utilise msbuild sur TeamCity comme ceci:

msbuild MySolution.sln /t:WebSite:Rebuild /p:DeployOnBuild=True /p:PublishProfile=Prod ...

Cependant, lorsque je l'exécute, msbuild essaie toujours de construire mon projet WebService, même si mon projet WebSite n'en dépend pas (mais il dépend d'un projet Services également dans la solution). Comment publier un seul projet, alias juste WebSite?

J'ai également essayé de créer le fichier de projet en utilisant

msbuild WebSite/WebSite.csproj /p:DeployOnBuild=True ...

mais il se plaint alors de ne pas pouvoir restaurer les packages:

[07:47:17]WebSite\WebSite.csproj.teamcity: Build target: Build
[07:47:17][WebSite\WebSite.csproj.teamcity] RestorePackages
[07:47:17][RestorePackages] Exec
[07:47:17][Exec] C:\TeamCity\buildAgent\work\cab8a3d752df3a51\.nuget\NuGet.targets(90, 15): error MSB4064: The "LogStandardErrorAsError" parameter is not supported by the "Exec" task. Verify the parameter exists on the task, and it is a settable public instance property.
[07:47:17][Exec] C:\TeamCity\buildAgent\work\cab8a3d752df3a51\.nuget\NuGet.targets(89, 9): error MSB4063: The "Exec" task could not be initialized with its input parameters. 
[07:47:17][WebSite\WebSite.csproj.teamcity] Project WebSite\WebSite.csproj.teamcity failed.

Lorsque je désactive la restauration du package NuGet, CoreCompile (Csc) échoue avec des erreurs dont je n'ai jamais entendu parler et ne devrait pas se produire:

[07:54:43]WebSite\WebSite.csproj.teamcity: Build target: Build (13s)
[07:54:55][WebSite\WebSite.csproj.teamcity] CoreCompile
[07:54:55][CoreCompile] Csc
[07:54:56][Csc] Areas\Api\Services\TripService.cs(19, 104): error CS0241: Default parameter specifiers are not permitted
[07:54:56][Csc] Helpers\StatisticsUtility.cs(11, 35): error CS1031: Type expected
[07:54:56][Csc] Helpers\StatisticsUtility.cs(11, 53): error CS1002: ; expected
[07:54:56][Csc] Helpers\StatisticsUtility.cs(16, 28): error CS1519: Invalid token '(' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(16, 37): error CS1519: Invalid token ',' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(17, 27): error CS1519: Invalid token '(' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(17, 32): error CS1519: Invalid token ')' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(23, 17): error CS1519: Invalid token 'for' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(23, 26): error CS1519: Invalid token '<=' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(23, 45): error CS1519: Invalid token '-' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(23, 51): error CS1519: Invalid token '++' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(24, 34): error CS0270: Array size cannot be specified in a variable declaration (try initializing with a 'new' expression)
[07:54:56][Csc] Helpers\StatisticsUtility.cs(24, 37): error CS1519: Invalid token '==' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(24, 51): error CS1519: Invalid token ')' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(24, 63): error CS1519: Invalid token '++' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(25, 41): error CS1519: Invalid token '>' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(25, 53): error CS1519: Invalid token ')' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(27, 36): error CS1519: Invalid token '=' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(27, 48): error CS1519: Invalid token ';' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(28, 36): error CS1519: Invalid token '=' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(29, 37): error CS1519: Invalid token '=' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(29, 48): error CS0270: Array size cannot be specified in a variable declaration (try initializing with a 'new' expression)
[07:54:56][Csc] Helpers\StatisticsUtility.cs(29, 50): error CS1519: Invalid token ';' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(30, 33): error CS1519: Invalid token '=' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(30, 44): error CS0270: Array size cannot be specified in a variable declaration (try initializing with a 'new' expression)
[07:54:56][Csc] Helpers\StatisticsUtility.cs(30, 50): error CS1519: Invalid token ';' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\StatisticsUtility.cs(32, 21): error CS0116: A namespace does not directly contain members such as fields or methods
[07:54:56][Csc] Helpers\StatisticsUtility.cs(35, 50): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\StatisticsUtility.cs(38, 21): error CS0116: A namespace does not directly contain members such as fields or methods
[07:54:56][Csc] Helpers\StatisticsUtility.cs(40, 50): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\StatisticsUtility.cs(42, 21): error CS1022: Type or namespace definition, or end-of-file expected
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(8, 59): error CS1031: Type expected
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(8, 80): error CS1002: ; expected
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(10, 55): error CS1519: Invalid token '(' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(10, 60): error CS1520: Class, struct, or interface method must have a return type
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(10, 82): error CS1002: ; expected
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(13, 23): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(15, 60): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(18, 23): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(20, 25): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(23, 28): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(26, 28): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(29, 24): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(29, 84): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(32, 28): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(35, 9): error CS1022: Type or namespace definition, or end-of-file expected
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(23, 26): error CS0101: The namespace '<global namespace>' already contains a definition for '?'
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(26, 26): error CS0101: The namespace '<global namespace>' already contains a definition for '?'
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(29, 22): error CS0101: The namespace '<global namespace>' already contains a definition for '?'
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(29, 83): error CS0101: The namespace '<global namespace>' already contains a definition for '?'
[07:54:56][Csc] Helpers\UrlHelperExtensions.cs(32, 26): error CS0101: The namespace '<global namespace>' already contains a definition for '?'
[07:54:56][Csc] Controllers\SessionController.cs(13, 51): error CS0241: Default parameter specifiers are not permitted
[07:54:56][Csc] Helpers\JsonNetResult.cs(13, 44): error CS1031: Type expected
[07:54:56][Csc] Helpers\JsonNetResult.cs(13, 72): error CS1041: Identifier expected, 'object' is a keyword
[07:54:56][Csc] Helpers\JsonNetResult.cs(13, 91): error CS1002: ; expected
[07:54:56][Csc] Helpers\JsonNetResult.cs(16, 38): error CS1519: Invalid token '=' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\JsonNetResult.cs(16, 59): error CS1519: Invalid token ';' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\JsonNetResult.cs(17, 64): error CS1519: Invalid token '=' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\JsonNetResult.cs(17, 90): error CS1519: Invalid token ';' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\JsonNetResult.cs(18, 32): error CS1519: Invalid token '=' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\JsonNetResult.cs(18, 46): error CS1519: Invalid token ';' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\JsonNetResult.cs(19, 33): error CS1519: Invalid token ';' in class, struct, or interface member declaration
[07:54:56][Csc] Helpers\JsonNetResult.cs(22, 23): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\JsonNetResult.cs(25, 37): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\JsonNetResult.cs(32, 23): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\JsonNetResult.cs(35, 37): error CS1518: Expected class, delegate, enum, interface, or struct
[07:54:56][Csc] Helpers\JsonNetResult.cs(40, 9): error CS1022: Type or namespace definition, or end-of-file expected
[07:54:56][Csc] Mailers\ITripMailer.cs(13, 132): error CS0241: Default parameter specifiers are not permitted
[07:54:56][Csc] Mailers\TripMailer.cs(54, 85): error CS0241: Default parameter specifiers are not permitted
[07:54:56][Csc] Services\Impl\AuthorizationService.cs(12, 70): error CS0241: Default parameter specifiers are not permitted
[07:54:56][Csc] Services\Impl\AuthorizationService.cs(43, 77): error CS0241: Default parameter specifiers are not permitted
[07:54:56][WebSite\WebSite.csproj.teamcity] Project WebSite\WebSite.csproj.teamcity failed.
36
Caleb Jares

J'ai blogué à ce sujet sur http://sedodream.com/2013/03/06/HowToPublishOneWebProjectFromASolution.aspx il y a quelques mois. J'ai également copié les détails ici, voir ci-dessous.


Aujourd'hui sur Twitter @ nunofcosta m'a posé à peu près la question "Comment publier un projet Web à partir d'une solution qui en contient plusieurs?"

Le problème qu'il rencontre est qu'il crée à partir de la ligne de commande et transmet les propriétés suivantes à msbuild.exe.

/p:DeployOnBuild=true
/p:PublishProfile='siteone - Web Deploy'
/p:Password=%password%

Vous pouvez en savoir plus sur la façon d'automatiser la publication sur http://sedodream.com/2013/01/06/CommandLineWebProjectPublishing.aspx .

Lorsque vous transmettez ces propriétés à msbuild.exe, elles sont appelées propriétés globales. Ces propriétés sont difficiles à remplacer et sont transmises à chaque projet créé. De ce fait, si vous avez une solution avec plusieurs projets Web, lorsque chaque projet Web est créé, il est transmis dans le même ensemble de propriétés. De ce fait, lorsque chaque projet est construit, le processus de publication de ce projet démarre et il s'attend à trouver un fichier nommé siteone - Web Deploy.pubxml dans le dossier * Properties\PublishProfiles *. Si le fichier n'existe pas, l'opération peut échouer.

Remarque: Si vous souhaitez utiliser cette technique pour une publication orchestrée, consultez mes commentaires sur https://stackoverflow.com/a/14231729/105999 avant de le faire. .

Alors, comment pouvons-nous résoudre ce problème?

Jetons un œil à un exemple (voir les liens ci-dessous). J'ai une solution, PublishOnlyOne , avec les projets suivants.

  1. ProjA
  2. ProjB

ProjA a un profil de publication nommé ‘ siteone - Web Deploy ’, pas ProjB. Lorsque vous essayez de publier cela, vous pouvez essayer la ligne de commande suivante.

msbuild.exe PublishOnlyOne.sln /p:DeployOnBuild=true /p:PublishProfile=’siteone – Web Deploy’ /p:Password=%password%

Voir publish-sln.cmd dans les exemples.

Si vous faites cela, quand il sera temps de construire ProjB, il échouera car il n'y a pas siteone - profil Web Deploy pour ce projet. Pour cette raison, nous ne pouvons pas passer DeployOnBuild. Voici plutôt ce que nous devons faire.

  1. Modifiez ProjA.csproj pour définir une autre propriété qui définira conditionnellement DeployOnBuild
  2. Depuis la ligne de commande, passez cette propriété

J'ai modifié ProjA et ajouté le groupe de propriétés suivant avant les instructions d'importation dans le fichier .csproj.

<PropertyGroup>
<DeployOnBuild Condition=" '$(DeployProjA)'!='' ">$(DeployProjA)</DeployOnBuild>
</PropertyGroup>

Ici, vous pouvez voir que DeployOnBuild est défini sur la valeur de DeployProjA tant qu'elle n'est pas vide. Maintenant, la commande révisée est:

msbuild.exe PublishOnlyOne.sln /p:DeployProjA=true /p:PublishProfile=’siteone – Web Deploy’ /p:Password=%password%

Ici, au lieu de passer DeployOnBuild, je passe dans DeployProjA qui définira ensuite DeployOnBuild. Étant donné que DeployOnBuild n'a pas été transmis à ProjB, il ne tentera pas de publier.

Vous pouvez trouver l'exemple complet sur https://github.com/sayedihashimi/sayed-samples/tree/master/PublishOnlyOne .

59

Il existe une solution beaucoup plus simple pour cela. MSBuild prend en charge le ciblage d'un seul projet lors de la création de la solution. Pour ce faire, placez le nom du projet dans le paramètre Target. Notez qu'il s'agit du nom visuel du projet que vous spécifiez dans la solution (pas nécessairement le même que le nom du fichier .csproj).

Remarque: La seule "astuce" nécessaire ici est de remplacer les points (.) Dans le nom du projet par des traits de soulignement (_) .

Exemple de ligne de commande MSBuild, si le nom de votre projet est "Your.Project.Name":

msbuild.exe YourSolutionName.sln /T:"Your_Poject_Name" /P:DeployOnBuild=true /P:PublishProfile=YourPublishProfile.pubxml

Vous pouvez également spécifier une cible de génération pour ce projet, mais cette cible doit exister pour tous les projets de la solution:

msbuild.exe YourSolutionName.sln /T:"Your_Poject_Name:Rebuild" /P:DeployOnBuild=true /P:PublishProfile=YourPublishProfile.pubxml

Sources

  1. Cela est partiellement documenté dans MSDN depuis Visual Studio 2008: https://msdn.Microsoft.com/en-us/library/ms164311 (v = vs.140) .aspx
  2. Un merci spécial à Vasil Trifonov pour avoir souligné l'astuce de remplacement: http://www.codeproject.com/Articles/654910/How-to-build-a-specific-project-from-a-solution-wi
25
arni