Avec TFS 2010, on crée souvent une définition de Build spécifique qui permet non seulement de vérifier l’intégration continue, mais également de préparer les éléments obtenus en sortie de compilation (Packaging), voire même de déployer ces éléments.
Si le Workflow 4 du template de Build permet d’effectuer ces étapes assez aisément , il est parfois intéressant de ramener cette étape de packaging au niveau de la compilation de la solution. Ce faisant, il est alors possible de générer le package à la fois côté serveur, et à la fois côté client.
Dans le cas où le packaging est configurable par projet, les évènements PreBuild et PostBuild des projets sont suffisants. Dans le cas par contre où le packaging nécessite d’effectuer des actions avant ou après la compilation de l’ensemble de la solution, des évènements PreBuild et PostBuild de la solution sont nécessaires.
Cas d’évènements spécifiques à une Solution Visual Studio :
Pour enregistrer des évènements avant la prise en compte du fichier .sln d’une Solution Visual Studio, il est possible de créer un fichier appelé before.NomDeLaSolution.sln.targets situé au même niveau que le fichier .sln Celui-ci peut alors contenir des instructions MSBuild telles que :
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="PreBuildPackaging" BeforeTargets="Build">
<Message Text="PreBuildPackaging..." Importance="high" />
<!-- Some MSBuild instructions: Copy, Move, Zip, Exe, etc. -->
</Target>
</Project>
(Pour obtenir une liste complète des activités MSBuild disponibles : http://msdn.microsoft.com/fr-fr/library/7z253716(v=vs.100).aspx)
L’enregistrement d’évènements après la prise en compte du fichier .sln d’une solution Visual Studio s’effectuera de manière similaire : Il faut créer un fichier appelé after.NomDeLaSolution.sln.targets situé au même niveau que le fichier .sln. Exemple de fichier :
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="PostBuildPackaging" AfterTargets="Build">
<Message Text="PostBuildPackaging..." Importance="high" />
<!-- Some MSBuild instructions: Copy, Move, Zip, Exe, etc. -->
</Target>
</Project>
Note : Pour les plus familiers du scripting MSBuild, ces évènements s’effectueront avant ou après une compilation ayant pour target Build. Pour gérer des dépendances entre les targets, il est possible d’utiliser l’attribut DependsOnTargets en lieu et place de AfterTargets ou BeforeTargets.
Pour pouvoir déclencher l’exécution de ces évènements, il suffit ensuite d’appeler le Visual Studio Command Prompt et de lancer la command MSBuild sur le fichier .sln :
(1) Commande MSBuild de compilation simple (2) Èvènement PreBuild de la Solution Visual Studio (3) Évènement PostBuild de la Solution Visual Studio
Note : Dans l’exemple ci-dessus, des fichiers before.ConsoleApplication9.sln.targets et after.ConsoleApplication9.sln.targets ont été créé au préalable
Pour reproduire ce packaging du côté de TFS, il suffit d’ajouter ces fichiers au contrôle de code source pour que ceux-ci soient pris en compte lors de la compilation MSBuild effectuée par les Agents de Build !
Cas d’évènements communs à toutes les Solutions Visual Studio :
/!\ Attention, les évènements MSBuild globaux sont à manipuler avec précautions car les modifications peuvent impacter toutes les solutions compilées sur l’ordinateur (Compilation MSBuild, compilation TFS)
Pour ajouter des évènements à toutes les Solutions Visual Studio compilées sur un ordinateur précis, cette fois-ci il faut se rendre du côté de : C:\Program Files (x86)\MSBuild. Il faut ensuite y créer des dossiers pour reproduire l’arborescence suivante : C:\Program Files (x86)\MSBuild\4.0\SolutionFile\ImportBefore.
Tout fichier ajouté dans ce répertoire (peu importe l’extension du fichier) est pris en compte lors de l’appel de la commande MSBuild.exe sur un fichier .sln.
En reprenant l’exemple précédent, en lieu et place de deux fichiers .targets, il est possible d’ajouter au répertoire ImportBefore un fichier AllSolutions.Packaging.proj. Ce fichier contient :
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="PreBuildPackaging" BeforeTargets="Build">
<Message Text="PreBuildPackaging..." Importance="high" />
<!-- Some MSBuild instructions: Copy, Move, Zip, Exe, etc. -->
</Target>
<Target Name="PostBuildPackaging" AfterTargets="Build">
<Message Text="PostBuildPackaging..." Importance="high" />
<!-- Some MSBuild instructions: Copy, Move, Zip, Exe, etc. -->
</Target>
</Project>
Le résultat obtenu lors de la compilation de la solution est le même. Cependant ce packaging est également disponible pour toutes les autres solutions si la compilation est lancée depuis l’ordinateur qui possède ce répertoire ImportBefore !
Dans un environnement TFS, plus besoin de mettre dans le contrôle de code source des fichier pour le packaging, mais il faudra par contre déployer le répertoire ImporteBefore et son contenu sur tous les Agents de Build qui doivent pouvoir exécuter le “packaging”.