Archives de catégorie : Développement

Dépasser les limites de planification de Team Build

Team Build permet de planifier le déclenchement de Builds via un scheduler assez basique :

image

Nous avons la possibilité de planifier à intervalles régulier le déclenchement d’une build selon deux critères : le jour et l’heure.

Impossible donc de planifier depuis cette interface une build afin qu’elle soit déclenchée toutes les deux heures, toutes les demi-journées ou selon des critères plus complexes.

Afin de pouvoir déclencher une build à sa guise il est donc nécessaire d’utiliser une technique. Il est par exemple possible de lancer un build grâce au SDK de TFS, grâce aux services web, ou aux API REST, mais encore plus simplement via l’outil en ligne de commande TFSBuild.exe.

Il est donc possible de programmer vos builds comme vous le souhaitez grâce aux tâches planifiées proposées par Windows !

Exemple de commande :

« C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\TFSBuild.exe » start https://moncompte.visualstudio.com/DefaultCollection TeamProject NomDefinitionBuild /queue

Siren of Shame reste bloqué sur “Attempting to connect to server”

Ou comment se laisser abuser par un message d’erreur…

Siren of Shame est un logiciel de suivi de Builds qui vous permet d’être notifié du démarrage des Builds, du bon déroulement ou des échecs de Builds directement depuis la SysTray.

De plus, bonus non négligeable, il permet de se connecter à une sirène USB afin de signaler de manière visuelle et sonore, qu’il y a un problème.

J’ai décrit plus longuement ce système via ce post : http://patricelamarche.net/the-siren-of-shame/ 

image

Depuis quelques jours, je restais bloqué sur une erreur de connection, SoS m’indiquant en continu “Attempting to connect to server”.

Après désinstallation/réinstallation, session de sniff via Fiddler afin de déterminer la source du problème de connectivité, la solution a été beaucoup plus simple : Aucune des builds enregistrées n’était valable car je les avais renommés quelques jours auparavant. Au lieu d’indiquer un problème avec les définitions de Build, SoS me dirigeait donc vers une mauvaise direction.

image

Comment fonctionne le versionning de base de données ?

J’ai récemment décrit comment mettre en place de l’intégration continue afin d’intégrer automatiquement les modifications de schéma de bases de données sur des bases de données de test par exemple.

On m’a à cette occasion très justement indiqué que j’aurais pu décrire comment fonctionne le versionning de base de données.

Je vais donc décrire via ce post comment gérer dans un SCM une base de données, et je vais l’illustrer via l’utilisation de RedGate SQL Source Control. Les principes fondamentaux restent identiques pour les autres outils de la catégorie.

Cet outil peut être utilisé avec différents SCM : SVN, Git, Mercurial et bien évidemment avec TFS.

Une fois installé, vous disposez d’un nouvel onglet dans SQL Server Management Studio, celui-ci vous permet d’effectuer les principales tâches de gestion de version d’une base de données :

  • Définition du lien avec le SCM de votre choix
  • Opérations Get Latest et Commit

Première étape à réaliser donc, établir le lien entre une base de données et votre SCM :

image

A noter que ce lien étant stocké sur la machine où il est réalisé, il doit être réalisé sur chaque poste de développement.

Une fois le lien effectué, RedGate SQL Source Control va scruter en continu les modifications effectuées sur votre base de données. Il sera ainsi capable de vous indiquer les modifications effectuées lorsque vous souhaiterez faire un commit.

Le développeur peut donc effectuer les modifications qu’il souhaite sur sa base et va ensuite être capable de faire un commit dans le source control de ses modifications.

A noter qu’afin d’être capable de stocker les informations de schémas d’une base de données dans n’importe quel SCM il faut être capable de créer un ou plusieurs fichiers représentant ce schéma.

La plupart des outils de versionning de bases de données fonctionne de la même manière.

Un des objectifs de la mise en place de versionning étant la capacité de recréer from scratch une BDD propre, les outils crééent un script de création de chaque “objet” (Table, Vue, Procédure stockée, Trigger, etc.) et stockent ces fichiers dans le repository.

Ainsi le premier commit effectué depuis RedGate génère la structure suivante dans le source control :

image

Un petit tour dans le dossier de définition des tables et nous retrouvons notre table de test stockée sous forme de fichier .sql :

image

Ce fichier SQL contenant le script de création de la table avec l’ajout du champ et de la clé primaire :

image

A chaque modification de schéma, l’outil de versionning de BDD va ainsi générer le même script de création mis à jour en fonction des modifications de schéma effectuées. Ainsi un ajout de champ “nom_test” génère une nouvelle version du fichier Test.sql :

image

 

Vous retrouverez également ces scripts directement dans SQL Source Control lorsque vous effectuerez un GetLatest :

image

Bien évidemment, lorsque l’on effectue ce GetLatest, RedGate SQL Source Control ne vas pas bêtement remplacer la table en exécutant directement le script de création présent dans le source control mais il va générer un script de modification adéquat  afin de préserver les données présentes :

image

Cette génération de requête à partir du diff de deux requêtes de création est d’ailleurs la seule partie complexe de ce type de logiciels.

Oubliez DropBox, de vrais outils gratuits de gestion de sources existent !

C’est avec une grande surprise que j’ai découvert il y a quelques jours l’annonce du support de DropBox pour les déploiements dans Windows Azure.

Proposer le support de TFS, de git ou de mercurial d’accord, mais DropBox ?!?

Dropbox : sauvegardez, synchronisez et partagez facilement, en toute sécurité.

DropBox étant un “simple” espace de stockage sur le cloud, j’avais du mal à croire que certains développeurs l’utilisent en tant que repository de source, et pourtant cela semble bien être le cas.

DropBox propose en effet un outil de synchro qui permet de directement mapper un dossier local vers l’espace de stockage DropBox.

Certains développeurs l’utilisent donc comme certains pouvaient utiliser un dossier partagé pour gérer leurs sources.

J’avoue être complètement surpris que l’on puisse encore utiliser ce type de système même pour des tout petits développements.

La plupart des outils de gestion de sources sont gratuits, nécessitent peu d’apprentissage, et ont un coût d’utilisation (=surcharge de travail) très très très faible.

Même Microsoft fournit ce type d’outil gratuitement :

Vous pouvez en effet côté serveur mettre en place un TFS Express pour des équipes de 5 personnes max, ou encore sans aucune installation utiliser TFS Service.

Côté client, Team Explorer 2012 et un coup de PowerTools (bon ok sur ce coup là l’install est pas vraiment très légère…) permet de gérer n’importe quel fichier directement depuis l’explorateur de fichiers et de bénéficier de bien de fonctions qu’un simple rollback de fichiers :

  • la gestion des changesets : pour quelle raison (=commentaire sur le changeset) a été modifié un fichier (ou un ensemble de fichiers) par qui et quand,  et quel a été le diff exact
  • permet de savoir quels sont les fichiers en cours de modification et par qui, et support des merge en cas de modification multiple
  • Gestion “nommée” de versions de source via des labels
  • etc.

Je ne vais pas vous le faire le coup du Allo ?!? Non mais allo, quoi… Mais vraiment utiliser DropBox comme gestionnaire de source me parait vraiment être d’un autre âge même pour toutes les petites structures et pour les petits projets.

image_thumb.png

Intégration Continue de BDD avec SQLCompare de RedGate

Nous utilisons SQL Source Control de RedGate pour le gérer le versionning de nos bases de données ainsi que SQLCompare afin de générer les scripts de mise à jour d’une version à une autre. Cette solution est en effet peu coûteuse et à mon sens plus simple à utiliser que les outils proposés par Microsoft.

L’objectif de la mise en place d’intégration continue est d’arriver à déployer de manière automatique toutes les modifications sur une base de données destinée aux tests.

Pour notre scénario exemple, j’ai donc une base de données DBTest liée au source control, et une base de données DBTest_CI non liée au source control et qui sera automatiquement mise à jour par le serveur de builds (celle-ci peut évidemment être sur un autre serveur) :

image

Pour arriver à impacter la base DBTest_CI à chaque checkin d’une modification sur la base versionnée, il est donc nécessaire de créer un processus de build en intégration continue :

image

Une fois le processus de build défini, il est nécessaire de rajouter une tâche au processus de build : cette tâche permettra d’appeler SQL Compare selon le principe suivant :

image

SQL Compare ne va pas effectuer un compare entre le source control et la base de données d’intégration mais entre le dossier de scripts présent sur le source control et cette même base.

Pour cela nous allons utiliser le fait que le processus de build par défaut un getlatest pour directement récupérer la dernière version des scripts SQL.

Pour avoir de souplesse dans les modifications du processus de builds je préfère souvent externaliser les commandes à réaliser via un fichier .bat ou un fichier powershell. L’intêret est que le développement en est beaucoup plus simple (plus besoin de fait un checkin/checkout de la définition de la build à chaque modification), l’inconvénient est que cette définition n’est donc pas versionnée.

Vous pouvez donc utiliser cette technique dans vos phases de définition/personnalisation de de builds et ensuite pousser vos modifications sur le source control une fois que vous avez terminé pour garder les avantages des deux solutions.

Pour lancer la commande vous pouvez utiliser l’activité InvokeProcess et spécifier en argument de la commande à lancer les informations souhaitées :

image

De plus comme vous pouvez le voir, afin d’avoir un retour dans le log de la build, j’ai placé une activité WriteBuildMessage au niveau de la gestion de l’output ce qui permettra d’avoir une tracabilité au niveau des actions effectuées.

Concernant mon .bat donc, la commande est assez simple :

SNAGHTML61b1df96

J’indique à SQL Compare d’utiliser le dossier de scripts SQL qui a été getlatesté par le processus de build, j’indique ensuite les informations de connexion au second serveur. A noter que j’utilise l’authentification SQL afin de me simplifier la vie. Le paramètre /sync indique enfin à SQL Compare de directement exécuter le résultat du compare pour synchroniser les deux sources de données.

Le résultat est que lorsque l’on checkin un ajout d’un nouveau champ dans une table de la base DBTest :

image

Une nouvelle build se déclenche automatiquement :

image

Build qui a pour effet d’automatiquement intégrer les modifications sur la base d’intégration continue :

imageimage

continousintegration

Critique : Continous Integration in .net

Comme indiqué dans le titre de l’ouvrage, ce livre traite de la mise en place du principe d’intégration continue au sein de projets .net.

Pour rester général, les auteurs évoquent cette mise en place via 3 environnements : CruiseControl.net, Team Foundation Server et Team City.

Le message distillé au long des plus de 300 pages est clair, la mise en place d’intégration continue ne nécessite pas un investissement financier important (peut être gratuit via les 3 produits cités sous différentes conditions), il nécessite un investissement en montée en compétence, et en temps d’implémentation qui va très vite être rentabilisé.

Gestion des sources, compilation, feedback, mise en place de tests, analyse statique via FxCop, StyleCop et NDepend, gestion des changements de schéma de BDD, génération de projets de setup, et génération de documentation, tous les sujets techniques sont évoqués et décris de manière pratique.

Le parti pris d’évoquer les 3 environnements à certainement pesé sur le fait que l’ouvrage ne décrit pas en profondeur les fondamentaux, ne donne pas la part belle à “la théorie”, au pourquoi du comment, ni aux concepts associés (les feature flags par exemple).

Continuous Integration in NET est un bon ouvrage pour les débutants en intégration continue qui souhaite se mettre de manière pratique via un des 3 environments cités ci-dessus. Ceux d’entre vous qui maitrisent déjà les notions de base et qui cherchent un ouvrage de référence préférerons passer le chemin et se diriger vers un ouvrage plus théorique.

image

FeatureFlags : Initial Checkin sur CodePlex

Comme indiqué dans le titre, je viens de faire un premier checkin de mon état d’avancement de la librairie de gestion de FeatureFlags sur CodePlex.

image

Vous pouvez accéder au portail du projet à cette adresse : http://featureflags.codeplex.com

Pour rappel du scope actuel :

  • Création de Feature
  • Gestion de Flip au niveau code ou au niveau UI (WPF uniquement)
  • Persistence de l’état des features dans une base SQL Server

Je vais très prochainement faire une vraie application de démo pour montrer l’utilisation de librairie ainsi que la documentation pour montrer comment étendre le stockage de l’état des features.

Toutes les remarques, idées, critiques sont les bienvenues ! N’hésitez pas à m’en faire part via l’issue tracker du projet directement sur CodePlex.

image

Librairie FeatureFlags : Choix de conception

Je vous ai parlé il y a peu de l’utilisation des Feature Flags qui est une technique qui facilite la mise en place d’intégration continue, je vous avais alors indiqué que les différentes implémentations disponibles en .net ne me satisfaisait pas.

imageJ’ai donc débuté le développement d’une librairie appelée tout simplement FeatureFlags.

Avant de mettre le code à disposition sur codeplex, je vais donc partager vous les différents choix de design que j’ai effectué.

J’ai opté pour un principe simple afin de faciliter la maintenance des features : je souhaite que l’utilisation du principe soit le plus fortement typé possible afin que l’on puisse agir directement sur les différents emplacements dans le code où une feature est utilisée.

Ainsi toute suppression de feature (car plus utile, par exemple dans le cas d’une activation définitive), doit lever différentes erreurs de compilation afin de forcer le développeur à supprimer tout le code inhérent.

Niveau UI

Mon besoin étant uniquement orienté autour d’applications WPF, je me suis attardé uniquement sur ce type d’intégration.

L’objectif est de pouvoir afficher ou non n’importe quel contrôle WPF en fonction de l’état d’activation d’une fonctionnalité.

Pour une intégration simple et souple, j’ai opté pour l’implémentation d’une custom MarkupExtension.

Cette solution de lier très simplement une propriété Visibility à une Feature et permet également de rester fortement typé. Si la classe de définiton de la feature est supprimée, nous nous retrouverons avec une erreur de compilation XAML facilement détectable.

image

A noter la possibilité d’afficher des contrôles en fonction de la non activation d’une feature via la définition de la propriété IsEnabled (définie à True par défaut) :

image

D’un point de vue du rafraichissement, j’ai opté pour une récupération de l’état d’activation de la feature en “One Time” uniquement au moment de la récupération de la MarkupExtension. Cela signifie que si l’état d’activation change alors que la fenêtre parent est déjà chargé, l’UI ne sera pas impactée.

Niveau Code

D’un point de vue code, le flip se fait de manière très simple :

image

Je viendrais dans un prochain post sur la gestion de la persistence de l’état des features en base de données.

N’hésitez pas à me faire part de vos remarques sur ce design par rapport aux autres libraires du marché.

image

Gestion des évolutions grâce aux Feature Flags

Gérer correctement les évolutions dans un projet logiciel n’est pas simple car il faut arriver à gérer le cycle des releases qui en général est beaucoup plus rapide que le rythme de mise à disposition de certaines fonctionnalités qui prennent du temps à être développé.

Il est donc souvent nécessaire de mettre en place certains mécanismes permettant d’arriver à livrer très régulièrement une application “malgré” des développements en cours non finalisés.

Première principe et le plus populaire :

La mise en place de branching

Quelle que soit la stratégie de branching choisie (branche corrective + branche évolutive, branches par version, ou branches par fonctionnalité – je vous recommande d’ailleurs ce guide sur les différentes stratégies de branching que l’on peut mettre en place –), la mise en place de branches ajoute une surcharge de travail qui est gérable mais qui peut être conséquente.

Il y a bien évidemment la surcharge de travail pour les développeurs au niveau des merges entre les différentes branches, mais également une surcharge de travail d’un point de vue des tests.

Il est en effet nécessaire d’effectuer des tests sur la branche sur laquelle le développement a été effectué, mais également sur toutes les autres branches sur lesquelles les modifications vont être fusionnées.

Il s’agit donc d’une technique qui peut avoir un impact sur la vélocité des releases, sur le rythme de mise à disposition de nouvelles fonctionnalités.

Les feature flags

Autre principe plus léger à mettre en place : les feature flags.

imageLe principe est simple : afin d’être capable de gérer les évolutions, il suffit de développer les fonctionnalités et de les livrer même non finalisés dans les différentes releases mais de les désactiver afin de les rendre inacessibles aux utilisateurs.

Il suffira ensuite de les activer ou non directement au runtime par configuration, sans aucune modification de code et donc sans aucun déploiement lorsqu’on le souhaitera.

 

 

Plusieurs avantages à ce principe :

  • On ne ralentit pas la cadence des releases puisqu’on livre les fonctionnalités non terminées (qui resteront masquées)
  • On peut activer ou non certains certains fonctionnalités en fonction des différents clients (selon leur profil par exemple) afin de les faire participer à des phases de tests (alpha, beta, etc.)
  • On n’est capable de revenir en arrière en cas de problème car en général les feature flags doivent pouvoir être accompagnées de logique de rollback

Ce concept a été mis en place et mis en avant par les équipes de Flickr. Je vous invite d’ailleurs à consulter le post de fin 2009 présentant le principe et son application au site web flickr.

Le principe a été ensuite décrit par Martin Fowler via le pattern Feature Toggle.

Il existe différentes implémentations des feature flags dans l’ecosystème .net : FeatureSwitcher, FeatureToggle, NFeature

La plupart des librairies reposent sur le même principe : on active ou désactive les features de l’application en passant par le fichier de configuration de l’application.

D’un point de vue de la représentation des features au niveau du code, la plupart se basent sur des classes implémentant une interface ou une classe de base, ou alors via une Enum qui permet de lister celles-ci.

N’aimant pas particulièrement les fichiers de configuration (ils sont trop compliqués à maintenir, à faire évoluer), je vais bientôt revenir vers vous avec une nouvelle libraire permettant de gérer cela directement en base de données.

Stay tuned !

image

Forcer les developpeurs a mettre des commentaires de changesets pertinents

Ecrire des commentaires de checkins pertinents fait parti  des tâches simples que l’on a du mal à faire comprendre et accepter des équipes.

Les tâches non liées à l’écriture de code mais qui sont là pour faciliter la maintenance des applications (via dans le cas présent une meilleure traçabilité des modifications effectuées) sont il est vrai souvent considérées par les développeurs comme des tâches moins importantes, moins prioritaires, des tâches de seconde classe.

Par fainéantise, ou par désintérêt on se retrouve le plus souvent avec ce type de commentaire :

image

Des commentaires (lorsqu’ils sont présent ce qui n’est pas le cas pour le changeset 7817) qui n’ont aucune valeur.

Le problème est important puisque cela conduit à ce genre de choses :

image

Un historique de fichier inutilisable  où on ne sait pas ce qui s’est passé sauf à passer beaucoup de temps à faire des compare entre chaque changeset.

Lors d’une discussion avec un responsable ALM, celui-ci m’indiquait qu’il n’arrivait pas à arriver à ce type de résultat :

image Un résultat certes imparfait mais quand même de qualité, avec des information utiles qui pourront être consultées dans le futur.

Pour parvenir à cela, et bien évidemment après avoir expliqué à l’équipe en quoi il est important de placer des commentaires pertinents, j’ai été obligé de passer en mode “dictateur”, et TFS propose une solution simple pour y arriver : les alertes.

Afin “d’encourager” les membres d’une équipe il suffit de se créer une alerte sur tous les checkins lié à un Team Project :

image

Une fois le mail d’alerte reçu, sachez qu’il est possible de directement répondre à ce mail afin de communiquer avec le développeur. – Je vous invite à consulter cet ancien post qui décrit le process -.

Ainsi vous pouvez réagir très rapidement à ces mauvais commentaires en demandant au développeur fautif de modifier à posteriori son commentaire afin qu’il soit pertinent.

Après avoir reçu plusieurs mails de rappel à l’ordre demandant de corriger le problème, les plus récalcitrants rentrent ainsi dans le bon chemin sur une période de temps assez courte (environ 1 mois dans mon cas).