简体   繁体   中英

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.

[Error: Failed Request: Bad Request(400) - TF401349: An unexpected error has occurred, please verify your request and try again.] statusCode: 400

Im using the WorkItemTrackingApi/createWorkItem function in vso-node-api library to create the work item. Following is the sample code I have used to create work items.

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" ],

As this post points out, TFS on permise only supports NTLM and Kerberos for authentication. I would assume until MS update TFS, access token is never an option.

TFS 2015.3 doesn't support token based authentication. 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. TFS 2017 support token authentication so that it will work fine with the PAT just like VSTS.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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