TFS 2017 发布管理:如何为发布下的任务显示父 PBI [英] TFS 2017 Release Management: How to display parent PBI for Tasks under Release

查看:29
本文介绍了TFS 2017 发布管理:如何为发布下的任务显示父 PBI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法在 TFS2017 下的列表中显示 Release 下 Task Work 项的父 PBI?

下面的屏幕截图显示了与 Release-3 相关的两个任务.在这里,我希望能够为每个人显示父 PBI.通过展开它们或仅显示一个附加的列与父 PBI 的链接

感谢您的帮助

我知道可以在 TFS 上创建查询.问题是我需要显示与特定版本相关的父工作项的信息,以便用户可以使用它们进行报告.我试图为此目的创建一个查询,但我找不到基于 Release 的过滤选项,所以我认为可能可以启用一些额外的列,或者可能有一个扩展,但我无法弄清楚如何去做..

解决方案

通过扩展实现的步骤:

  1. 获取指定版本以获取构建 ID
  2. 根据构建 ID 获取该构建的工作项
  3. 获取相关工作项

有简单的扩展代码来获取您可以参考的特定版本的工作项:

HTML:

<头><title>自定义小部件</title><meta charset="utf-8"/><script src="node_modules/vss-web-extension-sdk/lib/VSS.SDK.js"></script><script type="text/javascript">VSS.init({显式通知加载:真,usePlatformStyles:true});VSS.require(["TFS/Dashboards/WidgetHelpers", "TFS/TestManagement/RestClient", "TFS/WorkItemTracking/RestClient", "TFS/Build/RestClient", "VSS/Service", "VSS/Identities/Contracts", "VSS/Identities/RestClient", "VSS/Authentication/Services"], 函数 (WidgetHelpers, TFS_Test_WebApi, TFS_Work_WebApi, TFS_Build_Client, VSS_Service, idContracts, idRest, VSS_Auth_Service) {WidgetHelpers.IncludeWidgetStyles();VSS.register("WidgetStarain", function () {var authHeader = "无";var vstsAccount = "无";var projectName = "无";var releaseRestAPIPrex = "无"var getReleaseWorkItems= 函数 (widgetSettings) {var c = VSS.getWebContext();vstsAccount = c.account.name;项目名称 = c.project.name;releaseRestAPIPrex="https://" + vstsAccount + ".vsrm.visualstudio.com/DefaultCollection/" + projectName + "/_apis/release"VSS.getAccessToken().then(function (token) {authHeader = VSS_Auth_Service.authTokenManager.getAuthorizationHeader(token);$.ajax({类型:'获取',url: releaseRestAPIPrex+'/definitions?api-version=3.0-preview.1',缓存:假,数据类型:'json',beforeSend: 函数 (xhr) {xhr.setRequestHeader("授权", authHeader);},}).完成(功能(数据){var v = data.value;$("#releaseDefList").empty();$("#releaseDefList").append('<option value="select">select</option>');$.each(v, function (index, value) {$("#releaseDefList").append('<option value="' + value.id + '">' + value.name + '</option>');});}).错误(函数(e){var s = "ss";});});};$("#releaseDefList").change(function () {var str = "";$("#releaseList").empty();$("#releaseList").append('<option value="select">select</option>');$("#releaseDefList option:selected").each(function () {var releaseDefId = $(this).val();如果(releaseDefId !=选择"){$.ajax({类型:'获取',url: releaseRestAPIPrex+'/releases?definitionId=' + releaseDefId + '&api-version=3.0-preview.2',缓存:假,数据类型:'json',beforeSend: 函数 (xhr) {xhr.setRequestHeader("授权", authHeader);},}).完成(功能(数据){var v = data.value;$.each(v, function (index, value) {$("#releaseList").append('<option value="' + value.id + '">' + value.name + '</option>');});}).错误(函数(e){var s = "ss";});}});});$("#releaseList").change(function () {var str = "";$("#releaseList option:selected").each(function () {var releaseId = $(this).val();如果(releaseId!=选择"){$.ajax({类型:'获取',url: releaseRestAPIPrex+'/release/releases/' + releaseId + '?api-version=3.0-preview.2',缓存:假,数据类型:'json',beforeSend: 函数 (xhr) {xhr.setRequestHeader("授权", authHeader);},}).完成(功能(数据){var artifacts = data.artifacts;$.each(artifacts, function (index, value) {var buildId = value.definitionReference.version.id;TFS_Build_Client.getClient().getBuildWorkItemsRefs(projectName, buildId).then(function (workitemRefs) {var workItemIds = new Array();$.each(workitemRefs, function (index, value) {workItemIds.push(value.id);});var workitemString = "";TFS_Work_WebApi.getClient().getWorkItems(workItemIds,null,null,"All").then(function (workitems) {$.each(workitems, function (index, value) {workitemString += "ID: " + value.id + "; Title: " + value.fields["System.Title"];});$("#workitems").text(workitemString);});});});}).错误(函数(e){var s = "ss";});}});});返回 {负载:功能(小部件设置){getReleaseWorkItems(widgetSettings);返回 WidgetHelpers.WidgetStatusHelper.Success();}}});VSS.notifyLoadSucceeded();});<身体><div class="widget"><h2 class="title">widgets starain</h2><div class="token">none</div><select id="releaseDefList"><option id="select">select</option></选择><select id="releaseList"><option id="select">select</option></选择><div id="工作项">无工作项

</html>

vss-extension.json:

<代码>{清单版本":1,"id": "样本扩展名",版本":0.5.34","name": "我的测试扩展","description": "我的测试扩展描述","publisher": "Starain",目标":[{"id": "Microsoft.VisualStudio.Services"}],图标":{"default": "图片/logo.png"},范围":["vso.work","vso.build","vso.build_execute","vso.test","vso.test_write",vso.release"],贡献":[{"id": "WidgetStarain","type": "ms.vss-dashboards-web.widget",目标":[ms.vss-dashboards-web.widget-catalog",Starain.sample-extension.WidgetStarainConfiguration"],特性": {"name": "widget starain","description": "自定义小部件","catelogIconUrl": "图片/iconProperty.png","previewImageUrl": "图片/iconProperty.png","uri": "WidgetStarain.html",支持的尺寸":[{行跨度":1,列跨度":2}],supportedScopes":[project_team"]}}],文件":[{"path": "node_modules/vss-web-extension-sdk/lib",可寻址":true},{"path": "图片",可寻址":true},{"path": "脚本",可寻址":true},{"path": "WidgetStarain.html",可寻址":true}]}

Is there any way to show the parent PBI for a Task Work item under Release in the list under TFS2017?

The screenshot below shows two tasks associated with Release-3. Here I wish to be able to display the parent PBI for each of them. Either by expanding them or just by displaying an additional column with link to the parent PBI

I appreciate your help

Edit: I know that that there is a possibility to create a query on TFS. The problem is that I need to display the information on the parent Work item that are related to a specific Release so the user can use them for reporting. I tried to to create a query for this purpose but I couldn't find a filtering option based on Release so I thought it might be possible to enable some additional columns or there might be an extension for that but I couldn't figure out how to do it..

解决方案

The steps to achieve that with extension:

  1. Get specify release to get build id
  2. Get work items of that build per build id
  3. Get related work items

There is simple code of extension to get work items of specific release that you can refer to:

HTML:

<!DOCTYPE html>
<html>
<head>
    <title>Custom widget</title>
    <meta charset="utf-8" />
    <script src="node_modules/vss-web-extension-sdk/lib/VSS.SDK.js"></script>
    <script type="text/javascript">
        VSS.init({
            explicitNotifyLoaded: true,
            usePlatformStyles:true
        });
        VSS.require(["TFS/Dashboards/WidgetHelpers", "TFS/TestManagement/RestClient", "TFS/WorkItemTracking/RestClient", "TFS/Build/RestClient", "VSS/Service", "VSS/Identities/Contracts", "VSS/Identities/RestClient", "VSS/Authentication/Services"], function (WidgetHelpers, TFS_Test_WebApi, TFS_Work_WebApi, TFS_Build_Client, VSS_Service, idContracts, idRest, VSS_Auth_Service) {
            WidgetHelpers.IncludeWidgetStyles();
            VSS.register("WidgetStarain", function () {

                 var authHeader = "none";
                var vstsAccount = "none";
                var projectName = "none";
                var releaseRestAPIPrex = "none"
                var getReleaseWorkItems= function (widgetSettings) {
                    var c = VSS.getWebContext();
                    vstsAccount = c.account.name;
                    projectName = c.project.name;
                    releaseRestAPIPrex="https://" + vstsAccount + ".vsrm.visualstudio.com/DefaultCollection/" + projectName + "/_apis/release"
                    VSS.getAccessToken().then(function (token) {

                        authHeader = VSS_Auth_Service.authTokenManager.getAuthorizationHeader(token);

                        $.ajax({
                            type: 'GET',
                            url: releaseRestAPIPrex+'/definitions?api-version=3.0-preview.1',
                            cache: false,
                            dataType: 'json',
                            beforeSend: function (xhr) {
                                xhr.setRequestHeader("Authorization", authHeader);
                            },
                        }).done(function (data) {
                            var v = data.value;
                            $("#releaseDefList").empty();
                            $("#releaseDefList").append('<option value="select">select</option>');
                            $.each(v, function (index, value) {
                                $("#releaseDefList").append('<option value="' + value.id + '">' + value.name + '</option>');
                            });
                        }).error(function (e) {
                            var s = "ss";
                        });

                    });

                };
                $("#releaseDefList").change(function () {
                    var str = "";
                    $("#releaseList").empty();
                    $("#releaseList").append('<option value="select">select</option>');
                    $("#releaseDefList option:selected").each(function () {

                        var releaseDefId = $(this).val();
                        if (releaseDefId != "select") {
                            $.ajax({
                                type: 'GET',
                                url: releaseRestAPIPrex+'/releases?definitionId=' + releaseDefId + '&api-version=3.0-preview.2',
                                cache: false,
                                dataType: 'json',
                                beforeSend: function (xhr) {
                                    xhr.setRequestHeader("Authorization", authHeader);
                                },
                            }).done(function (data) {
                                var v = data.value;

                                $.each(v, function (index, value) {
                                    $("#releaseList").append('<option value="' + value.id + '">' + value.name + '</option>');
                                });
                            }).error(function (e) {
                                var s = "ss";
                            });
                        }

                    });


                });
                $("#releaseList").change(function () {
                    var str = "";

                    $("#releaseList option:selected").each(function () {

                        var releaseId = $(this).val();
                        if (releaseId != "select") {
                            $.ajax({
                                type: 'GET',
                                url: releaseRestAPIPrex+'/release/releases/' + releaseId + '?api-version=3.0-preview.2',                                
                               cache: false,
                                dataType: 'json',
                                beforeSend: function (xhr) {
                                    xhr.setRequestHeader("Authorization", authHeader);
                                },
                            }).done(function (data) {
                                var artifacts = data.artifacts;
                                $.each(artifacts, function (index, value) {
                                    var buildId = value.definitionReference.version.id;

                                    TFS_Build_Client.getClient().getBuildWorkItemsRefs(projectName, buildId).then(function (workitemRefs) {
                                        var workItemIds = new Array();
                                        $.each(workitemRefs, function (index, value) {
                                            workItemIds.push(value.id);
                                        });
                                        var workitemString = "";
                                        TFS_Work_WebApi.getClient().getWorkItems(workItemIds,null,null,"All").then(function (workitems) {
                                            $.each(workitems, function (index, value) {
                                                workitemString += "ID: " + value.id + "; Title: " + value.fields["System.Title"];
                                            });
                                            $("#workitems").text(workitemString);
                                        });

                                    });
                                });

                            }).error(function (e) {
                                var s = "ss";
                            });
                        }

                    });


                });
                 return {
                    load: function (widgetSettings) {
                       getReleaseWorkItems(widgetSettings);
                        return WidgetHelpers.WidgetStatusHelper.Success();
                    }
                }
            });
            VSS.notifyLoadSucceeded();
        });
    </script>
</head>
<body>
    <div class="widget">
        <h2 class="title">widgets starain</h2>  
        <div class="token">none</div>

        <select id="releaseDefList">
            <option id="select">select</option>
        </select>
        <select id="releaseList">
            <option id="select">select</option>
        </select>
        <div id="workitems">
            none workitem
        </div>


    </div>
</body>
</html>

vss-extension.json:

{
  "manifestVersion": 1,
  "id": "sample-extension",
  "version": "0.5.34",
  "name": "My test extension",
  "description": "my test extension description",
  "publisher": "Starain",
  "targets": [
    {
      "id": "Microsoft.VisualStudio.Services"
    }
  ],
  "icons": {
    "default": "Images/logo.png"
  },
  "scopes": [
    "vso.work",
    "vso.build",
    "vso.build_execute",
    "vso.test",
    "vso.test_write",
    "vso.release"
  ],
  "contributions": [
        {
      "id": "WidgetStarain",
      "type": "ms.vss-dashboards-web.widget",
      "targets": [ "ms.vss-dashboards-web.widget-catalog", "Starain.sample-extension.WidgetStarainConfiguration" ],
      "properties": {
        "name": "widget starain",
        "description": "custom widget",
        "catelogIconUrl": "Images/iconProperty.png",
        "previewImageUrl": "Images/iconProperty.png",
        "uri": "WidgetStarain.html",
        "supportedSizes": [
          {
            "rowSpan": 1,
            "columnSpan": 2
          }
        ],
        "supportedScopes": [ "project_team" ]
      }
    } 
  ],
  "files": [
    {
      "path": "node_modules/vss-web-extension-sdk/lib",
      "addressable": true
    },
    {
      "path": "Images",
      "addressable": true
    },
    {
      "path": "Scripts",
      "addressable": true
    },
    {
      "path": "WidgetStarain.html",
      "addressable": true

    }
   ]
}

这篇关于TFS 2017 发布管理:如何为发布下的任务显示父 PBI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆