Le Post Infeeny

Les articles des consultants et experts Infeeny

Archives Mensuelles: décembre 2016

Héberger un package Nuget sur Team Services et l’alimenter depuis une build

Objectif : 

L’objectif de cet article est de vous présenter comment automatiser depuis Team Services la génération d’un ensemble de classes qui seront ajoutées dans un package NUGET hébergé sur TFS online.

Contexte : 

Une solution VS contient un ensemble de classes communes à plusieurs projets.
Ces classes sont regroupées dans des librairies que l’on veut pouvoir accéder depuis NUGET.

vso_nuget_sc1

Création du container sur VSTS : 

Pour créer le container, vous devez aller dans la section « Packages » du menu « Build & Release ». Si vous ne voyez pas le menu, c’est que vous devez préalablement sélectionner un projet.

vso_nuget_sc2

Si vous n’avez pas le menu package depuis votre interface, vous devez aller dans le MarketPlace et installer Package Management (https://marketplace.visualstudio.com/items?itemName=ms.feed)

Vous pouvez alors ajouter un « feed ». Nous vous conseillons de laisser les options par défaut pour le moment.

Une fois créé, il faut modifier les droits de ce dernier. Pour cela aller dans la section « Permission », et ajouter aux contributeurs les comptes « Project Collection Build Service » et « Project Build Service ». Ces deux comptes sont ceux qu’utilisera le Publisher Nuget lors de la Build.

De même vous pouvez restreindre les accès en lecture à certains groupes si vous le désirez.

vso_nuget_sc3

Le container est maintenant créé, il faut l’alimenter.

Création de la Build : 

Nous allons maintenant créer la Build qui générera le package et le mettra dans le feed. Pour cela aller dans Builds et Cliquer sur « New » et choisir une le template Visual Studio.

Dans les étapes, supprimer les modules « Publish symbols path », « Copy Files » et « Publish Articfact », et ajouter les tâches « Nuget Packager » et « Nuget Publisher ».

On peut commencer le paramétrage de chaque étape.

La première consiste à restaurer les packages Nuget nécessaires à la compilation des projets.
Pour cela on sélectionne le path du fichier solution .sln.

vso_nuget_sc4

On procède de la même manière sur l’étape de compilation.

Comme notre solution comporte des tests unitaires, nous laissons l’étape de tests. Ainsi, s’il y a une régression, la build sera en erreur et le package ne sera pas généré.

Concernant l’étape « Nuget Packager », il est possible de spécifier un fichier .sln ; toutes les dlls de la solution seront alors intégrées dans le package, ou préciser un fichier de configuration.
Pour ne pas ajouter des dlls inutiles (celles du framework, celles des librairies de tests), nous faisons le choix de sélectionner un fichier de configuration .nuspec. Ce fichier ajouté manuellement se trouve à la racine de la solution.
Voici le fichier actuellement utilisé :

<?xml version= »1.0″ encoding= »utf-8″?>
<package xmlns= »http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd »&gt;
<metadata>
<id>CommonLibraries</id>
<version>2.0.1</version>
<authors>MCNEXT</authors>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<developmentDependency>true</developmentDependency>
<summary />
<releaseNotes />
</metadata>
<files>
<file src= »0-Services\bin\Debug\0-Entites.dll » target= »lib » />
<file src= »0-Services\bin\Debug\0-Helpers.dll » target= »lib » />
<file src= »0-Services\bin\Debug\0-Repository.dll » target= »lib » />
<file src= »0-Services\bin\Debug\0-Services.dll » target= »lib » />
</files>
</package>

Les données obligatoires sont l’id, le numéro de version et la liste des fichiers.
Le numéro de version est dans ce fichier une valeur fixe. Elle sera écrasée par la build à chaque incrément.

Voici le détail de la configuration :

vso_nuget_sc5

Remarquons que le package généré se trouvera dans le répertoire $(Build.StagingDirectory) et que nous automatisons le versionning en utilisant l’horodatage.

Enfin la dernière étape consiste à publier le package Nuget généré vers le container créé précédemment.
Nous précisons la localisation du package nuget à déployer, tout en supprimant les packages importés lors de la compilation ; le type de Feed, et l’url de ce dernier qui nous a été fournie lors de sa création.vso_nuget_sc6

 

La build est prête, vous pouvez la lancer pour générer votre premier package.

Maintenant nous allons voir comment l’utiliser dans vos solutions.

Importer le package Nuget dans son projet

La première étape est d’ajouter le container à Visual Studio.
Pour cela aller dans Visual Studio, Outils -> Options, ajouter la source de package avec l’url du feed.

Vous pouvez alors ajouter le package Nuget à votre solution/projet en utilisant le package manager de Visual Studio.

vso_nuget_sc8

Il est possible que pour l’installation ou les mises à jour vous ayez besoin de cocher « Include prerelease ».

Importer le package Nuget lors d’une build

Si votre projet consommateur du package Nuget généré est intégré à une build, il faut préciser à l’agent de Build comment récupérer le package pour compiler.

Pour cela, lors de l’étape de restauration du package Nuget, il ne faut pas préciser le path du fichier Solution (.sln) mais plutôt utiliser un fichier de configuration.

Dans chaque solution, nous avons normalement un fichier NuGet.Config dont nous modifions le contenu comme tel :

<?xml version= »1.0″ encoding= »utf-8″?>
<configuration>
<solution>
<add key= »disableSourceControlIntegration » value= »true » />
</solution>
<activePackageSource>
 <add key= »All » value= »(Aggregate source) » />
</activePackageSource>
<packageSources>
<add key= »nuget.org » value= »https://www.nuget.org/api/v2/ &raquo; />
<add key= »CommonLibraries_DEV » value= »https://monurl.pkgs.visualstudio.com/_packaging/CommonLibraries_DEV/nuget/v3/index.json »/&gt;
</packageSources>
</configuration>

Les informations à ajouter sont le paramètre activePackageSource où nous spécifions que nous voulons importer tous les packages.
Et bien sûr, le package à importer.

Dans la configuration d’une build d’un projet, le path est à préciser dans le champs « Path to Nuget.config »

vso_nuget_sc9

 

La build est paramétrée pour importer correctement le package Nuget créé en interne.

 

Nous venons de voir comment configurer un  package Nuget dans VSTS. Cette génération peut très bien être déclenchée dans le cadre d’une intégration continue.

Une étude plus approfondie peut être faite sur la génération du numéro de version pour éviter de rechercher les nouvelles versions du package en cochant ‘pre-release’.

Why and how we started contributing to Patterns & Practices

Our journey with Patterns & Practices

Our journey with Patterns & Practices started when we first saw the project on GitHub, maybe two years ago. We already had our own internal framework so we just checked what this new tool could do for us. It clearly didn’t cover all our use cases, and we would still have to use our own framework.

Then I came to Ignite in 2015, and I saw Vesa Juvonen presenting the provisioning framework. It was like “Damn, it has grown a lot!”. We started using it as nugget package. It was still not covering all our use cases, but we were migrating our code slowly. As a lot of people were using this project, we found PnP functions more tested than ours, and it was great. We still had our framework tho, but it was disappearing.

But we still had issues:
        We couldn’t debug when we had a problem
        We had to wait for fixes, so we copied PnP functions in our framework to fix them for ourselves
        We had to go to GitHub and browse files to understand fully all we could do with this framework

Contributing

And then, we decided to fork the project (we are using PnP-Sites-Core as a fork, as this is the project we use the most). When you know git (and I really recommend reading at least the first three chapters of the git documentation if you are new to it), it is really fast to set up your environment for development.

Our contribution workflow is:

contribution-patterns-practices

1.      We locally clone our fork
2.      When we want to do some changes, we create a branch for this change that we merge to master when it’s ready
3.      We have a dev branch, created from the tracked PnP-Sites-Core dev branch
4.      When we have something interesting to propose we create a branch, get the commits from our master branch and create the pull request

We then just have to regularly get updates from PnP repositories, and reference our fork as a submodule in other projects.

This new approach has some advantages:
        Our whole team has a better understanding of how the project works
        We can debug
        We don’t have to wait for official fixes
        We can add our own code directly into the framework
        It’s exciting to take part of a bigger community 

5 pull requests merged so far, and a 6th waiting 🙂