Tutoriel pour apprendre à partager vos indicateurs de qualité avec TFS et PowerShell

Armand LACORE

Ce tutoriel a pour objectif de vous apprendre à utiliser le langage PowerShell. Interrogez votre serveur de build TFS à l'aide de PowerShell et partagez par mail les indicateurs : code analysis, code coverage, résultats des tests et avertissements de compilation.

Commentez

- Titre : Tutoriel pour apprendre à partager vos indicateurs de qualité avec TFS et PowerShell

- Auteur : Armand LACORE

- Parution : 8 septembre 2017

- Licence : Copyright ® 2017 SOAT. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Voir également :

- Tutoriel pour apprendre les nouveautés de C# 6 et C# 7

- Apprendre à lancer votre application windows 10 via Cortana

Sommaire

- I. Introduction

- II. Connexion à TFS

- II-A. Charger les assemblies TFS

- II-A-1. Code

- II-B. Se connecter à votre collection de projets TFS

- II-B-1. Code

- II-C. Obtenir les services de votre collection de projets TFS

- II-C-1. Code

- II-D. Fonction : connexion à TFS, obtenir la collection de projets et les services TFS

- III. Obtenir les données de builds TFS

- III-A. Obtenir une build TFS

- III-A-1. Code

- III-A-2. Code

- III-B. Fonction : obtenir une build TFS

- III-C. Compilation, analyse de code, tests unitaires & couverture de code

- III-C-1. Obtenir les avertissements et erreurs de la build

- III-C-2. Code

- III-D. Obtenir les résultats des tests unitaires et la couverture de code

- III-D-1. Code

- III-E. Fonction : obtenir le détail d'une build

- III-F. Fonction : obtenir le détail de la dernière occurrence d'une build

- IV. Partagez les données de la build

- IV-A. Mise en forme HTML

- IV-A-1. Code

- IV-B. Fonction : convertir les objets PowerShell en tableau HTML

- IV-C. Envoi d'emails

- IV-C-1. Code

- IV-D. Script : partagez vos indicateurs de qualité

- V. Conclusion

I - Introduction

Dans une démarche de transparence, responsabilisez votre équipe, justifiez et récompensez les efforts de chacun par l'automatisation du partage quotidien d'indicateurs de qualité, factuels et visuels.

Tous les modules et scripts PowerShell détaillés dans ce tutoriel sont compilés dans le tfsKit disponible sur GITHUB.

II - Connexion à TFS

II-A - Charger les assemblies TFS

La première étape afin de travailler avec TFS et PowerShell est de charger les assemblies TFS dans votre session PowerShell.

Sur une machine avec Visual Studio 2015 installé, le chemin par défaut pour les API TFS est :

Vous pouvez les charger depuis le chemin par défaut, autrement je conseille de les exporter dans un répertoire pour générer un kit stand alone qui peut être lancé depuis n'importe quel client, même si TFS n'est pas installé, ou s'il l'est mais dans une version différente du serveur (utiliser les assemblies du serveur).

Vous devez ajouter les types suivants à votre script PowerShell pour être en mesure d'interroger TFS et votre serveur de build :

Avec les dépendances, la liste des dll impliquées est plus large. Pour exporter les dll, sélectionnez les membres suivants :

Les assemblies nécessaires pour interroger TFS 2015 ou 2013 sont disponibles sur GITHUB.

II-A-1 - Code

Les assemblies peuvent être chargées avec la cmdLet Add-Type désignée pour charger des classes .NET dans votre session PowerShell.

1. # Renseigne votre chemin assemblies

2. $assembliesPath = "F:\GitHub\Powershell\tfsKit\Assemblies"

4. # Renseigne votre liste TFS assemblies

5. $tfsAssemblies = ("Microsoft.TeamFoundation.Client.dll","Microsoft.TeamFoundation.Build.Client.dll","Microsoft.TeamFoundation.TestManagement.Client.dll","Microsoft.TeamFoundation.WorkItemTracking.Client.dll","Microsoft.VisualStudio.Services.Client.dll","Microsoft.TeamFoundation.WorkItemTracking.Client.DataStoreLoader.dll","Microsoft.TeamFoundation.Build.Common.dll")

7. # importe assemblies

8. $tfsAssemblies | % { Add-Type -Path ([IO.Path]::Combine($assembliesPath, $_)) }

Cet exemple simple ne nous permet pas d'avoir le détail de l'erreur si l'import échoue. Pour cela nous devons récupérer, depuis l'exception, la propriété LoaderExceptions.

Comme tous les noms d'assemblies commencent par « Microsoft » et finissent par « .dll », nous pouvons aussi raccourcir l'appel.

1. try

2. {

3. $assembliesShortName = @("TeamFoundation.Client","TeamFoundation.Build.Client","TeamFoundation.TestManagement.Client","TeamFoundation.WorkItemTracking.Client","VisualStudio.Services.Client","TeamFoundation.WorkItemTracking.Client.DataStoreLoader","TeamFoundation.Build.Common")

4. $assembliesShortName | % { Add-Type -Path ([IO.Path]::Combine($global:AssembliesFolder, "Microsoft.$_.dll")) }

5. }

6. catch [System.Reflection.ReflectionTypeLoadException]

7. {

8. Write-Error $($_.Exception | Select-Object LoaderExceptions | Out-String)

9. }

Dans Module-TFS.psm1, nous utilisons le wrapper Add-Assemblies du Module-IO.psm1, nous utilisons également ce module pour les fonctions de Login.

# importe TFS assemblies
Add-Assemblies @("TeamFoundation.Client","TeamFoundation.Build.Client","TeamFoundation.TestManagement.Client","TeamFoundation.WorkItemTracking.Client","VisualStudio.Services.Client","TeamFoundation.WorkItemTracking.Client.DataStoreLoader","TeamFoundation.Build.Common")

II-B - Se connecter à votre collection de projets TFS

Pour effectuer des requêtes à travers votre collection de projets TFS, vous devez instancier un objet TfsTeamProjectCollection depuis l'URI de la collection TFS et vos accès TFS. Pour cette action, nous utilisons la méthode static GetTeamProjectCollection de la classe TfsTeamProjectCollectionFactory du namespace Microsoft.TeamFoundation.Client.

Ensuite, pour s'assurer d'être authentifié à une collection de projets TFS valide, nous utilisons la méthode EnsureAuthenticated de l'objet TfsTeamProjectCollection ; cette méthode définit la propriété HasAuthenticated (Boolean) de l'objet source, et s'assure que la collection de projets est valide (aucune erreur n'est retournée lors de l'instanciation de l'objet. Si votre URI ou vos accès sont faux, vous aurez une erreur lors de l'exécution de la méthode EnsureAuthenticated).

La méthode GetTeamProjectCollection possède plusieurs surcharges, notez que Microsoft marque avec l'attribut obsolète les surcharges utilisant des accès TFS.

Nom

Description

GetTeamProjectCollection(Uri)

Obtient l'instance TfsTeamProjectCollection associée au serveur de l'URI spécifié.

GetTeamProjectCollection(RegisteredProjectCollection)

Obtient l'instance TfsTeamProjectCollection associée à l'instance de RegisteredProjectCollection spécifiée.

GetTeamProjectCollection(Uri, ICredentialsProvider)

Obsolète. Obtient l'instance TfsTeamProjectCollection associée au serveur de l'URI spécifié et du fournisseur d'identification de repli.

GetTeamProjectCollection(RegisteredProjectCollectio

Obsolète. Obtient l'instance TfsTeamProjectCollection associée à l'instance de RegisteredProjectCollection spécifiée et au fournisseur d'informations d'accès.

GetTeamProjectCollection(String, Boolean, Boolean)

Récupère l'objet TfsTeamProjectCollection qui est utilisé pour un serveur donné.

Puisque Microsoft marque avec l'attribut obsolète les surcharges utilisant des accès TFS, les moyens supportés pour gérer les accès sont :

- Lancer les commandes PowerShell depuis un compte active directory autorisé.

- Lancer le script depuis une machine avec TFS installé et votre serveur TFS ajouté à la collection de serveurs.

- Laisser PowerShell enregistrer un cookie TFS lorsque vous lancez la commande pour la première fois et êtes invité à entrer vos données d'identification.

II-B-1 - Code

Comme les accès sont enregistrés dans nos cookies, l'URI de la collection TFS est le seul paramètre obligatoire dont nous avons besoin pour appeler la méthode GetTeamProjectCollection.

1. $tfsCollectionUri = [System.Uri]"https://tfs.myprojectname.com/DefaultCollection"

3. $projectsCollection = [Microsoft.TeamFoundation.Client.TfsTeamProjectCollectionFactory]::GetTeamProjectCollection($tfsCollectionUri) # Cette méthode ne lance jamais d'exceptions

5. $projectsCollection.EnsureAuthenticated() # Cette méthode lève une exception sur un mauvais URI ou une mauvaise identification

7. if($projectsCollection.HasAuthenticated)

8. {

9. # Liste des actions

10. }

11. else

12. {

13. Write-Warning "you are not authenticated to $tfsCollectionUri" # Ce cas ne devrait jamais arriver vu qu'EnsureAuthenticated() lance une exception sur un mauvais URI ou une mauvaise identification

15. }

II-C - Obtenir les services de votre collection de projets TFS

Plusieurs services sont utiles depuis une collection de projets TFS :

- builds servers : collection de serveurs qui font tourner les builds TFS ; ils sont nécessaires pour interroger les builds TFS.

- work item store : connection work item tracking client sur les serveurs Team Foundation ; ce service est nécessaire pour interroger les projets TFS.

- test management service : objet principal de l'API test management client, ce service est nécessaire pour obtenir les résultats des tests unitaires, ainsi que la couverture de code (dépendant d'un projet TFS).

Pour obtenir ces services, nous utilisons la méthode GetService de l'objet TfsTeamProjectCollection. Cette méthode retourne une instance du service requêté s'il peut être trouvé, ou une ‘reference null' dans le cas contraire.

- Pour obtenir la collection builds servers, nous requêtons une interface IBuildServer du namespace Microsoft.TeamFoundation.Build.Client.

- Pour obtenir le service work item store, nous requêtons une classe WorkItemStore depuis le namespace Microsoft.TeamFoundation.WorkItemTracking.Client.

- Pour obtenir le Test management service, nous requêtons une interface ITestManagementService, depuis Microsoft.TeamFoundation.TestManagement.Client.

II-C-1 - Code

1. $buildServer = $projectsCollection.GetService([Microsoft.TeamFoundation.Build.Client.IBuildServer])

3. $workItemStore = $projectsCollection.GetService([Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemStore])

5. $testManagementService = $projectsCollection.GetService([Microsoft.TeamFoundation.TestManagement.Client.ITestManagementService])

II-D - Fonction : connexion à TFS, obtenir la collection de projets et les services TFS

Retrouvez la Function Get-TfsConnection dans le module Module-TFS.psm1 sur GITHUB.

III - Obtenir les données de builds TFS

Comme nous l'avons vu dans les sections précédentes, il est utile d'obtenir le service build server de la collection de projets, car ce service nous permet d'interroger les builds.

Les exemples suivants partent du prédicat que vous avez instancié un build server dans le champ $buildServer.

III-A - Obtenir une build TFS

L'interface IBuildServer du namespace Microsoft.TeamFoundation.Build.Client possède la méthode QueryBuilds, voici ses surcharges :

Nom

Description

QueryBuilds(String)

Obtient toutes les versions pour un projet d'équipe.

QueryBuilds(IBuildDefinition)

Obtient toutes les versions pour une définition de build.

QueryBuilds(IBuildDefinitionSpec)

Obtient toutes les versions pour une spécification de définition d'une build.

QueryBuilds(IBuildDetailSpec)

Obtient un seul résultat de requête de version pour les spécifications d'une build particulière.

QueryBuilds(IBuildDetailSpec[])

Obtient les résultats de la requête de build pour la liste des spécifications de la build.

QueryBuilds(String, String)

Obtient toutes les versions pour un projet d'équipe et une définition.

La surcharge la plus simple pour obtenir les informations utilise le nom du projet et le nom de la build comme paramètres. Elle retourne les informations complètes (QueryOptions = "All", InformationTypes = "*") de toutes les occurrences de la build, mais c'est un processus lourd (jusqu'à à 1 Go de mémoire utilisé) et très long, environ 16 minutes (les exemples ont été chronométrés depuis une build d'intégration continue âgée de six mois).

III-A-1 - Code

Temps d'exécution : 983757 ms

$tfsBuilds = $buildServer.QueryBuilds("yourProjectName", "yourBuildName")

La surcharge la plus versatile utilise un objet IBuildDetailSpec comme paramètre. Elle nous offre un contrôle complet sur l'interrogation à l'aide des propriétés suivantes :

Name

Description

BuildNumber

Obtient ou définit le nombre de builds souhaité. Les caractères génériques sont pris en charge.

DefinitionSpec

Obtient la spécification de définition de version pour les builds souhaitées.

DefinitionUris

Obtient l'URI de version pour les builds souhaitées.

InformationTypes

Obtient ou définit les types d'informations qui seront renvoyés à partir d'une ou de plusieurs requête(s).

MaxBuildsPerDefinition

Obtient ou définit le nombre maximal de builds à renvoyer par définition.

MaxFinishTime

Obtient ou définit la fin de l'intervalle de temps des builds spécifiées.

MinChangedTime

Obtient ou définit la date et l'heure de révision les plus anciennes des builds souhaitées.

MinFinishTime

Obtient ou définit la valeur de début de l'intervalle de temps de fin des builds spécifiées.

Quality

Obtient ou définit la qualité des builds souhaitées.

QueryDeletedOption

Obtient ou définit des options pour interroger les builds supprimées.

QueryOptions

Obtient ou définit les données supplémentaires que retourneront les requêtes.

QueryOrder

Obtient ou définit le schéma de commande à utiliser lorsque l'utilisateur définit un nombre maximum de builds.

Reason

Obtient ou définit le motif des builds souhaitées.

RequestedFor

Obtient ou définit l'utilisateur pour lequel la build a été demandée.

Status

Obtient ou définit les statuts des builds souhaitées.

Si vous voulez interroger toutes les occurrences d'une build, vous pouvez choisir de retourner le niveau minimum d'informations (QueryOptions = "None", InformationTypes = $null) ; le processus est bien plus rapide, environ 0,3 seconde.

III-A-2 - Code

Temps d 'exécution : 319 ms

1. $buildSpecification = $buildServer.CreateBuildDetailSpec("yourProjectName", "yourBuildName")

3. $buildSpecification.QueryOptions = "None"

4. $buildSpecification.InformationTypes = $null

6. $tfsBuilds = $buildServer.QueryBuilds($buildSpecification)

Si vous interrogez un numéro de build, vous interrogez une seule occurrence. Le processus reste rapide même si vous demandez toutes les informations disponibles pour la build, environ 1,7 seconde.

Temps d'exécution : 1726 ms

1. $buildSpecification = $buildServer.CreateBuildDetailSpec("yourProjectName", "yourBuildName")

3. $buildSpecification.BuildNumber = "yourBuildNumber"

5. $tfsBuild = $buildServer.QueryBuilds($buildSpecification)

Notre but est souvent d'interroger la dernière occurrence d'une build pour un nom de build donné. Comme nous ne pouvons pas deviner le BuildNumber de cette occurrence, combiner les deux exemples précédents nous permet d'obtenir toutes les informations de la dernière occurrence d'une build en un minimum de temps (les informations apportées par la propriété QueryOptions ne sont pas nécessaires) ; le processus a été chronométré à environ 2,1 secondes.

Temps d'exécution : 2131 ms

1. $buildSpecification = $buildServer.CreateBuildDetailSpec("yourProjectName", "yourBuildName")

3. $buildSpecification.QueryOptions = "None"

4. $buildSpecification.InformationTypes = $null

6. $tfsBuilds = $buildServer.QueryBuilds($buildSpecification)

8. # by default, QueryOrder property on build specification is StartTimeAscending

9. $tfsLastBuildNumber = ($tfsBuilds.Builds | ? { $_.Status -ne "InProgress" } | Select-Object -Last 1).BuildNumber

11. $buildSpecification.InformationTypes = "*"

12. $buildSpecification.BuildNumber = $tfsLastBuildNumber

14. $tfsBuild = $buildServer.QueryBuilds($buildSpecification)

III-B - Fonction : obtenir une build TFS

Retrouvez la Function Get-TfsBuilds dans le module Module-TFS.psm1 sur GITHUB.

III-C - Compilation, analyse de code, tests unitaires & couverture de code

Les exemples suivants partent du prédicat que vous avez instancié une build TFS.

III-C-1 - Obtenir les avertissements et erreurs de la build

Les résultats de la compilation et du code analysis sont imbriqués dans les erreurs et les avertissements de la build.

Pour obtenir les erreurs de la build, nous utilisons la méthode GetBuildErrors de la classe InformationNodeConverters depuis le namespace Microsoft.TeamFoundation.Build.Client.

Pour obtenir les avertissements de la build, nous utilisons la méthode GetBuildEWarnings de la classe InformationNodeConverters depuis le namespace Microsoft.TeamFoundation.Build.Client.

Ces deux méthodes acceptent une interface IBuildDetails comme paramètre (la fonction Get-TfsBuilds retourne les builds comme objet BuildDetails) et retournent une liste de BuildWarning ou BuildError.

Ensuite pour séparer les résultats de compilation et le code analysis, nous pouvons trier les résultats grâce aux propriétés ErrorType et WarningType.

III-C-2 - Code

1. $buildErrors = [Microsoft.TeamFoundation.Build.Client.InformationNodeConverters]::GetBuildErrors($tfsBuild)

2. $buildWarnings = [Microsoft.TeamFoundation.Build.Client.InformationNodeConverters]::GetBuildWarnings($tfsBuild)

4. $compilationErrors = $buildErrors | ? { $_.ErrorType -eq "Compilation" }

5. $compilationWarnings = $buildWarnings | ? { $_.WarningType -eq "Compilation" }

6. $codeAnalysisErrors = $buildErrors | ? { $_.ErrorType -eq "StaticAnalysis" }

7. $codeAnalysisWarnings = $buildWarnings | ? { $_.WarningType -eq "StaticAnalysis" }

III-D - Obtenir les résultats des tests unitaires et la couverture de code

Le service TestManagementService est nécessaire pour obtenir les tests unitaires et la couverture de code, nous avons vu précédemment comment l'obtenir.

Depuis ce service, nous pouvons obtenir une interface ITestManagementTeamProject à l'aide de la méthode GetTeamProject qui utilise le nom du projet comme paramètre.

L'interface ITestManagementTeamProject possède les helpers undefined & CoverageAnalysisManager.

Pour obtenir les résultats des tests unitaires, nous utilisons la méthode TestRuns.ByBuild. Pour obtenir la couverture de code nous utilisons la méthode CoverageAnalysisManager.QueryBuildCoverage. Ces deux méthodes prennent l'URI d'une build comme paramètre (Uri est un membre de l'objet BuildDetails). La méthode QueryBuilCoverage utilise aussi l'énumération CoverageQueryFlags comme indicateur pour définir la quantité de données à retourner.

III-D-1 - Code

1. $managementService =  $tfsBuilds.Tfs.TestManagementService.GetTeamProject("yourProjectName")

3. $unitTests = $managementService.TestRuns.ByBuild($tfsBuild.Uri)

5. $codeCoverage = $managementService.CoverageAnalysisManager.QueryBuildCoverage($tfsBuild.Uri,[Microsoft.TeamFoundation.TestManagement.Client.CoverageQueryFlags]::BlockData -bor [Microsoft.TeamFoundation.TestManagement.Client.CoverageQueryFlags]::Functions -bor [Microsoft.TeamFoundation.TestManagement.Client.CoverageQueryFlags]::Modules)

III-E - Fonction : obtenir le détail d'une build

Retrouvez la Function Get-TfsBuildDetails dans le module Module-TFS.psm1 sur GITHUB.

III-F - Fonction : obtenir le détail de la dernière occurrence d'une build

Retrouvez la Function Get-TfsLastBuildDetails dans le module Module-TFS.psm1 sur GITHUB.

IV - Partagez les données de la build

IV-A - Mise en forme HTML

Tous les objets renvoyés par les fonctions ci-dessus sont formatés sous forme de tableau à une dimension, néanmoins le type des occurrences du tableau varie : Collections.Hashtable, Collections.Specialized.OrderedDictionary ou PSCustomObject.

Pour les convertir en tableau HTML, il nous faut d'abord obtenir les en-têtes :

- pour les types Collections.Hashtable ou Collections.Specialized.OrderedDictionary, les en-têtes sont obtenus via la propriété : Keys ;

- pour les types PSCustomObject, les en-têtes sont obtenus via la cmdLet : Get-Member.

Nom

Description

PSCustomObject

Fournit un objet réservé qui est utilisé lorsque le constructeur PSObject(), qui n'a pas de paramètres, est utilisé.

Collections.Hashtable

Représente une collection de clés/valeurs qui sont organisées en fonction du code de hachage de la clé.

Collections.Specialized.OrderedDictionary

Représente une collection de clés/valeurs accessibles par la clé ou l'index.

Keys

Obtient un objet ICollection contenant les clés dans la collection OrderedDictionary.

Get-Member

Obtient les propriétés et les méthodes des objets.

IV-A-1 - Code

1. if ($testLine -is [Collections.Hashtable] -or $testLine -is [Collections.Specialized.OrderedDictionary])

2. {

3. $propertiesName = $testLine.Keys

4. }

5. elseif ($testLine -is [PSCustomObject])

6. {

7. $propertiesName = $testLine | Get-Member -MemberType NoteProperty

8. }

9. else

10. {

11. Throw "this method only allow PsCustomObject or Hashtable content"

12. }

Maintenant que nous avons les en-têtes, nous pouvons construire les tableaux HTML avec en TH le nom des propriétés et en TD leurs valeurs.

1. # Écrire le début du tableau

2. $htmlTable += "<table>$([Environment]::NewLine)"

4. # Écrire l'en-tête du tableau

5. $htmlTable += "`t<tr$($TrClass)>"

7. foreach ($propertyName in $propertiesName)

8. {

9. $htmlTable += "<th$($ThClass)>$propertyName</th>"

10. }

12. $htmlTable += "</tr>$([Environment]::NewLine)"

14. # Écrire les lignes du tableau

15. foreach ($entity in $Object)

16. {

17. $htmlTable += "`t<tr>"

19. foreach ($propertyName in $propertiesName)

20. {

21. $propertyValue = [Web.HttpUtility]::HtmlEncode($entity.$propertyName)

23. $htmlTable += "<td>$propertyValue</td>"

24. }

26. $htmlTable += "</tr>$([Environment]::NewLine)"

27. }

29. # Écrire la fin du tableau

30. $htmlTable += "</table>"

IV-B - Fonction : convertir les objets PowerShell en tableau HTML

Retrouvez la Function Write-ObjectToHtml dans le module Module-IO.psm1 sur GITHUB.

IV-C - Envoi d'emails

La première chose à faire pour envoyer un e-mail, c'est de connaître les paramètres de son compte email. Pour Gmail, par exemple, je les ai obtenus sur une page de support Google :

- Server : smtp.googlemail.com ;

- Port : 587 ;

- UseSsl : true.

Le 2e point d'attention, c'est la sauvegarde des accès. Pour cela PowerShell propose le format crypté CLIXML et les fonctions Get-Credential, Export-Clixml et Import-Clixml.

1. $emailCredentialsFilePath = "C:\Example\mail@$($env:username)@$($env:computername).clixml"

3. # enregistrer les accès :

5. Get-Credential -Message "Please enter your Email credentials" | Export-Clixml $emailCredentialsFilePath

7. # appeler les accès :

9. $emailCredentials = Import-Clixml $emailCredentialsFilePath

Tout est prêt pour commencer à envoyer des e-mails ; la fonction Send-MailMessage est la plus pratique, mais elle montre ses limites lors de lancements frénétiques répétés pour les tests. Pour contourner ce problème, on peut construire une méthode qui instancie et dispose proprement les objets System.Net.Mail.SmtpClient et System.Net.Mail.MailMessage.

Nom

Description

Send-MailMessage

Envoie un message électronique

System.Net.Mail.SmtpClient

Permet aux applications d'envoyer des e-mails en utilisant le protocole SMTP (Simple Mail Transfer Protocol).

System.Net.Mail.MailMessage

Représente un message électronique qui peut être envoyé à l'aide de la classe SmtpClient.

Get-Credential

Obtient un objet d'identification basé sur un nom d'utilisateur et un mot de passe

Export-Clixml

Crée une représentation basée sur XML d'un objet ou de plusieurs objets et le(s) stocke dans un fichier.

Import-Clixml

Importe un fichier CLIXML et crée des objets correspondants dans Windows PowerShell.

IV-C-1 - Code

1. # get email title and recipients

2. $subject = "Build report CI-SOAT_20170227.1"

3. $recipients = @{scrumMaster@soat.fr, ProductOwner@soat.fr, Architect@soat.fr, ProjectDirector@soat.fr}

4. $attachments= @{"C:\Example\Compilation.html", "C:\Example\UnitTests.html", "C:\Example\CodeCoverage.html"}

6. Write-Verbose "Sending email $subject to $recipients"

8. # i use System.Net.Mail.SmtpClient Object instead of Send-MailMessage function to get more controls and dispose functionnality

9. try

10. {

11. # Créer des objets de messagerie et de serveur

12. $message = New-Object -TypeName System.Net.Mail.MailMessage

13. $smtp = New-Object -TypeName System.Net.Mail.SmtpClient($buildInfoData.BuildReports.Mail.Server)

15. # Créer un message

16. $recipients | % { $message.To.Add($_) }

17. $message.Subject = $subject

18. $message.From = New-Object System.Net.Mail.MailAddress($emailCredentials.UserName)

19. $message.Body = $mailHtml

20. $message.IsBodyHtml = $true

21. $attachments | % { $message.Attachments.Add($(New-Object System.Net.Mail.Attachment $_)) }

23. # Créer un serveur SMTP

24. $smtp = New-Object -TypeName System.Net.Mail.SmtpClient([string]$buildInfoData.BuildReports.Mail.Server)

25. $smtp.Port = [int]$buildInfoData.BuildReports.Mail.Port

26. $smtp.Credentials = [System.Net.ICredentialsByHost]$emailCredentials

27. $smtp.EnableSsl = [bool]$buildInfoData.BuildReports.Mail.UseSsl

29. # Envoyer le message

30. $smtp.Send($message)

32. Write-Host "Email message sent"

33. }

34. catch

35. {

36. Write-Warning "$($_.Exception | Select Message, Source, ErrorCode, InnerException, StackTrace | Format-List | Out-String)"

37. }

38. finally

39. {

40. Write-Verbose "Disposing Smtp Object"

41. $message.Dispose()

42. $smtp.Dispose()

43. }

IV-D - Script : partagez vos indicateurs de qualité

Le fichier de données au format XML BuildInfo.xml contient les paramètres et le Template HTML.

Le script PowerShell Send-BuildInfos.ps1 effectue tout ce que nous avons vu dans cet article. Les entrées sont stockées dans BuildInfo.xml, TFS est interrogé via le Module-TFS.psm1, les fonctions de Login et de conversion HTML sont fournies par Module-IO.psm1, toutes les ressources sont disponibles sur GITHUB.

V - Conclusion

Vous avez maintenant tous les éléments en main pour télécharger ou produire un script PowerShell, qui lancé à partir d'un poste client ayant accès à votre serveur TFS, partagera vos indicateurs de qualité vers la liste d'e-mails de votre choix.

Vous pouvez définir une tâche planifiée pour partager le résultat de la dernière occurrence d'une build tous les jours, ou l'ajouter en action post build d'une build d'intégration.

Vous pouvez également charger le module-Tfs.psm1 dans une session PowerShell pour interroger votre serveur en temps réel en ajoutant des conditions sur les statuts de la build ou les dates.