Le Post Infeeny

Les articles des consultants et experts Infeeny

Bienvenue sur le Post de Infeeny !

MCNEXT devient Infeeny en 2017 !
www.infeeny.com

Retrouvez ici tous les Posts des consultants et experts du groupe Infeeny (+ de 600 posts !)

Vous voulez en savoir plus sur Infeeny ou vous souhaitez nous rejoindre ?
Consultez notre site corporate www.infeeny.com

Vous pouvez aussi nous suivre sur :
Twitter : @Infeeny_fr – https://twitter.com/Infeeny_fr
LinkedIn : https://www.linkedin.com/company/infeeny
– et vous abonner à notre chaîne YouTube Infeeny !

Compiler et minifier les fichiers .less en fichier min.css

Objectif

L’objectif de cet article est d’ajouter une tâche Gulp à vos build définis sur VSTS pour compiler et minifier les fichiers .less.

Prérequis

  • Un projet VSTS avec une application web ASP.NET.
  • Une définition de build pour l’application ASP.NET du projet
  • Installer Node.js :
    • Sur le poste de développement pour définir la tâche Gulp
    • Sur le serveur de build, pour exécuter la tâche Gulp

Création de la tâche Gulp

La création de la tâche Gulp pour compiler et minimiser les fichier .less en fichier .min.css, est faite sur un poste de développement au sein de visual studio 2015.

Poste de développement

Prérequis

En plus de l’utilisation de visual studio 2015, il faut installer :

  • Node.js : pour la gestion et l’exécution des package npm. A télécharger ici
  • Task Runner Explorer: Il s’agit d’une extension pour Visual Studio afin de tester et gérer les tâches Gulp. A télécharger ici

Configurer gulp pour l’application web

Il faut ajouter au projet de l’application web 2 fichiers afin de configurer gulp :

  • gulpfile.js : contient les définitions des tâches Gulp à exécuter
  • package.json : contient les listes des packages nécessaire à l’exécution des tâches définies dans le fichiers précédents

Script de la tâche gulp « less » pour compiler et minifier les fichiers .less en .min.css

var gulp = require('gulp');
var less = require('gulp-less');
var path = require('path');
var watch = require("gulp-watch");
var rename = require('gulp-rename');
var minifyCSS = require('gulp-minify-css');
var plumber = require('gulp-plumber');

gulp.task('less', function () {
    return gulp.src('./Content/**/*.less')
    .pipe(plumber())
      .pipe(less({
          paths: [path.join(__dirname, 'less', 'includes')]
      }).on('error', function (err) {
          console.log(err);
      }))
      .pipe(minifyCSS().on('error', function(err) {
            console.log(err);
       }))
        .pipe(rename({suffix: '.min'}))
      .pipe(gulp.dest('./content/'));
});
Et ci-dessous le fichier de configuration package.json associé
{
  "name": "Mon projet",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "gulp": "^3.9.1",
    "gulp-less": "^3.3.0",
    "gulp-rename": "^1.2.2",
    "gulp-minify-css": "^1.2.4",
    "gulp-watch": "^4.3.11",
    "gulp-plumber": "^1.1.0"
  }
}

 Tester la tâche Gulp

Sous Visual Studio :

  • Cliquez droit sur le fichier gulpfile.js
  • Dans « l’explorateur de solution »cliquez sur « Task Runner Explorer »Menu_Task_runner.png
  • Dans la fenêtre de « Task Runner Explorer », Cliquez droit sur la tache « install » du package.json
  • Cliquez sur « Run »pour installer les packages en local à la solutionRun_Task_Install.png
  • Dans la fenêtre de « Task Runner Explorer », Cliquez droit sur la tache « less »
  • Cliquez sur « Run »pour exécuter le test de la tâcheRun_Task_runner

Ajouter la tâche au build VSTS

Prérequis sur le serveur de build

Le serveur de build doit contenir tout le nécessaire à la compilation de la solution. Node.js doit donc être installé sur le serveur de build. A télécharger ici

Modification de la définition du build VSTS

  • Connectez sur VSTS
  • Allez dans « Build & Realease »/Builds
  • Editez la définition du build pour lequel vous souhaitez ajouter la tâche Gulp
  • Ajoutez une tache « NPM »Add_Task_Npm
  • Configurez cette tache afin d’installer les package npm nécessaire à l’exécution sur la tâche gulp précédemment créée: « less »
    • Working folder : répertoire du projet contenant le fichier package.json
    • npm command : install
    • arguments : -configConfig_Task_Npm.png
  • Ajoutez une tâche « Gulp » afin d’exécuter la tache « less »Add_Task_Gulp
  • Configurez cette tâche afin d’exécuter la tâche gulp précédemment créée: « less »
    • Gulp File Path : Chemin du répertoire du projet contenant le fichier gulpfile.js
    • Gulp Task(s) : nom de la tâche à exécuter
    • Arguments : Arguments nécessaire à la tâche
    • Working Directory : Chemin du répertoire de travail, comme on travaille avec les packages npm définis pour le projet, il s’agit du répertoire du projetConfig_Task_Gulp.png
  • Cliquez sur « Save »

Maintenant votre build VSTS exécute une tâche Gulp pour compiler et minifier les fichiers .less !

 

Getting started with Azure Search and the .NET SDK

search

In order to provide an alternative to ElasticSearch as a more convenient and straightforward solution, Microsoft introduced Azure Search, an Azure service based on ElasticSearch. Both solutions provide a dedicated environment for indexing and querying structured or semi-structured data. Azure Search, however, focuses on simplicity, to the expense of some of the features you may expect if you come from the more complex engines.

For starters, Azure Search is more rigid: it is contract-based, meaning you have to define the indexes and the structure of your documents (indexed data) before you can index anything. The document structure itself is simplified and aimed at simple use cases and you won’t have all the options ElasticSearch can offer. The most important limitation to keep in mind is that you cannot include complex types in your document structure.

You should really be aware of these limitations when considering Azure Search as a production tool. But if you’re going for a quick, low maintenance and scalable solution, it may very well fit your needs.

Now if you’re still there, let’s start by deploying it on Azure.

Deploying your Azure Search service

Provided you already have an Azure subscription running, setting Azure Search up couldn’t be easier. Just go to the official service page and hit « Try search azure now »… or just click this link.

AzureSearchDeploy

The Azure Search service creation page. Tier prices are removed because they may vary

The service configuration is straightforward: just enter an identifier to be part of the URL of your search service (in the example, « sample-books »), select the usual Azure subscription, resource group and location, and choose the pricing option that best matches your needs. You can even select a free plan if you just want to try it out.

Once you hit the Create button and the service is deployed, we can access its dashboard page and start configuring it.

AzureSearchDashboard

Our new Azure Search service’s Overview page

As you can see there, the service is available right away at the URL provided in the configuration, listed under URL on the overview page.

However, in order to make it operational, we have to create an index. If you’re not familiar with indexes, they are like collections of documents (data) sharing a similar structure, that are processed in order to optimize searches. Because documents live in an index, we are not going anywhere without one.

So let’s get this going by clicking the Add index button.

AzureSearchIndexCreation.png

The Azure Search index creation page

This takes us to another config view where you have to input the name of the index, and the structure of the documents in the index. The structure works pretty much like any graphic database table creation form — you can add fields with a type, and a handful of options that let the engine know how your document should be processed, which in turn affects how the fields behave in search queries.

The mandatory « id » field that comes pre-created will be used as a unique identifier for our documents — if you are trying to index a document and the id has already been indexed, the existing document will be updated.

In our example, each document represents a book. So we set up a few fields that we want indexed for our books.
Here is a quick breakdown of the options for your fields:

  • Retrievable: determines whether the field will be included in the query responses, or if you want to hide it;
  • Filterable: determines the ability to filter on the field (e.g. take all documents with a pageCount value greater than 200);
  • Sortable: determines the ability to sort by the field;
  • Facetable: determines the ability to group by the field (e.g. group books by category);
  • Searchable: determines whether the value of the field is included in full text searches

Our example is set up so that the title, author and description are processed in full search, but not the category. This means that a full text search query for « Mystery » will not include books of the category Mystery in the results.

Once you are done with the creation, your index is ready, although still empty and sad… so let’s fix that!

Indexing data

The next thing to do is indexing actual documents. In our example, this means indexing books.

There are two ways to do this:

  • Adding a data source and an indexer, meaning that Azure Search is going to crawl your data source (Azure Storage, DocumentDB, etc) periodically to index new data;
  • Indexing documents through the REST API, either directly, or indirectly with an SDK.

And of course, nothing prevents you from doing both. But in our case, we are going to index documents programmatically, using C# and the .net Azure Search SDK.

So let’s dig into the coding. As a side note, if you’re allergic to code, you can skip right to the start of the next part, where we play around with Azure Search’s query interface.

First, we’re going to create a console application and add the Azure Search SDK NuGet package.

AzureSearchNugetPackage

Installing the Azure Search SDK through the NuGet Package Manager view on VS2015

Alternatively, you can run the following NuGet command:

> Install-Package Microsoft.Azure.Search

Next, we are going to need a Book POCO class with properties matching the indexed fields. Rather than breaking the naming conventions of C# and using camelCase for our properties, we are going to use the SerializePropertyNamesAsCamelCase attribute to tell the SDK how it is supposed to handle our properties when uploading or downloading documents.

So here is our Book.cs:

[SerializePropertyNamesAsCamelCase]
public class Book
{
    public string Id { get; set; }
    public string Title { get; set; }
    public string Author { get; set; }
    public string Description { get; set; }
    public string Category { get; set; }
    public int PageCount { get; set; }
    public bool IsAvailableOnline { get; set; }
}

Next, we will need to create a client that connects to our Azure Search service. Using a bit from the official documentation, we can write the following method:

private static SearchServiceClient CreateAdminSearchServiceClient()
{
    string searchServiceName = "sample-books";
    string adminApiKey = "Put your API admin key here";

    SearchServiceClient serviceClient = new SearchServiceClient(searchServiceName, new SearchCredentials(adminApiKey));
    return serviceClient;
}

Note that you can find your keys in the Azure Service page, under the « Keys » section. You have to use an admin key in order to create indexes or index documents.
AzureSearchAdminKey.png

Now let’s write a method that indexes a few sample books:

private static void UploadDocuments(ISearchIndexClient indexClient)
{
    var books = new Book[]
    {
        new Book()
        {
            Id = "SomethingUnique01",
            Title = "Pride and Prejudice",
            Author = "Jane Austen",
            Category = "Classic",
            Description = "Set in the English countryside in a county roughly thirty miles from London...",
            IsAvailableOnline = true,
            PageCount = 234
        },
        new Book()
        {
            Id = "SomethingUnique02",
            Title = "Alice's Adventures in Wonderland",
            Author = "Lewis Carroll",
            Category = "Classic",
            Description = "Alice was beginning to get very tired of sitting by her sister on the bank...",
            IsAvailableOnline = true,
            PageCount = 171
        },
        new Book()
        {
            Id = "SomethingUnique03",
            Title = "Frankenstein",
            Author = "Mary Wollstonecraft Shelley",
            Category = "Horror",
            Description = "You will rejoice to hear that no disaster has accompanied...",
            IsAvailableOnline = true,
            PageCount = 346
        }
    };

    // Make a batch with our array of books
    var batch = IndexBatch.MergeOrUpload(books);

    // Query the API to index the documents
    indexClient.Documents.Index(batch);
}

As you can see, the SDK allows us to use directly our Book objects in its upload methods, performing the REST API query for us.

Note that for the purpose of simplicity, we’re not handling exceptions, but you should really do it in production code.

Also keep in mind that your documents will not be instantly indexed. You should expect a little delay between document upload and their availability in index queries. The delay depends on the service load, but in our case a few seconds should be enough.

So let’s set up our program to call these methods and index the books.

static void Main(string[] args)
{
    var serviceClient = CreateAdminSearchServiceClient();
    // Get the index client by name - use your index name here
    var indexClient = serviceClient.Indexes.GetClient("mybookindex");
    UploadDocuments(indexClient);
}

After running the program, if it ran alright and after the aforementioned delay, you should have your data indexed already.

You can check that your documents have been uploaded on the Azure dashboard page.

AzureSearchDocumentsIndexed.png

On the Azure overview page for our service, we can see that there are 3 documents indexed

Alright! When you’re done with the indexing, all that’s left to do is query!

Querying documents

So, our Azure Search service is up and running, with an operational index and some documents to go along. Let’s get to the core feature: querying documents.

For the purpose of illustration and to get a better understanding of what we will be doing next with the SDK, we are going to start with the Azure Search query interface called Search Explorer.

And sure enough, you can access it through the Search Explorer button on the overview dashboard.

AzureSearchExplorer0.png

The Azure Search Explorer default view

The Query string field roughly corresponds to the part after the « ? » in the URL when you query the rest API in a get request.

In the Request URL field below, you can see the full URL that will be called to execute your query.

And finally, the Results field shows the raw JSON response from the service.

Now let’s try it out with some examples:

AzureSearchExplorer2

An example of a full text search

In this example, we are searching for the term « disaster ». This will cause Azure Search to perform a full text search on every field that is marked as Searchable in the index document structure. Because the book « Frankenstein » has the word « disaster » in its description field, and that field is marked as Searchable, it is returned.

If we replace our search term with « Horror », the service returns no results, even though the value of category is literally « Horror » in the case of Frankenstein. Again, this is because our category field isn’t Searchable.

AzureSearchExplorer3

An example of a search using filters

This second example retrieves all books with more than 200 pages. I won’t explain the whole syntax here because there would be too much to write and it is already explained in the search documentation. In essence, we are using the $filter parameter to limit results to the documents satisfying the condition « pageCount gt 200 », which means that the value of pageCount has to be greater than 200 for a document to pass the filter.

Now that we have some clues about how the search API works, we are going to have the SDK do half of the job for us. Let’s go back to our C# .net project.

The first thing we want to start with when querying is a SearchServiceClient… and I know we already built one in part 2, but we are not going to use this one. When you are only querying, you’ll want to use a query API key instead of an admin key, for security reasons.

You can get those keys in the Keys section of the Azure Search service page, after clicking the Manage query keys link.
AzureSearchQueryKeys.png
You are free to use the default one. In my case, I added a new key called « mykey » because I don’t like using an unnamed key and obviously « mykey » is much more descriptive.

So let’s write our new client creation method:

private static SearchServiceClient CreateQuerySearchServiceClient()
{
    string searchServiceName = "sample-books";
    string queryApiKey = "YOUR QUERY API KEY HERE";

    SearchServiceClient serviceClient = new SearchServiceClient(searchServiceName, new SearchCredentials(queryApiKey));
    return serviceClient;
}

Of course this is almost the same code as before and we should really refactor it, but I’m leaving that as an exercise to the reader. For the sake of simplicity, of course.

Once we got that, we are going to write the methods that query our books. Let’s just rewrite the tests we have done with the Search Explorer, using the SDK. We will write 2 separate methods, again for the sake of clarity:

private static Book[] GetDisasterBooks(ISearchIndexClient client)
{
    // Query with the search text "disaster"
    DocumentSearchResult response = client.Documents.Search("disaster");

    // Get the results
    IList<SearchResult> searchResults = response.Results;
    return searchResults.Select(searchResult => searchResult.Document).ToArray();
}

private static Book[] GetBooksWithMoreThan200Pages(ISearchIndexClient client)
{
    // Filter on documents that have a value in the field 'pageCount' greater than (gt) 200
    SearchParameters parameters = new SearchParameters()
    {
        Filter = "pageCount gt 200"
    };

    // Query with the search text "*" (everything) and include our parameters
    DocumentSearchResult response = client.Documents.Search("*", parameters);

    // Get the results
    IList<SearchResult> searchResults = response.Results;
    return searchResults.Select(searchResult => searchResult.Document).ToArray();
}

What we can see here is that you have all the URL parameters we can use in the optional SearchParameters object, except the search text itself, which is specified as a separate parameter of the Search method.
And once again, the SDK is capable of using directly our Book class and retrieves Book objects by deserializing the response from our Azure Search service, in a transparent way.

Now let’s use these methods in our program:

static void Main(string[] args)
{
    var queryServiceClient = CreateQuerySearchServiceClient();
    var queryIndexClient = queryServiceClient.Indexes.GetClient("mybookindex");

    var disasterBooks = GetDisasterBooks(queryIndexClient);
    Console.WriteLine("GetDisasterBooks results: " + string.Join(" ; ", disasterBooks.Select(b => b.Title)));
    var moreThan200PagesBooks = GetBooksWithMoreThan200Pages(queryIndexClient);
    Console.WriteLine("GetBooksWithMoreThan200Pages results: " + string.Join(" ; ", moreThan200PagesBooks.Select(b => b.Title)));

    Console.ReadKey(false);
}

The client part is similar to what we did when we were indexing documents, and the rest is just getting the results from the query methods and displaying them with Console.WriteLine.

And running this program gets us this beautiful output:

GetDisasterBooks results: Frankenstein
GetBooksWithMoreThan200Pages results: Pride and Prejudice ; Frankenstein

Going deeper

We have seen how to deploy an Azure Search service, how to create and configure its indexes, and how to use the SDK for both indexing and querying documents. As mentioned in the previous parts, there is a bit more that you can do with Azure Search and that go beyond the scope of this article.

If you want to go further, here are some points we haven’t discussed, along with links providing documentation on the topic:

Thanks for reading and I hope this article at least made you want to read more classical literature.

[SSRS][PowerBI] Introduction a Power BI dans le Server de Rapport SQL Server (SSRS)

Suite à de nombreuses demandes d’utilisateurs ne souhaitant pas voir leur donner partir dans le cloud Microsoft.

Microsoft à mis en place 2 solutions à dispositions pour la partie Power BI :

  • La mise en place d’une gateway permettant de ne pas exporter les données dans le cloud
  • La création d’un serveur de rapport SSRS permettant d’héberger des rapports Power BI conçu à partir de Power BI Desktop

Dans cette introduction nous allons étudiés la solution numéro qui vient de sortir en mode pré view dans la vNext de SQL Server

Lire la suite

Mettre en place du déploiement continue en local depuis VSTS

Objectif

L’objectif de cet article est de vous présenter comment mettre en place une chaine de déploiement continue sur un serveur IIS local, hébergé sur votre réseau, à partir de code source stocké dans Visual Studio Team System.

Contexte

Vous stockez  sur VSTS les code sources de vos différents projets applicatifs, mais vous aimeriez mettre en place un chaine de déploiement continue sur vos propres serveurs OnPremise n’ayant pas accès à internet à partir du code source contenu dans votre environnement VSTS.

La solution est de passer par un serveur build intermédiaire qui effectuera aussi le déploiement en local. Ce dernier  aura donc un accès à VSTS et au serveur cible IIS hébergé dans le réseau interne.

VSTS_BuildInterne

Serveur de Build

Nous avons utilisé dans notre cas un serveur de Build avec Windows Server 2012 R2. Mais il est possible d’utiliser le poste de développement en guise de serveur de Build, à condition de respecter les prérequis suivant :

 

L’environnement de développement doit être installé sur le serveur de build et l’agent de build, afin que celui-ci puisse effectuer la compilation du code source contenu dans le VSTS.

Installation et Configuration

Environnement de développement

Il est préférable d’installer et de configurer l’environnement de développement avant de configurer l’agent de build, car ce dernier détecte automatiquement l’environnement du serveur lorsqu’il se connecte à VSTS.

Dans notre cas nous avons installé :

  • Visual Studio 2015 Enterprise, version minimum recommandée
  • NodeJs pour la compilation des less avec gulp
  • Framework 4.6.2

Agent de build

Prérequis de sécurité

Pour installer et configurer l’agent de build, utiliser un compte qui soit à la fois Administrateur du Serveur de build et qui soit administrateur dans VSTS.

Authentification avec un « Personal Access Tokens »
  • Connectez vous sur votre VSTS avec le compte administrateur que vous souhaitez utiliser
  • Ouvrez le profil du compte
  • Allez dans sécurité

PAT_1

  • Allez dans Personal Acces Tokens
  • Cliquez sur PAT_2
  • Cochez seulement le scope Agent Pools (Read, manage), et veillez à laisser les autres décoché

PAT_3.png

  • Cliquez ensuite sur PAT_4

PAT_5

  • Copiez le token ainsi obtenu

Note : Veillez à conserver précieusement le token généré, il sera utile pour configurer et supprimer l’agent.

Installation

Pour installer l’agent sur le serveur de build :

  • Connectez vous sur le serveur de build, avec un compte administrateur
  • Depuis le serveur, connectez vous sur votre VSTS avec un compte administrateur.
  • Allez dans Settings\Agent Pools
  • Cliquez sur  DownLoadAgnet

Une fenêtre contenant les commandes à effectuer pour installer sur différent OS s’ouvre.

DownLoadAgent_2

Lancer le téléchargement à la fin de celui-ci exécuter les commandes PowerShell du bloc Create Agent. Ceci décompressera le zip précédemment téléchargé dans le répertoire C:\agent.

Configuration

Création du pool

Lors de la configuration de l’agent de build, nous allons le rattacher à un pool que nous avons spécialement créé :

  • Connectez vous sur votre VSTS avec un compte administrateur.
  • Allez dans Settings\Agent Pools
  • Cliquez sur « New Pool… » New_Pool
  • Dans la fenêtre de saisie, entrez le nom du nouveau pool : « Interne »

Create_Pool

Agent de build

Nous pouvons passer, maintenant, à la configuration de l’agent de build :

  • Dans la console PowerShell  en tant qu’administrateur, placez vous dans le répertoire où a été installé l’agent
  • Exécuter la commande :Configuration_agent_1

Un assistant de configuration en ligne de commande PowerShell démarre :

Connexion à VSTS :

Configuration_agent_Connection_PS_3
  • Saisissez l’URL VSTS : https://{your-account}.visualstudio.com
  • Sélectionnez le type authentification PAT (précédemment configuré avec le compte que vous utilisé)
  • Saisissez le jeton précédemment généré

Inscription de l’agent sur VSTS :

Configuration_agent_Inscription_PS_4

 

  • Saisissez le nom du pool d’agent précédent créé : Interne
  • Saisissez le nom de l’agent, par défaut il vous propose le nom du serveur : BuildInterne
  • Saisissez le dossier de travail de l’agent : _workVSTS
  • Choisissez de l’exécuter en tant que Service, en saisissant ‘O’
  • Choisissez le compte par défaut

Résultat :

  • Connectez vous sur votre VSTS
  • Allez dans Settings\Agent Queues

Vous  devez voir le résultat suivant :

Configuration_agent_Resultat_VSTS

Vous pouvez utiliser maintenant le pool Interne dans la configuration de vos Builds.

Note : Sur un serveur de build, vous pouvez installer plusieurs agent de build, il faut juste les utiliser des répertoires d’installation différents.

Création d’un Build VSTS

  • Connectez sur VSTS
  • Allez dans « Build & Realease »/Builds

 

Create_Build_1.png

  • Cliquez sur New

Create_Build_2

  • Sélectionnez le Template ASP.NET et cliquez sur « Apply »

Create_Build_3

  • Allez dans l’onglet « Triggers » pour activer l’intégration continue
  • Préciser la branche à surveiller

 

Create_Build_4.png

  • Allez dans l’onglet « Options » pour sélectionner l’agent interne précédemment créé

Create_Build_5.png

  • Allez dans l’onglet « Variables » Afin de modifier :
    • BuildConfiguration selon la configuration souhaitez (Release, Debug, ou une que vous avez créée dans votre solution). Dans notre cas, nous avons créé la configuration de Build « Developpement »

Create_Build_Variables

  • Cliquez sur « Save »

Save_Build_6.png

  • Cliquez sur « Save »

 

Déploiement automatique

L’objectif est déployer automatiquement sur le serveur cible IIS, le dernier package compilé par le pool de build que nous venons de créer avec l’agent « BuildInterne ».

Configuration du serveur Cible

Dans notre cas nous effectuons le déploiement automatique sur un serveur web IIS Windows server 2012 R2.

Sur ce dernier, il faut activer WinRM : Remote Management.

WinRM

Pour activer WinRM sur Windows Server 2012 :

  • Connectez vous sur le serveur Cible
  • Ouvrir sur le serveur Server Manager > Local Server

Server_manager

Site Web Cible

Dans notre exemple, nous allons mettre en place un déploiement automatique sur un site web existant que nous allons créer sur le serveur manuellement. mais cette action est parfaitement automatisable dans le processus de déploiement automatique.

  • Connectez vous sur le serveur cible
  • Ouvrir sur le serveur IIS manager
  • Ajouter un nouveau site Web, par exemple : WebInterne sur un port libre

Note : Pensez bien à ouvrir le port utilisé sur le serveur cible

Créer une release

  • Connectez sur VSTS
  • Allez dans « Build & Realease »/Releases

Create_release_1

  • Cliquez sur « Create release definition »

Create_release_2

  • Sélectionnez Empty et cliquez sur Next
 Create_release_3
  • Sélectionnez votre projet
  • Sélectionnez la définition du build que vous avez précédemment créé
  • Cochez « Continuous Deployement », pour le déploiement s’exécute à chaque nouveau build.
  • Cliquez sur Create

Ajout de tâches

Maintenant que la release a été créé vide, il faut lui ajouter des tâches à exécuter.

Task_release_1.png

  • Modifier le nom de la Release : Interne
  • Liez la release à un package de déploiement :
    • Cliquez sur « Link to an artifact source « Link_to_artefact_release_2.png
  • Sélectionnez la queue de déploiement :
    • Celle que nous avons précédemment créée : Interne

Select_Queue_release_2.png

  • Cliquez sur « Add tasks » :
    • Windows Machine File Copy
      • Ajouter la tache « Windows Machine File Copy », afin de copier le package à déployer sur le serveur cible.Add_Task_Copy_files.PNG
      • Configurez cette tache de copie :
        • Sélectionner le fichier compresser dans le package précédemment lié,Select_Package_release_3
        • Select_Package_release_4
        • Select_Package_release_5
    • WinRM – IIS Web Deployment
      • Ajoutez la tache « WinRM – IIS Web Deployment »Add_Task_Web App Deployment
        • Si cette dernière n’est pas disponible, il faut ajouter l’extension à votre VSTS depuis le market Visual Studio ici.
      • Configurez la tache :
        • WinRM :
          •  Machines : Nom réseau du serveur cible
          • Admin Login/Password : Login et Password d’un compte admin sur le serveur cible
          • Protocol : Sélectionnez le protocole utilisez par le WinRM sur le serveur cible
        • Deploiement :
          • Web Deploy Package : Nom et chemin de copie du package de déploiement, définie dans la tache précédente
          • Website Name : Name du site web précédemment créé : InterneWebApp_release_.png
  • Allez dans l’onglet « Triggers » :
    • Cochez « Continuous Deployment »
    • Sélectionnez le nom du build à surveiller et pour quelle branche le build a été effectuéTriggers_release_.png

 

 

Activating Office 365 groups is not an option

 I see a lot of different reactions when it comes to Office 365 groups. But there is one thing that unites close from every IT department I know : deactivate it, hide it ! (and pray for users to not get aware of its existence). Caricature ? Maybe

Reasons ?

  • We are not ready
  • We can’t control everything yet
  • We have difficulties matching every tool with a use case
  • We only want users to have the tools we decided they needed

Here is why those arguments are irrelevant in my opinion.

growefficiently-turntocloud

Everything is built upon groups

This is SaaS. Microsoft is deciding (with feedback from users of course) what the future is. And Microsoft decided the future will be built upon groups.

Lots of features have rolled out, some others are rolling out right now. And not only for first release customers. The only way to go back to good old SharePoint Sites : stop Office 365.

We are building technical debt

Technical debt is something we fight a lot as developers. Every problem, every bug that we just hide will come back one day. And it will be far more difficult to fix. We all know what happens when we shut down some work because we have other priorities. We will always have other priorities.

One day we will have to activate it,  whether there is no more ability to stop it or because no tool works without. And it is going to hurt. A lot.

This is the perfect moment to prepare

Features are rolling out, one by one. It is easy to stay tuned, news after news. We still have time. The perfect moment to try it. To get feedback from users. To check which tools we prefer for our usages. To build our adoption strategy. We may be surprised, as users may prefer groups to the big SharePoint template we spent months building.

All the time we spend creating SharePoint branding that will be obsolete in 6 months. All the energy we spend trying to hide O365 features. We could be monitoring usages, communicating, building adoption strategies, building tools to do what groups don’t do.

What’s wrong with giving tools to users ?

Everything that is rolling out now is just a set of extra tools users can have. Why so much hate ? It’s like IT departments want to tell people a list of scenarios with a tool attached to each one. We want to control everything. We are control freaks. There are reasons we build procedures, of course. But sometimes we should let go.

Maybe users know better than us what they need. Maybe they are used to massive tooling in there private life. Maybe they are now using Slack + Dropbox + Trello and have the same features but without you monitoring it. Maybe they just need a go and will be delighted to use those tools. Maybe not. The best way to know is to go for it, and get feedback. Feedback, iterative or lean strategies are not only for startups !

What is the worst case scenario ?

Users creating an important amount of groups, and information is not well organized ? Users creating groups they shouldn’t create ? Users uploading top secret documents in external groups ?

We can have power users with a global vision of the team and responsible for organizing work and data. Those people are already organizing other content in their team.

We can classify groups to remind users about what content should be in each group. We will soon be able to apply policies with each classification.

Users are adults with responsibility on their actions. We don’t block  every action that could be possibility dangerous if maybe someone was doing something very stupid. Or it is not yet the case in my country. We should stop doing that in IT every day, treating users as brainless children.

If you really need to ensure some documents will never ever possibly get out of your company, there are true solutions.

So what now ?

We don’t have to use everything now. We don’t have to love every feature. We don’t have to stop everything we had and migrate to groups. But we have to get used to them. And I think we will finally love using them.

[SQL 2016]Introduction au Row Level Security

Voici une nouveauté intéressante de SQL Server 2016

Le Row Lever Security (RLS)

Qu’est-ce que c’est ?

Le Row Level Security permet de sécuriser des données au niveau des lignes.

Grace au Row Level sécurité on peut attribuer des rôles et afficher les données correspondant au rôle correspondant à l’utilisateur logué.

Lire la suite

Introduction à PolyBase

PolyBase :

Polybase est une technologie qui permet de requêter et de combiner des données non-relationnelles et relationnelles à partir de SQL Server

PolyBase supporte Hadoop et Azure Blob Storage

Les requêtes sont optimisées pour pousser le calcul vers Hadoop

Comment créer une table polybase :

Lire la suite

Les Temporal Table SQL Server 2016

A la sortie de SQL Server 2016 une nouvelle fonctionnalité est arrivée :

Les Temporal Table !

Qu’est-ce que c’est ?

Vous avez tous eu besoin un jour ou l’autre de devoir auditer vos tables de vos bases de données

Jusqu’à maintenant des solutions existaient :

  • Change Data Capture
  • SQL Broker
  • La mise en place de Trigger ?
  • Lecture des logs ?

Mouais ! Pas toujours très convaincantes ces solutions, mais surtout pas facile à mettre en place et souvent contre performante …  Bref !

Lire la suite

SQL 2016 Le live Query Statistique

Dans les versions passés il n’existait pas de fonctionnalités pour connaitre l’état des requêtes en temps réel.

Lorsque qu’on lançait une requête il était impossible de connaitre l’état d’avancement de celle-ci.

Lire la suite

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’.