簡體   English   中英

從/到JSon文件導出/導入構建定義(TFS 2013)

[英]export/import build definition from/to JSon file (TFS 2013)

我正在嘗試從tfs2013導出和導入構建定義,遵循此鏈接 ,但它們都不適用於我。 我知道有一些tfs的插件可以做到這一點,但由於公司政策的限制,我不能使用任何插件。

GetDefinitionAsync和GetFullDefinitionsAsync方法很好,但它們不檢索ProcessParameters屬性,因此我無法導出包含此重要信息的完整構建定義。 我試圖讓這個屬性調用IBuildServer.QueryBuildDefinitions,但是當我嘗試創建新的構建定義時我不能因為數據類型是Microsoft.TeamFoundation.Build.Client.IBuildDefinition而且我無法創建Microsoft的新實例.TeamFoundation.Build.Client.BuildDefinition,因為它是一個密封的類。 如何復制ProcessParameters和其他信息以導入完整的構建定義?

謝謝

好吧,經過深入研究后,我找到了出口/進口的方法

導出到JSon:

    public static void ExportBuildDef(Microsoft.TeamFoundation.Build.Client.IBuildDefinition buildDefinition, string project, string filePath)
    {
        Console.WriteLine($"Exporting build definition '{buildDefinition.Name}' from '{project}' project.");

        var json = JsonConvert.SerializeObject(
            buildDefinition, 
            Newtonsoft.Json.Formatting.Indented, 
            new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });

        json = removePasswords(json);

        File.WriteAllText(filePath, json);
        Console.WriteLine($"Build definition '{buildDefinition.Name}' succesfully exported to '{filePath}'.");
    }

    private static string removePasswords(string json)
    {
        string res = json;

        var searchFor = "\"Password\":";
        var startIndex = json.IndexOf(searchFor);
        if (startIndex >= 0)
        {
            var endIndex = json.IndexOf(",", startIndex);
            var pwd = json.Substring(startIndex, endIndex - startIndex);
            if (pwd.IndexOf(":") > 0)
            {
                pwd = json.Substring(startIndex, endIndex - startIndex).Split(':')[1].Trim();
                res = json.Replace(pwd, "\"{hidden}\"");
            }

        }

        return res;
    }

從JSon導入

注意: BuildDefinitionModel類是一組“POCO”類(不包括長文件),可以從這里從導出的JSon文件轉換為C#類

public static void ImportBuildDefinition(IBuildServer buildServer, string projectName, string filePath, string newBuildName, string sourceProvider)
    {
        if (!File.Exists(filePath))
            throw new FileNotFoundException("File does not exist!", filePath);

        Console.WriteLine($"Importing build definition from file '{filePath}' to '{projectName}' project.");
        var json = File.ReadAllText(filePath);
        var buildDef = JsonConvert.DeserializeObject<BuildDefinitionModel>(json);

        var newBuildDefinition = CloneBuildDefinition(buildServer, buildDef, newBuildName, projectName, sourceProvider);

        Console.WriteLine($"Build definition '{buildDef.Name}' succesfully imported to '{projectName}' project.");
    }

    static IBuildDefinition CloneBuildDefinition(IBuildServer buildServer, BuildDefinitionModel buildDefinitionSource, string newBuildName, string projectName, string sourceProvider)
    {
        var buildDefinitionClone = buildServer.CreateBuildDefinition(projectName);

        buildDefinitionClone.BuildController = GetBuildController(buildServer, "");
        buildDefinitionClone.Process = buildServer.QueryProcessTemplates(buildDefinitionSource.TeamProject).FirstOrDefault(c=> c.Id == buildDefinitionSource.Process.Id);
        buildDefinitionClone.ProcessParameters = buildDefinitionSource.ProcessParameters;
        buildDefinitionClone.TriggerType = buildDefinitionSource.TriggerType;
        buildDefinitionClone.ContinuousIntegrationQuietPeriod = buildDefinitionSource.ContinuousIntegrationQuietPeriod;
        buildDefinitionClone.DefaultDropLocation = buildDefinitionSource.DefaultDropLocation;
        buildDefinitionClone.Description = buildDefinitionSource.Description;
        buildDefinitionClone.QueueStatus = Microsoft.TeamFoundation.Build.Client.DefinitionQueueStatus.Enabled;
        buildDefinitionClone.BatchSize = buildDefinitionSource.BatchSize;
        buildDefinitionClone.Name = newBuildName;

        foreach (var schedule in buildDefinitionSource.Schedules)
        {
            var newSchedule = buildDefinitionClone.AddSchedule();
            newSchedule.DaysToBuild = schedule.DaysToBuild;
            newSchedule.StartTime = schedule.StartTime;
            newSchedule.TimeZone = schedule.TimeZone;
        }

        foreach (var mapping in buildDefinitionSource.Workspace.Mappings)
        {
            buildDefinitionClone.Workspace.AddMapping(
                mapping.ServerItem, mapping.LocalItem, mapping.MappingType, mapping.Depth);
        }

        buildDefinitionClone.RetentionPolicyList.Clear();

        foreach (var policy in buildDefinitionSource.RetentionPolicyList)
        {
            buildDefinitionClone.AddRetentionPolicy(
                policy.BuildReason, policy.BuildStatus, policy.NumberToKeep, policy.DeleteOptions);
        }

        //Source Provider
        IBuildDefinitionSourceProvider provider = buildDefinitionClone.CreateInitialSourceProvider(sourceProvider);
        if (sourceProvider == VersionControlType.TFGIT.ToString())
        {
            provider.Fields["RepositoryName"] = "Git";
        }
        buildDefinitionClone.SetSourceProvider(provider);


        buildDefinitionClone.Save();
        return buildDefinitionClone;
    }

    private static IBuildController GetBuildController(IBuildServer buildServer, string buildController)
    {
        if (string.IsNullOrEmpty(buildController))
            return buildServer.QueryBuildControllers(false).Where(c=> c.Status == ControllerStatus.Available).First();

        return buildServer.GetBuildController(buildController);
    }

對於XAML構建,您需要使用IBuildServer.GetBuildDefinition方法首先獲取構建定義,然后執行復制。

首先,通過調用TfsTeamProjectCollection實例上的GetService方法獲取對構建服務器的引用。 獲得構建服務器引用后,您可以加載要復制的構建定義。

如果要使用流程參數復制構建定義,則還應首先復制模板。 示例代碼sinnper

  // Copy Process parameters
  newBuildDefinition.Process = buildDefinitionToCopy.Process;
  var processParams = WorkflowHelpers.DeserializeProcessParameters(buildDefinitionToCopy.ProcessParameters);
  var copyProcessParams = WorkflowHelpers.DeserializeProcessParameters(newBuildDefinition.ProcessParameters);
 foreach (KeyValuePair<string, object> entry in processParams)
  {
      copyProcessParams.Add(entry.Key.ToString(), entry.Value);
  }
 newBuildDefinition.ProcessParameters = WorkflowHelpers.SerializeProcessParameters(copyProcessParams);

有關如何通過API實現復制的更多詳細信息,您可以參考此博客 - 復制TFS構建定義

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM