Affichage des articles dont le libellé est Team System. Afficher tous les articles
Affichage des articles dont le libellé est Team System. Afficher tous les articles

mardi 4 mai 2010

My WCF application is not called by TFS 2010 Event Service

For TFS 2010 be able to contact your WCF you have to use the WSHttpBinding and you have to specify a bindingConfiguration that disable the security. You can see below what I use for mine.

I hope that will help someone (at least Nicolas M).


ITfsEventSubscriber.cs :


...
[ServiceContract(Namespace = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03")]
public interface ITfsEventSubscriber
{
    [OperationContract(Action = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03/Notify")]
    void Notify(String eventXml, String tfsIdentityXml);
}
...



TfsEventSubscriber.cs :

...
public class TfsEventSubscriber : ITfsEventSubscriber
{
    void ITfsEventSubscriber.Notify(String eventXml, String tfsIdentityXml)
    {
        // My notify code
    }
}
...



Web.config :


...
<system.serviceModel>
    <bindings>
     <wsHttpBinding>
        <binding name="NoSecurity">
         <security mode="None">
         </security>
        </binding>
     </wsHttpBinding>
    </bindings>
    
    <services>
     <service behaviorConfiguration="WcfTfsDeployer.Behavior" name="WcfTfsDeployer.TfsEventSubscriber">
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="NoSecurity" contract="WcfTfsDeployer.ITfsEventSubscriber" />
     </service>
    
    </services>

    <behaviors>
     <serviceBehaviors>
        <behavior name="WcfTfsDeployer.Behavior">
         <serviceMetadata httpGetEnabled="true"/>
         <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
     </serviceBehaviors>
    </behaviors>
</system.serviceModel>



...

lundi 3 mai 2010

What's new with BisSubscribe in TFS 2010

Hi all,

We currently migrating our Team Foundation Server 2008 to TFS 2010 and have some little issues, so I found a solution around BisSubscribe.exe that I want to share with all.

I tried to subscribe our WCF service that intercept the build quality change event to deploy our web sites on diffrent severs. But with using the BisSubscribe.exe syntax I knew with TFS 2008 it's failed with this message :


....
Exception Message: Event type BuildStatusChangeEvent does not exist. (type TeamFoundationServiceException)
...



With TFS 2008 a subscription looked like :

bissubscribe /eventType BuildStatusChangeEvent /address http://myWebServer/MyService/myNotificationService.asmx /deliveryType Soap /server http://tfsserver:8080


For TFS 2010 due to the Team Project Collection the url of the parameter /server is not functionnal and you have to use /collection instead, like this sample :

C:\Program Files\Microsoft Team Foundation Server 2010\Tools>BisSubscribe.exe /eventType BuildStatusChangeEvent /address http://myWebServer/MyService/myNotificationService.asmx /deliveryType Soap /collection http://tfsServer:8080/tfs/MyCollection


Where MyCollection is the Team Project Collection where you want to subscribe. It's appear the /server doesn't work well with all events (like BuildStatusChangeEvent).

I hope that could help someone !

vendredi 19 septembre 2008

Petite introduction sur DbPro de Visual Studio Team System

Me voici sur un nouveau sujet, assez palpitant puisqu'enfin les développeurs vont pouvoir gérer leurs scripts de bases de données en même temps et au même endroit (Visual Studio) que les sources de leur application. Ce sujet est donc DbPro disponible dans la version Team System de Visual Studio.

Voici, après quelques heures d'utilisation, ce que propose DbPro.
Grace à DbPro nous pouvons "aspirer" le modèle de notre base de données existante et Visual Studio nous créer un projet DbPro qui cohabite avec nos autres projets de la solution et qui contient les scripts de tous les objets de notre base de données (table, vues, user, procédures...). Assez génial ! Du coup tous les scripts de la base de données sont sauvegardés dans le serveur de code source de la même manière qu'un fichier CS ou VB. Fini l'écrasement accidentel et la perte définitive d'une procédure stockée qui à prit 5 jours de réalisation, tout est dans le serveur de code source !

DbPro va encore plus loin car il permet d'éditer tous les objets de la base de données dans Visual Studio (plus besoin de Sql Manager Studio, ou presque) et surtout, génère le script de déploiement vers la base de données cible. Ici Microsoft facilite un autre point crucial dans le cycle de développement qu'est le recensement des modifications apportées à une base de données durant une phase de développement.

Dans un contexte d'intégration continu on peut bien sur envisager le déploiement automatique des modifications de base de données à chaque check-in. Il suffit de modifier un peu la déclaration de son serveur de build Team System pour que ce dernier compile le projet Dbpro et déploie les modifications sur le serveur d'intégration ! C'est exactement ce que je mets en place actuellement. C'est plutôt simple à réaliser et les MSDN documentent assez bien le sujet.
Dans mon prochain article je vais ajouter quelques liens pour la mise en oeuvre de DbPro avec Team Build, plus quelques petit tips que j'aurais découvert.

Bien à vous.

mercredi 30 juillet 2008

Créer des tâches personnalisées pour un Team Build

But

Créer une tâche personnalisée qui sera exécutable par un serveur de build Team System.

Pré requis

Configuration de la machine de développement :
La création de build custom task se fait en VB ou en C# dans Visual Studio et se base sur l'API de Team System. Donc il faut un Visual Studio + l'installation du SDK Team System ou plus simple, Visual Studio Team System.

Configuration du serveur de build (Team Build) :
Pour que le serveur de build puisse compiler la documentation du code en se basant sur SandCastle, il faut bien sur installer SandCastle... Logique non ? Allez voir sur http://www.codeplex.com pour avoir la dernière version.
Ensuite il faut installer SandCastleBuilder sur le serveur de build (l'application qui permettra de compiler l'aide grâce à des projets de documentation), voir aussi sur http://www.codeplex.com pour le téléchargement.


Scénario 1 :
Le serveur de build exécute les tâches qui sont définies dans le fichier tfsbuild.proj. Le format de ce fichier de projet est écrit dans le standard MSBuild et propose différentes choses, dont notamment la possibilité d'exécuter une ligne de commande. On va donc pouvoir compiler la documentation de notre code avec SandCastleBuilder (voir pré requis dans le scénario 2) en l'appelant depuis le fichier de projet du team build.

Le code de l'exemple :

<target name="GenerateDocumentation">
<propertygroup>
<sandcastlebuidlerpath>C:\Program Files\EWSoftware\Sandcastle Help File Builder\SandcastleBuilderConsole.exe</sandcastlebuidlerpath>
<sandcastlebuilderprojectfile>..\Sources\DemoDocumentation\DemoDocumentation.shfb</sandcastlebuilderprojectfile>
<sandcastlebuilderarguments>-OutputPath="$(OutDir)\"</sandcastlebuilderarguments>
</propertygroup>
<exec command="">
</exec>

Scénario 2 :
On étudie ici l'ajout d'une tâche qui consiste à compiler la documentation du code avec SandCastleBuilder, après la compilation du code.
Le serveur de build va donc exécuter les tâches dans l'ordre suivant :

  1. prendre la dernière version des sources
  2. compiler la solution (sln)
  3. exécuter les tests unitaires existants
  4. compiler la documentation du code compilé en 1

Création de la custom task :
Une custom task est encapsulée dans une Dll .Net qui sera référencée dans le fichier de projet du Team Build (tfsbuild.proj). Pour rappel ce fichier de projet est un fichier type MSBuild, donc pour plus d'informations sur ce format rechercher MSBuild dans Google.

  1. Nous créons un projet de type ClassLibrary dans Visual Studio
  2. Nous lui ajoutons les références aux assemblies de Team System :
    • . Microsoft.Build.Framework
    • . Microsoft.TeamFoundation.Client
    • . Microsoft.TeamFoundation.Build.Common
  3. On supprime Class1.cs qui ne sert à rien...
  4. On ajoute notre nouvelle classe qui va nous permettre de compiler la documentation de code. Je vais l'appeler BuildHelp.
  5. Microsoft nous propose 2 manières d'implémenter une classe tâche de build. Soit hériter de la classe Microsoft.Build.Utilities.Task ou alors implémenter l'interface Microsoft.Build.Framework.ITask. Dans notre exemple nous prendrons la première solution, plus rapide à implémenter.
  6. La classe Task est une classe abstraite et définie la méthode Execute() comme abstraite, nous la surchargeons donc dans notre classe BuildHelp. C'est cette méthode qui sera invoquée par le serveur de build pour déclencher le travail de notre custom task.
  7. Le code de notre fonction Execute() est plutôt simple puisqu'il consiste à appeler le programme SandCastleBuilderConsole.exe en lui passant en paramètres, le projet SandCastleBuilder qui contient tous les paramètres de génération de documentation.

Voici du code simple (pour l'exemple) pour faire ceci :


public override bool Execute()
{
// Création du processInfo
System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo(@"SandcastleBuilderConsole.exe");
psi.Arguments = "monProjet.shfb";
psi.RedirectStandardOutput = true;
psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
psi.UseShellExecute = false;
System.Diagnostics.Process sandCastleBuilder = null;

// La fonction Log.LogCommandLine() est fournie par Team System et permet d'écrire dans le journal de build
Log.LogCommandLine(MessageImportance.Low, @"SandcastleBuilderConsole.exe" + " " + "monProjet.shfb");
sandCastleBuilder = System.Diagnostics.Process.Start(psi); // Démarre le programme de compilation de la documentation
sandCastleBuilder.WaitForExit(MAX_WAITING_TIME);

return true;
}

La valeur que retourne la fonction Execute() permet au serveur de build de connaitre le résultat de la tâche qu'il a démarré. True la tâche s'est déroulée avec succès, sinon false.

8- On compile la Dll.
9- Pour ajouter la custom task au serveur de build, on édite le fichier projet du serveur de build, le fameux fichier tfsbuild.proj. On lui ajoute notre tâche à la fin après la dernière balise <ItemGroup>:
<usingtask taskname="Reseaux.TeamSystem.Build.CustomTask.BuildHelp" assemblyfile="$(SolutionRoot)\\DemoDocumentation\\Reseaux.TeamSystem.Build.CustomTasks.dll">
<target name="GenerateDocumentation">
<buildhelp>
</buildhelp>
10- Pour pouvoir exécuter notre custom task, le serveur de build doit pourvoir la trouver, donc on peut la mettre dans le répertoire de la solution (il y a d'autres méthodes, voir dans Google et/ou les MSDN). On ajoute donc la Dll générée qui contient notre custom task, dans le contrôle de code source Team System, à coté du fichier sln que notre serveur de build compile.
11- On archive tout (le fichier projet du TeamBuild, la Dll de la customTask) et on démarre un nouveau build.

En principe dans le répertoire de sortie définit par le projet SandCastleBuilder, vous devriez y trouver l'aide compilée.
Si ce n'est pas le cas aller voir dans le fichier de log du serveur de build et rechercher l'appel à votre custom task pour voir si une erreur est remontée.

Ajouter l'output de SandCastleBuilder : Bon aller il y a de grandes chances pour que le shfb qui tourne en local se comporte autrement sur le serveur de build, donc ça serait cool d'avoir l'output de SansCastleBuilderConsole dans le fichier de log du serveur de build. Pour faire ça, on remplace le code de notre Custom Task pour obtenir ceci :

public override bool Execute()
{
bool result = false;
string applicationName = @"SandcastleBuilderConsole.exe";
string parameters = "monProjet.shfb";
System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo(applicationName);
psi.Arguments = parameters;
psi.RedirectStandardOutput = true;
psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
psi.UseShellExecute = false;
System.Diagnostics.Process sandCastleBuilder = null;

try
{
Log.LogCommandLine(MessageImportance.Low, applicationName + " " + parameters);
sandCastleBuilder = System.Diagnostics.Process.Start(psi);
}
catch (ObjectDisposedException e)
{
Log.LogErrorFromException(e, true);
}
catch (InvalidOperationException e)
{
Log.LogErrorFromException(e, true);
}
catch (ArgumentNullException e)
{
Log.LogErrorFromException(e, true);
}
catch (Win32Exception e)
{
Log.LogErrorFromException(e, true);
}
finally
{
if (sandCastleBuilder != null)
sandCastleBuilder.WaitForExit(MAX_WAITING_TIME);
}

try
{
string errorMessage = string.Empty;
string logMessage = string.Format("No output available for {0}", applicationName);
if (sandCastleBuilder.HasExited)
{
string applicationOutput = sandCastleBuilder.StandardOutput.ReadToEnd();
if (sandCastleBuilder.StandardOutput != null)
logMessage = string.Format("See {0} output bellow :\r\n{1}", applicationName, applicationOutput);

if (applicationOutput.IndexOf("Fatal error") != -1)
errorMessage = "See previous error in application output";
else
result = true;
}

Log.LogMessage(logMessage); // Affiche la sortie de l'outil
if (errorMessage.Length > 0)
Log.LogError(errorMessage, null);
}
catch (InvalidOperationException e)
{
Log.LogErrorFromException(e, true);
}
catch (Win32Exception e)
{
Log.LogErrorFromException(e, true);
}
catch (NotSupportedException e)
{
Log.LogErrorFromException(e, true);
}

return result;
}

Rendre les arguments de notre custom task paramétrables, dans le fichier projet Team Build :
Ce qui est pratique c'est qu'on peut facilement définir des paramètres à notre classe custom task. Ces paramètres sont automatiquement lus dans le fichier projet et envoyé à notre custom task par le serveur de build.

Il faut donc ajouter une propriété publique à notre classe BuildHelp. Cette propriété doit portée l'attribut [Required].
Par exemple on peut définir le nom et l'emplacement du fichier projet de documentation à compiler (.shfb)

[Required]
public string SandCastleBuilderProjectFile
{
get { return _sandCastleBuilderProjectFile; }
set { _sandCastleBuilderProjectFile = value; }
}

Et dans le fichier projet, on ajoute le paramètre :

<buildhelp sandcastlebuilderprojectfile=""..\Sources\DemoDocumentation\DemoDocumentation.shfb" ">
</buildhelp></target>/<usingtask></target>

Voilà pour l'essentiel.

Sur mes projets, à ce jour j'ai préféré n'utiliser que la configuraion du fichier TFSBuild.proj en faisant appel aux outils externes via la commande <exec.../> utilisable dans les fichiers MSBUILD. Ca me permet de faire ce dont j'ai besoin (compilation de la documentation de code, regroupement de Dll en une seule et packaging dans un MSI) sans avoir à maintenir de code supplémentaire qui serait induit par l'utilisation de custom task codée en C# ou VB.

J'espère que ça vous aidera à démarrer sur le sujet.

Bien sur, Google est très parlant sur le sujet.

Bon codage à toutes et tous...

jeudi 17 juillet 2008

TeamSystem : Comment supprimer définitivement un WorkItem

Aller sur le serveur TeamSystem et exécuter la commande qui suit :
tfpt destroywi /server:SERVERNAME /workitemid:IDWORKITEM

La commande tfpt.exe fait partie des PowerTools de Team System :
Télécharger les ici http://msdn2.microsoft.com/en-us/tfs2008/bb980963.aspx