2017-01-09 74 views
0

我想從TFS2015構建定義中獲取信息。我們在XAML格式中有大約100個構建定義,並且在2015年新格式中有大約50個構建定義。 服務器是內部團隊基礎服務器。 (微軟的Visual Studio Team Foundation Server的 版15.105.25910.0)TFS服務器API只列出XAML構建定義

我不使用REST API,但這裏推薦的Microsoft.TeamFoundationServer.ExtendedClient爲:https://blogs.msdn.microsoft.com/buckh/2015/08/10/nuget-packages-for-tfs-and-visual-studio-online-net-client-object-model/

這是我的代碼例如:

using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.Linq; 
using Microsoft.TeamFoundation.Build.Client; 
using Microsoft.TeamFoundation.Client; 
using Microsoft.TeamFoundation.Framework.Client; 
using Microsoft.TeamFoundation.Framework.Common; 
using Serilog; 

namespace TFSExperiment 
{ 
    class Program 
    { 
     // see https://blogs.msdn.microsoft.com/buckh/2015/08/10/nuget-packages-for-tfs-and-visual-studio-online-net-client-object-model/ 
     //Needs nuget package Install-Package Microsoft.TeamFoundationServer.ExtendedClient -Version 14.102.0 
     // to use serilogg: Install-Package Serilog ; Install-Package Serilog.Sinks.RollingFile 
     static void Main(string[] args) 
     { 
      var myLog = new LoggerConfiguration() 
       .WriteTo.RollingFile("..\\..\\Applog\\mylog-{Date}.log").CreateLogger();   
      TfsConfigurationServer configurationServer = 
       TfsConfigurationServerFactory.GetConfigurationServer(new Uri("https://tfs.inhouseserver2015.org/tfs/")); 
      ReadOnlyCollection<CatalogNode> collectionNodes = 
       configurationServer.CatalogNode.QueryChildren(new[] {CatalogResourceTypes.ProjectCollection}, false, 
        CatalogQueryOptions.None); 
      CatalogNode defultTfsCol = collectionNodes.AsQueryable().Single(c=>c.Resource.DisplayName.Equals("DefaultCollection")); 
      Console.WriteLine(defultTfsCol.Resource.DisplayName); 
       TfsTeamProjectCollection tfsProjectCollection = 
       configurationServer.GetTeamProjectCollection(new Guid(defultTfsCol.Resource.Properties["InstanceId"])); 
       tfsProjectCollection.Authenticate(); 
       var buildServer = (IBuildServer)tfsProjectCollection.GetService(typeof(IBuildServer));     
       ReadOnlyCollection<CatalogNode> projectNodes = defultTfsCol.QueryChildren(
        new[] { CatalogResourceTypes.TeamProject }, 
        false, CatalogQueryOptions.None); 
       foreach (var proj in projectNodes) 
       { 
        var buildDefinitionList = new List<IBuildDefinition>(buildServer.QueryBuildDefinitions(proj.Resource.DisplayName)); 
        foreach (var buildDef in buildDefinitionList) 
        {      
         Console.WriteLine(buildDef.Name);     
         myLog.Information($"{buildDef.Id} --{buildDef.Name} --{buildDef.BuildServer.BuildServerVersion} "); 
        } 
       }    
      Console.WriteLine(" Hit any key to exit "); 
      Console.ReadKey(); 
     } 
    } 
} 

回答

0

在Microsoft.TeamFoundationServer.ExtendedClient這些API主要有供給與XAML向後兼容性的基礎之上。據我所知,他們不支持Build vNext,因爲它們是在他們的時間之前編寫的。

由於您提供的鏈接建議,REST API是未來的方式。

+0

好吧,也許我讀了快我讀到Microsoft.TeamFoundationServer.ExtendedClient:」 ..Because不是每個API是在2015年TFS或VSO目前可用的REST API,也將是情況下,你必須使用這個軟件包...「所以我認爲一切都在這個。 (因此名稱擴展名爲「 –

+0

我嘗試了Rest API,但沒有得到Windows身份驗證的工作我只有System.Net.Http.HttpRequestException:響應狀態代碼不表示成功:401(未授權) –

+0

您是否嘗試過設置UseDefaultCredentials = true;在你的WebClient對象上? –

1

您正在使用只能獲取XAML構建的遺留SOAP API。

假設你已經安裝了最新的.NET Client Libraries,您可以使用REST API在庫中獲得兩個XAML和vNext建立這樣的:

using System; 
using System.Collections.Generic; 
using Microsoft.TeamFoundation.Client; 
using Microsoft.TeamFoundation.Build.WebApi; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Uri tfsurl = new Uri("http://xxxx:8080/tfs/CollectionName"); 
      TfsTeamProjectCollection ttpc = new TfsTeamProjectCollection(tfsurl); 
      BuildHttpClient bhc = ttpc.GetClient<BuildHttpClient>(); 
      List<Build> builds = bhc.GetBuildsAsync("ProjectName").Result; 
      foreach (Build bu in builds) 
      { 
       Console.WriteLine(bu.BuildNumber); 
      } 
      Console.ReadLine(); 
     } 
    } 
} 
+0

嗨thx。我需要關於構建的信息defs有關xaml構建的變量,我不得不使用booth api:s。 –

1

如回答了埃迪 - MSFT,撕毀奧斯特加德我不得不使用其餘的API。但它看起來像我也必須使用舊的API來從構建定義中獲取所有信息。從restapi我得到了構建的名稱,但沒有深入信息的XAML構建。

我想從指出Octopus Deploy項目名稱的變量中收集信息。我在這裏發佈代碼以防有人遇到類似問題。

using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.Diagnostics; 
using System.Linq; 
using System.Net; 
using System.Text.RegularExpressions; 
using Microsoft.TeamFoundation.Build.Client; 
using Microsoft.TeamFoundation.Client; 
using Microsoft.TeamFoundation.Build.WebApi; 
using Microsoft.TeamFoundation.Common; 
using Microsoft.TeamFoundation.Framework.Client; 
using Microsoft.TeamFoundation.Framework.Common; 
using Newtonsoft.Json; 
using Serilog; 
using Serilog.Core; 


namespace ListOctopusProjectsAndTfsBuilds 
{ 
    class Program 
    { 
     // see https://blogs.msdn.microsoft.com/buckh/2015/08/10/nuget-packages-for-tfs-and-visual-studio-online-net-client-object-model/ 
     //Needs nuget package Install-Package Microsoft.TeamFoundationServer.ExtendedClient -Version 14.102.0 
     // to use serilogg: Install-Package Serilog ; Install-Package Serilog.Sinks.RollingFile 

     static Logger _myLog = new LoggerConfiguration() 
       .WriteTo.RollingFile($"..\\..\\Applog\\myBuildDeflog-{DateTime.Now:yyyyMMddHHHHmmss}.log").CreateLogger(); 
     static void Main(string[] args) 
     { 
      Console.WriteLine("Start looking for BuildDefs"); 
      Dictionary<string, string> octopusDeployDictionary = GetvNextBuildDefVariable(new Uri("https://inhouseserver2015/tfs/DefaultCollection"), "YourTfsProject", "OctoProj"); 
      Dictionary<string, string> octopusDeployXamlDictionary = GetXamlBuildDefVariable(new Uri("https://inhouseserver2015/tfs/DefaultCollection"), "YourTfsProject", "ArgOctopusProjectsToPublish"); 
      Console.WriteLine("Builds vnext defs -- Octopus project"); 
      foreach (var cd in octopusDeployDictionary) 
      { 
       Console.WriteLine($"{cd.Key}; {cd.Value}"); 
      } 
      Console.WriteLine("Builds xaml defs -- Octopus project"); 
      foreach (var cd in octopusDeployXamlDictionary) 
      { 
       Console.WriteLine($"{cd.Key}; {cd.Value}"); 
      } 
      Console.ReadLine(); 
     } 

     private static Dictionary<string, string> GetXamlBuildDefVariable(Uri tfsUri, string tfsProject, string buildDefVar) 
     { 
      var collection = tfsUri.LocalPath.Split('/')[2]; 
      //Define Reg expression ahead so it can faster parse xml and find the Octopus Deploy projectname. 
      Regex findArgOctopusProjectsToPublish = null; 
      try 
      { 
       findArgOctopusProjectsToPublish = new Regex($"x:Key=\"{buildDefVar}\".*<x:String>([^<]*)", 
        RegexOptions.IgnoreCase | RegexOptions.Singleline); 
      } 
      catch (ArgumentException ex) 
      { 
       _myLog.Error(ex, "Error with RegularExpression syntax"); 
      } 
      Dictionary<string, string> tfsVarBuildDefDict = new Dictionary<string, string>(); 
      TfsConfigurationServer configurationServer = 
       TfsConfigurationServerFactory.GetConfigurationServer(tfsUri)); 
      ReadOnlyCollection<CatalogNode> collectionNodes = 
       configurationServer.CatalogNode.QueryChildren(new[] {CatalogResourceTypes.ProjectCollection}, false, 
        CatalogQueryOptions.None); 
      CatalogNode defultTfsCol = 
       collectionNodes.AsQueryable().Single(c => c.Resource.DisplayName.Equals(collection)); 
      TfsTeamProjectCollection tfsProjectCollection = 
       configurationServer.GetTeamProjectCollection(new Guid(defultTfsCol.Resource.Properties["InstanceId"])); 
      tfsProjectCollection.Authenticate(); 
      var buildServer = (IBuildServer) tfsProjectCollection.GetService(typeof(IBuildServer)); 
      ReadOnlyCollection<CatalogNode> projectNodes = defultTfsCol.QueryChildren(
       new[] {CatalogResourceTypes.TeamProject}, 
       false, CatalogQueryOptions.None); 

       var buildDefinitionList = 
        new List<IBuildDefinition>(buildServer.QueryBuildDefinitions(tfsProject)); 
       foreach (var buildDef in buildDefinitionList) 
       { 
       Debug.Assert(findArgOctopusProjectsToPublish != null, "findArgOctopusProjectsToPublish != null"); 
       var octopusProjectsToPublish = 
         findArgOctopusProjectsToPublish?.Match(buildDef.ProcessParameters).Groups[1].Value; 
        if (octopusProjectsToPublish.IsNullOrEmpty()) 
        { 
         octopusProjectsToPublish = "NoOctopus Projekt"; 
        } 
       tfsVarBuildDefDict.Add(buildDef.Name, octopusProjectsToPublish); 
        _myLog.Information($"{buildDef.Id} --{buildDef.Name} --{buildDef.BuildServer.BuildServerVersion} "); 
       } 

      return tfsVarBuildDefDict; 
     } 

     private static Dictionary<string, string> GetvNextBuildDefVariable(Uri tfsUri,string tfsProject,string buildDefVar) 
     { 
      Dictionary<string, string> tfsVarBuildDefDict = new Dictionary<string, string>(); 
      TfsTeamProjectCollection ttpc = 
       new TfsTeamProjectCollection(tfsUri); 
      BuildHttpClient bhc = ttpc.GetClient<BuildHttpClient>(); 
      var definitions = bhc.GetDefinitionsAsync(project: tfsProject); 
      var client = new WebClient {UseDefaultCredentials = true}; 
      foreach (var buildDef in definitions.Result) 
      { 
       if (buildDef.Type == DefinitionType.Build) 
       { 
        var json = client.DownloadString(buildDef.Url); 
        BuildDefinition result = JsonConvert.DeserializeObject<BuildDefinition>(json); 
        if (result.Variables.ContainsKey(buildDefVar)) 
        { 
         tfsVarBuildDefDict.Add(buildDef.Name, result.Variables[buildDefVar].Value.ToString()); 
         _myLog.Information($"{buildDef.Name} Octoproject: {result.Variables[buildDefVar].Value.ToString()}"); 
        } 
       } 
       else 
       { 
        _myLog.Information($"{buildDef.Name} BuildType {buildDef.Type} "); 
       } 
      } 
      return tfsVarBuildDefDict; 
     } 
    } 
}