简体   繁体   English

TFS 2015.2中的工作项创建问题(使用vsts-node-api)

[英]Work item creation issue in TFS 2015.2 (with vsts-node-api)

I'm getting following error when creating bug item in TFS 2015.2 (On permise) via vso-node-api package, however same code is working perfectly in my VSTS (online) subscription. 通过vso-node-api包在TFS 2015.2(在permise中)中创建错误项时,出现以下错误,但是相同的代码在我的VSTS(在线)订阅中可以正常工作。

[Error: Failed Request: Bad Request(400) - TF401349: An unexpected error has occurred, please verify your request and try again.] statusCode: 400 [错误:失败的请求:错误的请求(400)-TF401349:发生意外错误,请验证您的请求,然后重试。] statusCode:400

Im using the WorkItemTrackingApi/createWorkItem function in vso-node-api library to create the work item. 我在vso-node-api库中使用WorkItemTrackingApi / createWorkItem函数创建工作项。 Following is the sample code I have used to create work items. 以下是我用来创建工作项的示例代码。

WorkItemCreator.ts WorkItemCreator.ts

import * as vm from 'vso-node-api/WebApi';
import * as wa from 'vso-node-api/WorkItemTrackingApi';
import * as wi from 'vso-node-api/interfaces/WorkItemTrackingInterfaces';
import * as vss from 'vso-node-api/interfaces/Common/VSSInterfaces';
import * as core from 'vso-node-api/interfaces/CoreInterfaces';
import tl = require('vsts-task-lib/task');

export class WorkItemCreator {
    workItemType: string = "Bug";
    fieldsToRetrieve: string[] = ["System.State", "System.Title"];

    collectionUrl: string;
    projName: string;
    accessToken: string;
    vstsWI: wa.IWorkItemTrackingApi;
    projectId: string;

    constructor() {
        console.log("Initializing Workitem Creator...");
        console.log("Retrieving enviornment values...");
        this.collectionUrl = process.env["SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"];
        this.projName = process.env["SYSTEM_TEAMPROJECT"];
        this.projectId = process.env["SYSTEM_TEAMPROJECTID"];

        console.log("SYSTEM_TEAMFOUNDATIONCOLLECTIONURI: " + this.collectionUrl);
        console.log("SYSTEM_TEAMPROJECT: " + this.projName);

        this.accessToken = this.getAccessToken();
        let creds = vm.getBearerHandler(this.accessToken);
        let connection = new vm.WebApi(this.collectionUrl, creds);
        this.vstsWI = connection.getWorkItemTrackingApi();
    }

    /**
     * Create Work Items
     */
    public createWorkItems(workItems: Array<BugItem>) {
        workItems.forEach(workItem => {
            let selectWorkItemsQry = { query: "Select [System.Id] From WorkItems Where [System.WorkItemType] = '" + this.workItemType + "' AND [System.Title] = '" + workItem.title + "'" };
            this.getWorkitem(this.projName, this.projectId, selectWorkItemsQry).then((qr: wi.WorkItemQueryResult) => {
                console.log("WorkItem Count:" + qr.workItems.length);
                if (qr.workItems.length == 0) {
                    console.log("Creating WorkItem '" + workItem.title + "' in project '" + this.projName + "'");
                    let xs: string[] = ["TagX", "TagY", "TagZ"];
                    console.log("Tags: " + xs);
                    this.createWorkitem(this.projName, this.workItemType, workItem.title, workItem.description, workItem.severity, xs);
                }
            })
            .catch((e) => {
                    console.error("Failed to retrieve WorkItem by title '" + workItem.title + "' Error: " + e);
            });
        });        
    }

    //Get acces token
    private getAccessToken(): string {
        tl.debug("Getting credentials for local feeds");
        let auth = tl.getEndpointAuthorization("SYSTEMVSSCONNECTION", false);
        if (auth.scheme === "OAuth") {
            console.log("Token retrieved: " + auth.parameters["AccessToken"]);
            tl.debug("Token retrieved: " + auth.parameters["AccessToken"]);
            return auth.parameters["AccessToken"];
        }
        else {
            tl.warning("Could not retrieve authentication token for Workitem creation.");
        }
    }


    //Create Workitem
    private createWorkitem(projectName: string, witype: string, title: string, description: string, severity: string, tagsCollection: string[]) {
        let wijson: vss.JsonPatchDocument = [
            { "op": "add", "path": "/fields/System.Title", "value": title },
        ];

        this.vstsWI.createWorkItem(null, wijson, projectName, witype, null, null).then((workitem: wi.WorkItem) => {
            console.log("WorkItem '" + workitem.id + "' Created");
        }).catch((e) => {
            console.error("Failed to create work item for '" + title + "' Error: " + e);
        });
    }

    /**
     * Get Workitems
     */
    private getWorkitem(projectName: string, teamProjectId: string, wiqlQuerry: wi.Wiql): Promise<wi.WorkItemQueryResult> {
        console.log(wiqlQuerry.query);
        let teamContext: core.TeamContext = { project: projectName, projectId: teamProjectId, team: "", teamId: "" };
        return this.vstsWI.queryByWiql(wiqlQuerry, teamContext, null, null);
    }
}

/**
 * BugItem
 */
export class BugItem {
    title: string;
    description: string;
    severity: string;

    constructor(title: string, description: string, severity: string) {
        this.title = title;
        this.description = description;
        this.severity = severity;
    }
}

App.ts 应用程式

/// <reference path="../definitions/node.d.ts" />
/// <reference path="../definitions/minimatch.d.ts" />
const Critical = "1 - Critical";
const Low = "4 - Low";

import * as wIc from './WorkItemCreator';

var x = new wIc.WorkItemCreator();
var fullCollection = new Array<wIc.BugItem>();

var itm1 = new wIc.BugItem("Bug1TitleItem1", "DescriptionCritical", Critical);
fullCollection.push(itm1);
var itm6 = new wIc.BugItem("Bug1TitleItem6","DescriptionLow",Low);
fullCollection.push(itm6);

x.createWorkItems(fullCollection);
console.log("End.");

Scopes: "scopes": [ "vso.build_execute", "vso.work_write" ], 范围: “范围”:[“ vso.build_execute”,“ vso.work_write”],

As this post points out, TFS on permise only supports NTLM and Kerberos for authentication. 由于这个职位指出,TFS上permise只支持NTLM身份验证和Kerberos。 I would assume until MS update TFS, access token is never an option. 我假设直到MS更新TFS为止,访问令牌永远不会成为一种选择。

TFS 2015.3 doesn't support token based authentication. TFS 2015.3不支持基于令牌的身份验证。 Alternative is to use Basic Authentication option. 替代方法是使用基本身份验证选项。 If the extension should be compatible with both VSTS and TFS, then you have to create a mechanism to use separate authentication mechanism for each deployment scenario. 如果扩展应同时与VSTS和TFS兼容,则必须创建一种机制以针对每种部署方案使用单独的身份验证机制。 TFS 2017 support token authentication so that it will work fine with the PAT just like VSTS. TFS 2017支持令牌身份验证,因此它可以像VSTS一样与PAT一起正常使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM