簡體   English   中英

TFS 2015.2中的工作項創建問題(使用vsts-node-api)

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

通過vso-node-api包在TFS 2015.2(在permise中)中創建錯誤項時,出現以下錯誤,但是相同的代碼在我的VSTS(在線)訂閱中可以正常工作。

[錯誤:失敗的請求:錯誤的請求(400)-TF401349:發生意外錯誤,請驗證您的請求,然后重試。] statusCode:400

我在vso-node-api庫中使用WorkItemTrackingApi / createWorkItem函數創建工作項。 以下是我用來創建工作項的示例代碼。

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;
    }
}

應用程式

/// <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.");

范圍: “范圍”:[“ vso.build_execute”,“ vso.work_write”],

由於這個職位指出,TFS上permise只支持NTLM身份驗證和Kerberos。 我假設直到MS更新TFS為止,訪問令牌永遠不會成為一種選擇。

TFS 2015.3不支持基於令牌的身份驗證。 替代方法是使用基本身份驗證選項。 如果擴展應同時與VSTS和TFS兼容,則必須創建一種機制以針對每種部署方案使用單獨的身份驗證機制。 TFS 2017支持令牌身份驗證,因此它可以像VSTS一樣與PAT一起正常使用。

暫無
暫無

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

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