Utiliser l’API des Builds du TFS SDK pour les afficher dans un calendrier Outlook

Depuis quelques temps je me suis remis au développement de BOWIE. Voulant absolument découvrir l’API de gestion des Builds du SDK de TFS, je me suis creusé les méninges afin de trouver une fonctionnalités intéressantes pour pouvant s’intégrer de façon originale dans Outlook.

Sachant qu’une Build :

  • s’exécute à un temps T1
  • se termine à un temps T2
  • et possède un certain status (Accepted, Failed…),

une Build peut donc être représentée dans un calendrier Outlook par un rendez-vous avec :

  • une date de début
  • une date de fin
  • une catégorie représentant le status
  • une zone permettant d’afficher le détail de la Build, comme dans Visual Studio

On peut également aller plus loin en représentant dans le calendrier les définitions de Build. Dans certain cas, nous créons des définitions de Build récurrentes. Ces définitions de Build récurrentes définissent :

  • un pattern de récurrence (journalier, hebdomadaire…)

Ce type de définition de Build peut donc être représentée par un rendez-vous récurrent dans un calendrier Outlook. Nous pourrions par exemple en ouvrant le rendez-vous, proposer une interface permettant d’éditer la définition, ou encore de démarrer une nouvelle Build.

Après avoir mis à plat toutes ces idées, il ne reste plus qu’à trouver les points d’entrées dans le TFS SDK. Tout d’abord nous avons besoin des références suivantes :

  • TeamFoundation.Client
  • TeamFoundation.Build.Client
  • TeamFoundation.Build.Common

La récupération de toutes les Builds d’un projet nécessite une instance de la classe TeamFoundationServer que l’on obtient à l’aide de la classe TeamFoundationFactory.

Ensuite il faut récupérer l’API du serveur de Build via la méthode GetService<IBuildServer>(). Enfin il ne reste qu’à appeler la fonction QueryBuilds(string projectName) en lui spécifiant un nom de Team Project :

            TeamFoundationServer tfs = TeamFoundationServerFactory.GetServer("http://ServerUri");
            IBuildServer bserver = tfs.GetService<IBuildServer>();
            IBuildDetail[] details = bserver.QueryBuilds("TeamProjectName");

Maintenant que nous avons nos Builds, il nous faut les parcourir et créer des rendez-vous dans le calendrier pour chacune d’elle… et ne pas oublier de stocker l’Uri de la Build dans les UserProperties de l’Appointment :

            AppointmentItem appt = folder.Items.Add(OlItemType.olAppointmentItem) as AppointmentItem;
            appt.Start = item.StartTime;
            appt.End = item.FinishTime;
            appt.Subject = item.BuildDefinition.Name + " - " + item.Status.ToString();
            appt.ReminderSet = false;
            appt.UserProperties.Add("BuildUri", OlUserPropertyType.olText);
            appt.UserProperties["BuildUri"].Value = item.Uri.ToString();

Après quelques petits efforts on arrivera facilement à faire un petit formulaire dans ce style :


image

Pour l’affichage du rapport d’exécution d’une Build on peut utiliser une FormRegion dans le formulaire d’un Appointment.

On récupère l’Uri de la Build dans les UserProperties de l’Appointment. Puis toujours avec l’API du serveur de Build on récupère les détails d’exécution via la méthode GetAllBuildDetails(Uri buildUri) :

            TeamFoundationServer tfs = TeamFoundationServerFactory.GetServer("http://TeamServerUri");
            IBuildServer bserver = tfs.GetService<IBuildServer>();
            IBuildDetail details = bserver.GetAllBuildDetails(new Uri("BuildUri"));

Un objet BuildDetail, comme son nom l’indique, contient toutes les informations d’une Build : l’heure d’exécution, le temps d’exécution, le numéro de build, les étapes de la build, le work item

éventuellement créé, le status, le chemin du fichier de log, la liste des erreurs, des warnings, la configuration… bref vraiment toutes les infos.

Le code ci-dessous nous montre comment récupérer certaines de ces informations :

            // Numéro de la Build
            lblBuildNumber.Text = details.BuildNumber;

            // Emplacement du Log
            lnkLogPath.Text = details.DropLocation;

            // Dernière Modification
            lblSummary.Text = string.Format("Build last modified by {0} {1:0.0} hours ago rn", details.LastChangedBy, (DateTime.Now - details.LastChangedOn).TotalHours);

            // Plateforme
            lblErros.Text += configuration.Fields[InformationFields.Platform] + " | " + configuration.Fields[InformationFields.Flavor] + "rn";

            // Nombre d'erreurs et de warnings
            lblErros.Text += configuration.Fields[InformationFields.TotalCompilationErrors] + "error(s), " + configuration.Fields[InformationFields.TotalCompilationWarnings] + "warning(s) rn";

            // WorkItem créé
            foreach (IBuildInformationNode node in details.Information.GetNodesByType(InformationTypes.OpenedWorkItem, true))
            {
            lnkBug.Text = string.Format("Bug {0}", node.Fields[InformationFields.WorkItemId]);
            lblState.Text = string.Format("Current state is {0}, currently assigned to {1} rn", node.Fields[InformationFields.Status], node.Fields[InformationFields.AssignedTo]);
            }

            // Le détail des erreurs (fichier, numéro de ligne, message)
            foreach (IBuildInformationNode item in details.Information.GetNodesByType(InformationTypes.BuildError, true))
            {
            lblErros.Text += "    " + item.Fields[InformationFields.File] + " (" + item.Fields[InformationFields.LineNumber] + "): " + item.Fields[InformationFields.Message] + " rnrn";
            }

Le code précédent donne le résultat suivant :


image

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s