2 votes

Obtenir l'espace de travail TFS 2017 vNext Build avec powershell

J'ai un projet où il est nécessaire de modifier certains fichiers pendant le processus de génération. Je dois utiliser Powershell pour cela. J'ai déjà configuré toutes les étapes nécessaires pour le faire. Toutes les étapes fonctionnent sur mon PC client. Le serveur de build a la même configuration. Vs 2015 (pour TF Powertools 2015) et VS 2017 installés. Lorsque j'ai mis en file d'attente une génération, la génération échoue au moment où il essaie d'obtenir l'Espace de Travail. Peut-être que cela est dû au fait que l'agent de build crée uniquement des espaces de travail locaux ? À ce stade, les modifications requises sont déjà vérifiées. Je ne peux pas utiliser TF.exe checkin, car il existe des politiques de vérification qui empêchent la vérification sans élément de travail associé. C'est ce que j'essaie de faire à cette étape :

  • Obtenir l'Espace de Travail via le chemin des sources ($Env:BUILD_SOURCESDIRECTORY)
  • Obtenir les changements en attente de cet espace de travail $pendingChanges = $tfsws.GetPendingChanges()
  • Créer workitemcheckininfo avec un travail associé
  • Vérifier avec workitemcheckininfo créé $changesetNumber = $tfsws.CheckIn($pendingChanges,"$CommentString vérifié par BuildServer",$null, $workItemChanges,$null)

Comme je n'obtiens pas l'Espace de Travail (étape 1), les étapes suivantes ne vont pas commencer.

Voici ce que j'ai essayé jusqu'à présent :

1

$binpath   = "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer"
#$binpath   = "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\ReferenceAssemblies\v2.0"
Add-Type -path "$binpath\Microsoft.TeamFoundation.Client.dll"
Add-Type -Path "$binpath\Microsoft.TeamFoundation.WorkItemTracking.Client.dll"
Add-Type -Path "$binpath\Microsoft.TeamFoundation.VersionControl.Client.dll"
Add-Type -Path "$binpath\Microsoft.TeamFoundation.Common.dll"

$teamProjectCollection = "http://mytfs/tfs/defaultcollection"
$tfs = [Microsoft.TeamFoundation.Client.TfsTeamProjectCollectionFactory]::GetTeamProjectCollection($teamProjectCollection)

#La ligne suivante échoue, car la commande provient de TF Powertools 2015 et le serveur TFS est en 2017.
#Je reçois le message d'erreur "Microsoft.TeamFoundation.Client.TfsTeamProjectCollection ne peut pas être converti en Microsoft.TeamFoundation.Client.TfsTeamProjectCollection"
$tfsws = Get-TfsWorkspace -Server $tfs -Computer $hostname -Owner $Username

2

$binpath   = "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer"
#$binpath   = "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\ReferenceAssemblies\v2.0"
Add-Type -path "$binpath\Microsoft.TeamFoundation.Client.dll"
Add-Type -Path "$binpath\Microsoft.TeamFoundation.WorkItemTracking.Client.dll"
Add-Type -Path "$binpath\Microsoft.TeamFoundation.VersionControl.Client.dll"
Add-Type -Path "$binpath\Microsoft.TeamFoundation.Common.dll"

$localReference = join-path $Env:BUILD_SOURCESDIRECTORY $TargetBranch
$teamProjectCollection = "http://mytfs/tfs/defaultcollection"
$tfsTeamProjectCollection = New-Object Microsoft.TeamFoundation.Client.TfsTeamProjectCollection($teamProjectCollection)
$versioncontrolServer = $tfsTeamProjectCollection.GetService([Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer])

#Les lignes suivantes échouent, car $versioncontrolServer est nul
[Microsoft.TeamFoundation.VersionControl.Client.Workstation]::Current.EnsureUpdateWorkspaceInfoCache($versionControlServer, $username);
$tfsws = $versioncontrolServer.GetWorkspace($localReference)

Deux choses qui pourraient causer des problèmes : 1ère => l'agent de build n'utilise que des espaces de travail locaux ? 2e => TFS 2017 et VS 2015 ne sont pas suffisamment compatibles ?

Quelqu'un a-t-il un bon exemple ou une solution fonctionnelle ?

J'ai envisagé d'autres options. Peut-être pourrais-je programmer un exécutable qui fait mon travail.

Puis-je faire une vérification sans espace de travail et associer ultérieurement l'élément de travail ? Comment associer de manière programmative un élément de travail à un Changeset existant ?

0voto

Andy Li-MSFT Points 18202

Vous ne pouvez pas vous enregistrer sans workspace.

Cependant, le processus créera un espace de travail local lors de l'étape de récupération des sources. Ainsi, vous pouvez directement vérifier les modifications en contournant les stratégies de vérification, puis associer ultérieurement un élément de travail au Changeset spécifique.

Pour contourner/remplacer les stratégies de vérification, vous pouvez exécuter la commande de vérification ci-dessous (Vous pouvez copier la commande ci-dessous et l'enregistrer en tant que script PowerShell/cmd, puis ajouter une tâche PowerShell/Command pour exécuter le script). Voir Commande de vérification:

tf Checkin $source_dir /comment:"Changer les fichiers" /noprompt /force /bypass /override:"Sans associer d'élément de travail"

Remarque: Assurez-vous que l'agent que vous utilisez est la version 2.122.1 ou ultérieure, sinon vous pourriez rencontrer des erreurs, voir ce fil de discussion connexe pour plus de détails.

Pour associer un élément de travail à un Changeset existant:

C# avec une API client:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;

namespace APPI
{
    class Program
    {
        static void Main(string[] args)
        {
            string url = "http://xxx.xxx.xxx.xxx:8080/tfs/DefaultCollection";
            TfsTeamProjectCollection ttpc = new TfsTeamProjectCollection(new Uri(url));
            WorkItemStore wis = ttpc.GetService();
            VersionControlServer vcs = ttpc.GetService();
            int wid = 194;
            int cid = 440;
            WorkItem wi = wis.GetWorkItem(wid);
            Changeset cs = vcs.GetChangeset(cid);
            ExternalLink el = new ExternalLink(wis.RegisteredLinkTypes["Fixed in Changeset"], cs.ArtifactUri.AbsoluteUri);
            wi.Links.Add(el);
            wi.Save();     
        }
    }
}

PowerShell avec une API REST:

Param(
   [string]$collectionurl = "http://server:8080/tfs/DefaultCollection",
   [string]$keepForever = "true",
   [string]$WorkitemID = "194",
   [string]$ChangesetID = "439",
   [string]$user = "NomUtilisateur",
   [string]$token = "motdepassedétoken"
)

# Encode en Base64 le jeton d'accès personnel (PAT) de manière appropriée
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))

function CreateJsonBody
{

    $value = @"
[
 {
    "op": "add",
    "path": "/relations/-",
    "value": {
      "rel": "ArtifactLink",
      "url": "vstfs:///VersionControl/Changeset/$ChangesetID",
      "attributes": {
        "name": "Fixed in Changeset"
      }
    }
  }
]

"@

 return $value
}

$json = CreateJsonBody

$uri = "$($collectionurl)/_apis/wit/workitems/$($WorkitemID)?api-version=1.0"
$result = Invoke-RestMethod -Uri $uri -Method Patch -Body $json -ContentType "application/json-patch+json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}

0voto

jessehouwing Points 16951

Vous voudrez peut-être consulter (sans jeu de mots) mes tâches de construction TFVC pour VSTS/TFS. Il offre tout ce dont vous avez besoin. La seule chose qui manque est l'association avec les éléments de travail, sauf si vous utilisez les modifications validées par mise à jour.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X