TFS 2015: Customisation des activités de build (part1)

Auteur original, de notre ancien blog : Laurent Jacques

tfs9

Aujourd’hui nous allons discuter de la customisation des activités de build avec TFS 2015. En effet, alors que dans un prochain billet j’aborderai le tout nouveau système de build vNext ; il me semblait important de souligner une des (nombreuses) possibilités de customisation du mécanisme existant. Etant donné le volume d’étapes je présenterai la customatisation en 2 parties : 

  1. la création d’un nouvelle activité de build,
  2. l’intégration du workflow dans la définition de build.
PART1 : Création d’une nouvelle activité de build.

Lire la suite

[ALM] TFS 2015 est RTM

Auteur original, de notre ancien blog : Laurent Jacques

tfs2015_1

Microsoft a publié hier la release finale de Team Foundation Server 2015.

Parmi les nouveautés notables par rapport à la version précédente, on peut noter:

  • Nouveau système de build : vNext
  • Nouveau pipeline de déploiement (countinuous delivery),
  • Amélioration agile & planning,
  • Modification du licensing (basic user).

Lire la suite

TFS 2015 : automatiser la création d’une définition de build XAML.

Auteur original, de notre ancien blog : Laurent Jacques

xaml1

xaml2

Aujourd’hui nous étudierons un cas pratique d’utilisation avancée de TFS  (2012,2013 et 2015) et de ses mécanismes de build.

Nous chercherons à automatiser la création et la suppression des définitions de builds avec l’utilisation de l’API de Team Foundation Server avec Visual Studio 2013.

Pour le cas d’étude de ce billet, l’organisation du code source se présente ainsi :

  • une branche dev : le travail courant des développeurs, tous check-in leurs modificationdedans au jour le jour.
  • plusieurs branches uat : en fin de cycle de développement, une nouvelle branche uat_X.Y.Z est créée à partir du dev pour partir en validation (test d’intégration)
  • une branche master : une fois validée la branche uat_X.Y.Z devient la nouvelle branche master : version référence pour les développements.

Ce qui donne par exemple l’arborescence suivante :

[code light= »true »]/Projet/
/dev
/Appli1
/Appli2
/master
/Appli1
/Appli2
/uat_1.2.3
/Appli1
/Appli2
/uat_1.3.0
/Appli1
/Appli2[/code]

 

L’équipe de développement a mis au point deux définitions de build basées sur la branche DEV :

  • une intégration continue, tournant les tests unitaires automatiques, générant la doc, fournissant les livrables dans un répertoire dépôt;
  • une nightly : déployant les applications sur l’environnement de test tous les jours à 23h.

Problématique 

Une fois validée en interne, le DEV est branché en UAT_X.Y.Z : les définitions de builds ne fonctionnent donc pas sur cette branche.

Actuellement : pour chaque nouvelle branche UAT le lead technique vient créer une nouvelle définition de build UAT et ajouter les différents paramètres.

Besoin 

Automatiser le processus.

Mise en oeuvre

Pour cette première version nous visons la mise en place d’une app console en c# qui ira, à intervalles réguliers, vérifier l’état des branches et gérer les définitions de builds.[…]

Avant toute chose: ajouter les références (v12) dans le projet :

xaml3

1ière étape:  récupérer la listes des branches UAT existantes.:

[code language= »csharp »]
List<Branch> branchList = new List<Branch>();
using (var tfs = new TfsTeamProjectCollection(_TFSserver))
{
VersionControlServer vcs = (VersionControlServer)tfs.GetService(typeof(VersionControlServer));
var items = vcs.GetItems(sourceCodeArea, VersionSpec.Latest, RecursionType.OneLevel,
DeletedState.NonDeleted, ItemType.Folder).Items;
foreach (Item item in items)
{
// skip self
if (!item.ServerItem.Equals(sourceCodeArea))
{
if (item.ServerItem.ToLower().Contains(filter.ToLower()))
branchList.Add(new Branch(item.ServerItem, item.CheckinDate, project));
}
}
}
[/code]

Dans le code présent la logique est la suivante:

  1. on fournit comme paramètres :
  • l’url d’accès au serveur TFS ,
  • la zone de départ dans le source (sourceCodeArea) , 
  • un fitre est indiqué qui va permettre de ne ressortir que les branches qui nous intéressent (filter) 
     2. on récupère la liste des folders (branche) ;

[code language= »csharp » light= »true »]
var items = vcs.GetItems(sourceCodeArea, VersionSpec.Latest, RecursionType.OneLevel, DeletedState.NonDeleted, ItemType.Folder).Items;
[/code]

3. pour chacun de ses folders, on vérifie la cohérence du nom par rapport au filtre précisé :

[code language= »csharp » light= »true »]
if (item.ServerItem.ToLower().Contains(filter.ToLower()))
[/code]

4. une fois récupérées, les branches seront ajoutées dans une liste d’objets maisons pour être gérées plus tard.

 

2ième étape:  récupérer les définitions de build existantes:

[code language= »csharp »]
var tfs = new TfsTeamProjectCollection(_TFSserver);
tfs.Authenticate();
var buildServer = (IBuildServer)tfs.GetService(typeof(IBuildServer));
var buildDefinitionList = new List<IBuildDefinition>(buildServer.QueryBuildDefinitions(TEAM_PROJECT));
[/code]

Afin de déterminer si les builds n’existent pas déjà, il faut en premier lieu récupérer la liste des builds existantes.

Les instructions ci-dessus permettent d’interroger le serveur TFS pour cela.

Ici, le TEAM_PROJECT  est simplement une constante représentant le nom du projet d’équipe.

L’appel à  buildServer.QueryBuildDefinitions va fournir l’ensemble des builds existantes pour le projet.

 

3ème étape:  parcourir la liste des branches et créer les builds inexistantes:

[code language= »csharp »]
if (!buildDefinitionList.Exists(x => x.Name == TfsBuildServices.BuildName(projectName, branch)))
                {
                    IBuildDefinition CIBuild = buildDefinitionList.Where(x => x.Name == projectName + "_CI").First();
                    if (CIBuild != null)
                    {
                        var newbuild = buildServer.CreateBuildDefinition(TEAM_PROJECT);
                        newbuild.CopyFrom(CIBuild);
                        newbuild.Name = TfsBuildServices.BuildName(projectName, branch);
                        BuildSettings settings = new BuildSettings();
                        var process = WorkflowHelpers.DeserializeProcessParameters(newbuild.ProcessParameters);
                        settings.ProjectsToBuild = new StringList(((BuildSettings)process["BuildSettings"]).ProjectsToBuild.ToString().Replace("DEV",branch));
                        process.Remove("BuildSettings");
                        process.Remove("ProjectsToBuild");
                        process.Add("BuildSettings", settings);
                        process.Add("ProjectsToBuild", new string[] { settings.ProjectsToBuild.ToString() });
                        newbuild.ProcessParameters = WorkflowHelpers.SerializeProcessParameters(process);
                        newbuild.DefaultDropLocation += @"" + projectName;
                        newbuild.Workspace.Mappings[0].ServerItem = newbuild.Workspace.Mappings[0].ServerItem.Replace("DEV", branch);
                        newbuild.Save();
                    }
                }
[/code]

1. une simple requête linq sur le nom de la build permet de passer la création si la build existe déjà

[code language= »csharp » light= »true »]
if (!buildDefinitionList.Exists(x => x.Name == TfsBuildServices.BuildName(projectName, branch)))
[/code]

L’appel  à TfsBuildServices.BuildName  permet de centraliser et de formaliser  la création du nom de la build 

2. on récupère la build d’intégration continue qui va nous servir de modèle pour la nouvelle définition 

[code language= »csharp » light= »true »]
IBuildDefinition CIBuild = buildDefinitionList.Where(x => x.Name == projectName + "_CI").First();
[/code]

3. on initialise la nouvelle build avec le modèle

[code language= »csharp » light= »true »]
var newbuild = buildServer.CreateBuildDefinition(TEAM_PROJECT);
  newbuild.CopyFrom(CIBuild);
[/code]

4. la modification des paramètres

La build definition utilise des BuildSettings pour enregistrer ses paramètres :

[code language= »csharp »]
BuildSettings settings = new BuildSettings();
                        var process = WorkflowHelpers.DeserializeProcessParameters(newbuild.ProcessParameters);
                        settings.ProjectsToBuild = new StringList(((BuildSettings)process["BuildSettings"]).ProjectsToBuild.ToString().Replace("DEV",branch));
                        process.Remove("BuildSettings");
                        process.Remove("ProjectsToBuild");
                        process.Add("BuildSettings", settings);
                        process.Add("ProjectsToBuild", new string[] { settings.ProjectsToBuild.ToString() });
                        newbuild.ProcessParameters = WorkflowHelpers.SerializeProcessParameters(process);
                        newbuild.DefaultDropLocation += @"" + projectName;
                        newbuild.Workspace.Mappings[0].ServerItem = newbuild.Workspace.Mappings[0].ServerItem.Replace("DEV", branch);
[/code]

Ces settings sont sérialisés sous forme de dictionnaires et doivent donc être réédités pour cadrer avec le besoin spécifique UAT:

  • la copie de la build CI pointe par exemple vers la solution à compiler $/Project/dev/Appli1/Appli1.sln . il faut donc modifier ce répertoire pour celui UAT : 

[code language= »csharp » light= »true »]
settings.ProjectsToBuild = new StringList(((BuildSettings)process["BuildSettings"]).ProjectsToBuild.ToString().Replace("DEV",branch));
[/code]

  • de la même manière le default drop location contient celle de la build CI et doit être modifié : 

[code language= »csharp » light= »true »]
newbuild.DefaultDropLocation += @"" + projectName;
[/code]

  • et enfin le modèle objet de la définition de build contient aussi le mapping vers le répertoire source controle mappé qui doit lui aussi être remplacé : 

[code language= »csharp » light= »true »]
newbuild.Workspace.Mappings[0].ServerItem = newbuild.Workspace.Mappings[0].ServerItem.Replace("DEV", branch);
[/code]

5. on sauvegarde, laisse 15 min au four : et hop. la build est créée !

[code language= »csharp » light= »true »]
newbuild.Save();
[/code]

 

4ième étape:  supprimer les builds des anciennes branches :

Récupération de la liste des branches supprimées :

[code language= »csharp » highlight= »2″]
var items = vcs.GetItems(area, VersionSpec.Latest, RecursionType.OneLevel,
DeletedState.Deleted,
ItemType.Folder).Items;
[/code]

Pour chacune des anciennes branches on récupère la définition de la build associée (si elle existe)

[code language= »csharp » highlight= »4″]
IBuildDefinition UAT_CIBuild = buildDefinitionList.Where(x => x.Name == TfsBuildServices.BuildName(projectName, branch)).FirstOrDefault();
if (UAT_CIBuild != null)
{
buildServer.DeleteBuilds(UAT_CIBuild.QueryBuilds());
}
[/code]

A noter: pour pouvoir supprimer une définition de builds il faut que les historiques de run soient eux-aussi supprimés, c’est pourquoi l’appel buildServer.DeleteBuilds(UAT_CIBuild.QueryBuilds());  est fait ainsi  : cela supprime l’ensemble.

 

5ième étape:  emballer dans une petite application :

Je ne rentrerai pas dans les détails sur ce point, mais avec les éléments fournis rien de plus simple que de réunir tout cela dans une application qui tourne à intervalle régulier et exécute ces appels afin de synchroniser les définitions de builds et les branches.

 

Pour aller plus loin 

http://nakedalm.com/

https://msdn.microsoft.com/fr-fr/vstudio/ff637362.aspx

ALM ranger’s site

Prochaine étape 

Dans le prochain billet j’expliquerai comment se passer de l’application console en intégrant ce code au sein d’activités de build maisons et comment créer notre propre template de build avec tout ceci.

 

Laurent.

 

[ASP.NET MVC] Requêtes GET très longues sur arterySignalR (Browser Link)

Récemment, lors du développement d’un site ASP.NET MVC 5 interrogeant une Web API 2.2 OData, nous avons constaté que nos processeurs tournaient à 100% lorsque nous exécutions le site en local.
Le problème ne se posait pas en debug, ni sur les plateformes d’intégration mais uniquement sur des sites IIS locaux.

En étudiant la trace Réseau avec les outils développeurs de Chrome et IE, nous avons remarqué qu’il y avait des milliers de requêtes GET sur http://localhost:<port>/<guid>/arterySignalR/send?transport=longPolling …

IE
arterysignalr-IE

Chrome
arterysignalr-Chrome

Il s’avère que « arterySignalR » n’est autre que l’appel à Browser Link. C’est une fonctionnalité de Visual Studio 2013 permettant d’établir une connexion temps-réelle avec l’ensemble des navigateurs exécutant une application actuellement ouverte dans VS.
Toutes les interactions que vous faites dans votre code peuvent être répercutées via Visual Studio sur tous les navigateurs ouverts sur l’application en question.
Cela vous permet aussi de rafraîchir automatiquement vos feuilles de styles par exemple, sans avoir à faire un F5 sur votre navigateur.

Il s’avère que dans notre cas, l’appel à notre Web API derrière le site MVC plombait les perfs. Il a été plus judicieux de le désactiver en attendant de trouver une solution de contournement.

Si vous désirez faire de même, il vous suffit dans Visual Studio de cliquer sur le bouton de rafraîchissement à côté du bouton de Debug en navigateur, puis de décocher « Activer le lien de navigateur » :

arterysignalr-VS

Voilà !

En espérant que ça puisse vous aider autant que nous.

Source : http://stackoverflow.com/questions/19917595/net-localhost-website-consistantly-making-get-arterysignalr-polltransport-long

Visual Studio/TFS 2013 Update 4 : les outils web et la gestion des projets agiles mises en avant !

Normal
0

21

false
false
false

FR
X-NONE
X-NONE

/* Style Definitions */
table.MsoNormalTable
{mso-style-name: »Tableau Normal »;
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-parent: » »;
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:11.0pt;
font-family: »Calibri », »sans-serif »;
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-fareast-language:EN-US;}

En
attendant la nouvelle version de Visual Studio (Visual Studio 14), Microsoft vient de publier
la RC (« Release Candidate ») de Visual Studio 2013 Update 4 ainsi que de Team
Foundation Server 2013 Update 4.

Concrètement,
beaucoup d’améliorations ont été faites notamment sur la prise en charge du
cycle de développement
ou encore sur l’éditeur de code JavaScript. Vous noterez également que VS 2013.4 intègre des améliorations
concernant les outils de suivi et de gestion des projets agiles
.

Pour
plus de détails sur les nouvelles fonctionnalités, je vous
invite à consulter les articles suivants :

·        
Développez.com : Microsoft publie la RC de Visual Studio 2013 Update 4

·        
Blog – MSDN : Visual Studio and TFS 2013.4 (Update 4) Release Candidate

Donner un nom de version aux itérations scrum / scrumban?

photo credit: NPF.1 via photopin cc

Lorsque l’on parle de sprint, on fait souvent référence à un numéro pour les identifier. On commence avec le sprint zéro pour aller vers des sprints où la vélocité devient de plus en plus précise. En maintenance logicielle, le développement d’une application peut s’étaler sur plusieurs années et comprendre de multiples versions. Dans ce contexte, donner un nom de version à chaque itération du cycle de développement présente certains avantages. Lire la suite

Reconnaissance de fait pour Scrum

Microsoft vient de reconnaitre, de fait, la pertinence de Scrum (la méthode de gestion de projet que nous avons adoptée pour nos forfaits) en l’intégrant dans Visual Studio Team System. Une autre manière de dire que la fond prévaut sur la forme (ou, ici, la méthode sur l’outil).

A noter toutefois que eScrum n’est pas terriblement simple a installer et configurer et que la plus value de l’outil est ici assez discutable. Mais il parait que Microsoft a pris bonne note des remarques des premiers utilisateurs et travaille a un sp1.

l’annonce:http://www.journaldunet.com/developpeur/breve/international/13161/microsoft-integre-scrum-a-visual-studio.shtml

et, pour un premier avis :http://feeds.feedburner.com/~r/bsimser/~3/125203560/an-attempt-at-working-with-escrum.aspx

Si vous ne connaissez pas Scrum, voici une tres bonne présentation