Monthly Archives: April 2011

[FR] Pourquoi il est important de bien choisir son workspace lors d’une build

Le workspace d’une build est le passage obligé lors de sa création. SI il est mal fait, la build ne pourra pas être utilisée à 100% de ses capacités.

Prenons un exemple avec le source suivant:

image

Il y a 2 applications: App_X et App_Y. J’ai configuré 2 builds quasiment identiques pour App_X:

image

Ces 2 builds ont que leurs workspaces de different:

image

Ces 2 builds feront exactement la même chose tant qu’elles seront lancées manuellement. Une première différence peut apparaître au lancement car la build possède la tâche suivante:

image

S’il y a beaucoup de fichiers, la première build sera donc plus longue et surtout si un label est posé, il le sera sur tout le source: ce qui ne sera pas très pratique lorsque l’on voudra récupérer  le source de App_X posé sur cette build: on récupérera aussi celui de App_Y! Imaginons maintenant que l’on veuille que les builds soient en mode intégration continue, c’est à dire qu’à chaque check-in du projet la build se lance. Les 2 builds vont avoir un comportement différent.

C’est pas magique: la seule façon  de savoir quelle build doit être lancée à chaque check-in et de confronter les fichiers du changeset, et les workspaces des builds. Si un des fichiers est compatible avec le workspace de la build, cette build est lancée. Modifions maintenant un fichier du projet App_Y. Il se passe la chose suivante: la build App_X est activée alors que l’on n’a pas du tout modifié le project App_X et la build App_X_2 n’est bien sur pas lancée:

image

Ces quelques secondes passées à la définition du workspace font donc toute la différence!

@+

[FR] Branches, bugs, et chef de projet! Ou comment faire voyager les changesets dans le contrôleur de source sans faire de “baseless merge”.

Voici la situation: Bob bosse sur un bug de la version R1 du soft, la correction est prète mais le chef de projet décide que ce bug ne sera pas corrigé dans la V1: la V2 est déjà sorti, et  il ne veux plus que des corrections de sécurité sur la V1. Par contre le bug existe dans la version en cours de développement, il faut donc corriger cette version.

 

Voici une image du contrôleur de source:

image

Si c’était possible, il faudrait faire un merge entre la branche R1-BUG_345 et la Main. Mais ce n’est possible qu’en mode baseless (Let me google that for you Smile ). Mais cette opération n’est pas forcément la plus simple car elle n’utilise pas les informations que TFS possède sur l’origine des fichiers: il est tout à fait possible qu’entre la R1 et la Main actuelle, les fichiers qu’il faut fusionner aient été renommés ou déplacés, et là, le baseless merge ne vas pas trop nous aider. Autre possibilité: utiliser le merge de TFS tout en compensant: nous allons effectuer 2 merges jusqu’à la main et ensuite faire en sorte d’annuler nos modifications dans R1 et surtout acter cette modification dans la Main. Pour cela nous allons utiliser la ligne de commande de TFS 2010 (la fonction était dans les powertools dans les versions précédèntes).

Dans Visual Studio j’effecture les opérations suivantes:

  • merge R1-BUG_345 –> R1: changeset 22
  • merge R1 –> Main du changeset 22 : changeset 23

Maintenant nous avons notre correction dans la main. Il ne reste plus qu’à la supprimer de la branche R1. Pour cela nous allons donc utiliser la commande “tf rollback”:

tf rollback /changeset:C22~C22 /recursive /keepmergehistory

image

Voici l’état des pending changes:

image

On remarque bien que l’état est “Rollback”! Regardons l’historique du fichier en question:

image

 

J’ai ajouté l’option /keekmergehistory pour indiquer à TFS que je ne veux plus que le changeset 22 soit appliqué si je remerge la branche R1-BUG_345 dans R1.

On pourrait penser que tout est bon maintenant, mais il manque une étape: si je merge la branche R1 dans la Main, le code va être annulé comme dans R1! Il y a maintenant 2 possibilités pour corriger cela:

  • Solution 1: faire le merge dans la main et refaire un rollback avec l’option /keepmergehistory: 2 opérations
  • Solution 2: faire croire que le merge de R1  vers Main est effectué via un /discard dans le merge: 1 opération.

Prenons la solution 2: tf merge /recursive /discard /version:C24 “$/MSF Agile Test/Release/R1” “$/MSF Agile Test/Main”

image

Historique devient comme suit:

image

Les commentaires sont importants pour bien comprendre ce qui s’est passé.

Nous avons donc réussi notre mission: Rien dans R1 et le bug corrigé dans la Main. Un conseil pour ces opérations: travailler si possible sur un seul changeset à la fois ou un groupe de changetset assez proche de la latest d’une branche: cela vous évitera les conflits pour la résolution du code.

J’ai utilisé l’option /keekmergehistory, mais sans cette option le rollback est très utile pour:

  • un développeur:  pour annuler un changeset un peut trop rapidement fait,
  • pour un gestionnaire de l’usine: pour annuler un changeset qui fait planter la build si le développeur ne peux pas corriger de suite: c’est un peu notre arme anti-plantage de build Smile.

@+

[FR] Qui a dit que la build compilait toujours la dernière version?

L’affirmation qui dit que la build compile toujours la dernière version est ni vrai ni fausse, juste incomplète: la build ne compile pas la dernière version du code au moment où la build récupère le code, mais au moment où elle démarre. Cela fait toute la différence et c’est tant mieux en fait!

 

Démonstration:

Je prends un projet dans l’état suivant: avant la build le dernier changeset archivé est le #13. Je lance la build. Remarquez quelle version est prise:

image

On en apprend pas beaucoup à ce moment là.

A ce moment même, j’archive un bout de code: c’est le changeset #14. La build a continué de son coté et son status changé entretemps:

image

La build ne prend pas en compte ce changeset et s’arrète au #13!

Explication:

Voilà ce qu’il s’est passé: avant que j’archive le changeset #14, la build a déterminé que le dernier changeset correspondant à la “Latest” était le #13. Donc quelque soient les nouveaux changesets créés, la version du source qui sera utilisée pour la build sera la dernière version jusqu’au changeset# 13. Donc mon changeset #14 n’est pas pris en compte. Cela est très utile pour plusieurs cas:

  • Imaginons une build avec 2 solutions: A et B. si la build commence à compiler la “latest” pour A puis la “latest” pour B si peut y avoir potentiellement un soucis si par exemple la “latest” de B prend en compte un changeset qui comprend des modifications de A ainsi que des modifications de B qui ont besoin des modifications de A. Le résultat est un plantage de la build. Pourtant lorsqu’on récupère la dernière version du code: tout marche!
  • Avec ce numéro de changeset la build peut être relancée plusieurs fois avec le même code source (changeset ou label). Pour cela il suffit d’aller dans les propriétés avancées lors du lancement de la build:

 

image

Build me baby one more time!

 

Un tout petit détail: et bien en fait cela ne marche pas! Il faut modifier le template de build car celui par défaut ignore complètement cette propriété. Pour cela, j’ai ajouté la tâche suivante dans le workflow:

image

Elle est ajoutée dans la séquence “Run On Agent” et la tâche SetBuildProperties a les propriétées suivantes:

 

image

Avec tout cela la version compilée par vos builds n’aura plus de secrets pour vous!

@+