Let There Be Code RSS 2.0
# Friday, January 29, 2010

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 \r\n", details.LastChangedBy, (DateTime.Now - details.LastChangedOn).TotalHours);

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

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

// 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} \r\n", 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] + " \r\n\r\n";
}

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

image

Friday, January 29, 2010 5:40:00 PM (Romance Standard Time, UTC+01:00)  #    Voir Commentaires
Outlook Work Items Extension | TFS SDK
Archive
<January 2010>
SunMonTueWedThuFriSat
272829303112
3456789
10111213141516
17181920212223
24252627282930
31123456
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2012
Benoît Laut
Sign In
All Content © 2012, Benoît Laut
DasBlog theme 'Business' created by Christoph De Baene (delarou)