Support PAT token on command line
This commit is contained in:
Родитель
78add5bc2e
Коммит
7a37b23193
|
@ -1,3 +1,4 @@
|
|||
node_modules/*
|
||||
output/*
|
||||
build/*
|
||||
test/*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "process-import-export",
|
||||
"version": "0.9.3",
|
||||
"name": "process-migrator",
|
||||
"version": "0.9.4",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
@ -63,6 +63,27 @@
|
|||
"resolved": "https://registry.npmjs.org/@types/requirejs/-/requirejs-2.1.31.tgz",
|
||||
"integrity": "sha512-b2soeyuU76rMbcRJ4e0hEl0tbMhFwZeTC0VZnfuWlfGlk6BwWNsev6kFu/twKABPX29wkX84wU2o+cEJoXsiTw=="
|
||||
},
|
||||
"azure-devops-node-api": {
|
||||
"version": "6.6.0",
|
||||
"resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-6.6.0.tgz",
|
||||
"integrity": "sha512-fF3AI0dyVyJvd3ucSDIGtexlbK7uA2dH/uh1X5Ue9bsSQQcX1cYqXWS6I7IS5/TxSzs3A3d6IXRx8zstgNGXMA==",
|
||||
"requires": {
|
||||
"tunnel": "0.0.4",
|
||||
"typed-rest-client": "1.0.9",
|
||||
"underscore": "1.8.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"typed-rest-client": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.0.9.tgz",
|
||||
"integrity": "sha512-iOdwgmnP/tF6Qs+oY4iEtCf/3fnCDl7Gy9LGPJ4E3M4Wj3uaSko15FVwbsaBmnBqTJORnXBWVY5306D4HH8oiA==",
|
||||
"requires": {
|
||||
"tunnel": "0.0.4",
|
||||
"underscore": "1.8.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"guid-typescript": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://witiq.pkgs.visualstudio.com/_packaging/processimportexport/npm/registry/guid-typescript/-/guid-typescript-1.0.7.tgz",
|
||||
|
@ -108,15 +129,6 @@
|
|||
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz",
|
||||
"integrity": "sha1-LTeFoVjBdMmhbcLARuxfxfF0IhM="
|
||||
},
|
||||
"typed-rest-client": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-0.12.0.tgz",
|
||||
"integrity": "sha1-Y3b1Un9CfaEh3K/f1+QeEyHgcgw=",
|
||||
"requires": {
|
||||
"tunnel": "0.0.4",
|
||||
"underscore": "1.8.3"
|
||||
}
|
||||
},
|
||||
"typescript": {
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.8.1.tgz",
|
||||
|
@ -137,16 +149,6 @@
|
|||
"querystring": "0.2.0"
|
||||
}
|
||||
},
|
||||
"vso-node-api": {
|
||||
"version": "6.5.0",
|
||||
"resolved": "https://witiq.pkgs.visualstudio.com/_packaging/processimportexport/npm/registry/vso-node-api/-/vso-node-api-6.5.0.tgz",
|
||||
"integrity": "sha512-hFjPLMJkq02zF8U+LhZ4airH0ivaiKzGdlNAQlYFB3lWuGH/UANUrl63DVPUQOyGw+7ZNQ+ufM44T6mWN92xyg==",
|
||||
"requires": {
|
||||
"tunnel": "0.0.4",
|
||||
"typed-rest-client": "0.12.0",
|
||||
"underscore": "1.8.3"
|
||||
}
|
||||
},
|
||||
"vss-web-extension-sdk": {
|
||||
"version": "5.131.0",
|
||||
"resolved": "https://registry.npmjs.org/vss-web-extension-sdk/-/vss-web-extension-sdk-5.131.0.tgz",
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
"minimist": "^1.2.0",
|
||||
"mkdirp": "^0.5.1",
|
||||
"url": "^0.11.0",
|
||||
"vso-node-api": "^6.5.0",
|
||||
"azure-devops-node-api": "^6.5.0",
|
||||
"vss-web-extension-sdk": "^5.131.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/// <reference types="vss-web-extension-sdk" />
|
||||
import * as WITInterfaces from "vso-node-api/interfaces/WorkItemTrackingInterfaces";
|
||||
import * as WITProcessDefinitionsInterfaces from "vso-node-api/interfaces/WorkItemTrackingProcessDefinitionsInterfaces";
|
||||
import * as WITProcessInterfaces from "vso-node-api/interfaces/WorkItemTrackingProcessInterfaces";
|
||||
import { WorkItemTrackingApi } from "vso-node-api/WorkItemTrackingApi";
|
||||
import * as WITInterfaces from "azure-devops-node-api/interfaces/WorkItemTrackingInterfaces";
|
||||
import * as WITProcessDefinitionsInterfaces from "azure-devops-node-api/interfaces/WorkItemTrackingProcessDefinitionsInterfaces";
|
||||
import * as WITProcessInterfaces from "azure-devops-node-api/interfaces/WorkItemTrackingProcessInterfaces";
|
||||
import { WorkItemTrackingApi } from "azure-devops-node-api/WorkItemTrackingApi";
|
||||
import { getCollectionClient } from "VSS/Service";
|
||||
import { WorkItemTrackingHttpClient } from "TFS/WorkItemTracking/RestClient";
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@ export const defaultLogFileName = "output\\processMigrator.log";
|
|||
export const defaultProcessFilename = "output\\process.json";
|
||||
export const paramMode = "mode";
|
||||
export const paramConfig = "config";
|
||||
export const paramSourceToken = "sourceToken";
|
||||
export const paramTargetToken = "targetToken";
|
||||
export const paramOverwriteProcessOnTarget = "overwriteProcessOnTarget";
|
||||
export const defaultConfiguration =
|
||||
`{
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import * as WITProcessDefinitionsInterfaces from "vso-node-api/interfaces/WorkItemTrackingProcessDefinitionsInterfaces";
|
||||
import * as WITProcessInterfaces from "vso-node-api/interfaces/WorkItemTrackingProcessInterfaces";
|
||||
import * as WITInterfaces from "vso-node-api/interfaces/WorkItemTrackingInterfaces";
|
||||
import { IWorkItemTrackingProcessDefinitionsApi as WITProcessDefinitionApi } from "vso-node-api/WorkItemTrackingProcessDefinitionsApi";
|
||||
import { IWorkItemTrackingProcessApi as WITProcessApi } from "vso-node-api/WorkItemTrackingProcessApi";
|
||||
import { IWorkItemTrackingApi as WITApi } from "vso-node-api/WorkItemTrackingApi";
|
||||
import * as WITProcessDefinitionsInterfaces from "azure-devops-node-api/interfaces/WorkItemTrackingProcessDefinitionsInterfaces";
|
||||
import * as WITProcessInterfaces from "azure-devops-node-api/interfaces/WorkItemTrackingProcessInterfaces";
|
||||
import * as WITInterfaces from "azure-devops-node-api/interfaces/WorkItemTrackingInterfaces";
|
||||
import { IWorkItemTrackingProcessDefinitionsApi as WITProcessDefinitionApi } from "azure-devops-node-api/WorkItemTrackingProcessDefinitionsApi";
|
||||
import { IWorkItemTrackingProcessApi as WITProcessApi } from "azure-devops-node-api/WorkItemTrackingProcessApi";
|
||||
import { IWorkItemTrackingApi as WITApi } from "azure-devops-node-api/WorkItemTrackingApi";
|
||||
|
||||
export enum LogLevel {
|
||||
error,
|
||||
|
@ -26,6 +26,8 @@ export interface ICommandLineOptions {
|
|||
mode: Modes;
|
||||
overwriteProcessOnTarget: boolean;
|
||||
config: string;
|
||||
sourceToken?: string;
|
||||
targetToken?: string;
|
||||
}
|
||||
|
||||
export interface IConfigurationFile {
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
import * as WITProcessDefinitionsInterfaces from "vso-node-api/interfaces/WorkItemTrackingProcessDefinitionsInterfaces";
|
||||
import * as WITProcessInterfaces from "vso-node-api/interfaces/WorkItemTrackingProcessInterfaces";
|
||||
|
||||
import * as vsts_NOREQUIRE from "vso-node-api/WebApi";
|
||||
import { IWorkItemTrackingProcessDefinitionsApi as WITProcessDefinitionApi_NOREQUIRE } from "vso-node-api/WorkItemTrackingProcessDefinitionsApi";
|
||||
import { IWorkItemTrackingProcessApi as WITProcessApi_NOREQUIRE } from "vso-node-api/WorkItemTrackingProcessApi";
|
||||
import { IWorkItemTrackingApi as WITApi_NOREQUIRE } from "vso-node-api/WorkItemTrackingApi";
|
||||
import * as WITProcessDefinitionsInterfaces from "azure-devops-node-api/interfaces/WorkItemTrackingProcessDefinitionsInterfaces";
|
||||
import * as WITProcessInterfaces from "azure-devops-node-api/interfaces/WorkItemTrackingProcessInterfaces";
|
||||
import * as vsts_NOREQUIRE from "azure-devops-node-api/WebApi";
|
||||
import { IWorkItemTrackingProcessDefinitionsApi as WITProcessDefinitionApi_NOREQUIRE } from "azure-devops-node-api/WorkItemTrackingProcessDefinitionsApi";
|
||||
import { IWorkItemTrackingProcessApi as WITProcessApi_NOREQUIRE } from "azure-devops-node-api/WorkItemTrackingProcessApi";
|
||||
import { IWorkItemTrackingApi as WITApi_NOREQUIRE } from "azure-devops-node-api/WorkItemTrackingApi";
|
||||
|
||||
import { IConfigurationFile, IDictionaryStringTo, IProcessPayload, IWITBehaviors, IWITBehaviorsInfo, IWITFieldPicklist, IWITLayout, IWITRules, IWITStates, IWITypeFields, IRestClients } from "./Interfaces";
|
||||
import { ExportError } from "./Errors";
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import * as assert from "assert";
|
||||
import { Guid } from "guid-typescript";
|
||||
|
||||
import * as WITInterfaces from "vso-node-api/interfaces/WorkItemTrackingInterfaces";
|
||||
import * as WITProcessDefinitionsInterfaces from "vso-node-api/interfaces/WorkItemTrackingProcessDefinitionsInterfaces";
|
||||
import * as WITProcessInterfaces from "vso-node-api/interfaces/WorkItemTrackingProcessInterfaces";
|
||||
import { IWorkItemTrackingProcessDefinitionsApi as WITProcessDefinitionApi_NOREQUIRE } from "vso-node-api/WorkItemTrackingProcessDefinitionsApi";
|
||||
import { IWorkItemTrackingProcessApi as WITProcessApi_NOREQUIRE } from "vso-node-api/WorkItemTrackingProcessApi";
|
||||
import { IWorkItemTrackingApi as WITApi_NOREQUIRE } from "vso-node-api/WorkItemTrackingApi";
|
||||
import * as WITInterfaces from "azure-devops-node-api/interfaces/WorkItemTrackingInterfaces";
|
||||
import * as WITProcessDefinitionsInterfaces from "azure-devops-node-api/interfaces/WorkItemTrackingProcessDefinitionsInterfaces";
|
||||
import * as WITProcessInterfaces from "azure-devops-node-api/interfaces/WorkItemTrackingProcessInterfaces";
|
||||
import { IWorkItemTrackingProcessDefinitionsApi as WITProcessDefinitionApi_NOREQUIRE } from "azure-devops-node-api/WorkItemTrackingProcessDefinitionsApi";
|
||||
import { IWorkItemTrackingProcessApi as WITProcessApi_NOREQUIRE } from "azure-devops-node-api/WorkItemTrackingProcessApi";
|
||||
import { IWorkItemTrackingApi as WITApi_NOREQUIRE } from "azure-devops-node-api/WorkItemTrackingApi";
|
||||
|
||||
import { PICKLIST_NO_ACTION } from "./Constants";
|
||||
import { Engine } from "./Engine";
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import * as WITInterfaces from "vso-node-api/interfaces/WorkItemTrackingInterfaces";
|
||||
import * as WITProcessDefinitionsInterfaces from "vso-node-api/interfaces/WorkItemTrackingProcessDefinitionsInterfaces";
|
||||
import * as WITProcessInterfaces from "vso-node-api/interfaces/WorkItemTrackingProcessInterfaces";
|
||||
import * as WITInterfaces from "azure-devops-node-api/interfaces/WorkItemTrackingInterfaces";
|
||||
import * as WITProcessDefinitionsInterfaces from "azure-devops-node-api/interfaces/WorkItemTrackingProcessDefinitionsInterfaces";
|
||||
import * as WITProcessInterfaces from "azure-devops-node-api/interfaces/WorkItemTrackingProcessInterfaces";
|
||||
import { KnownError } from "./Errors";
|
||||
import { logger } from "./Logger";
|
||||
import { Modes, IConfigurationFile, LogLevel } from "./Interfaces";
|
||||
import { Modes, IConfigurationFile, LogLevel, ICommandLineOptions } from "./Interfaces";
|
||||
import * as url from "url";
|
||||
import { Guid } from "guid-typescript";
|
||||
import { regexRemoveHypen } from "./Constants";
|
||||
|
@ -193,7 +193,7 @@ export class Utility {
|
|||
return false;
|
||||
}
|
||||
if (!configuration.targetAccountToken) {
|
||||
logger.logError(`[Configuration validation] Personal access token for target account is empty.`);
|
||||
logger.logError(`[Configuration validation] Missing personal access token for target account.`);
|
||||
return false;
|
||||
}
|
||||
if (configuration.options && configuration.options.overwritePicklist && (configuration.options.overwritePicklist !== true && configuration.options.overwritePicklist !== false)) {
|
||||
|
|
|
@ -2,7 +2,7 @@ import { existsSync, readFileSync, writeFileSync } from "fs";
|
|||
import { normalize } from "path";
|
||||
import * as minimist from "minimist";
|
||||
import * as url from "url";
|
||||
import { defaultConfiguration, defaultConfigurationFilename, defaultEncoding, paramConfig, paramMode, paramOverwriteProcessOnTarget } from "../common/Constants";
|
||||
import { defaultConfiguration, defaultConfigurationFilename, defaultEncoding, paramConfig, paramMode, paramSourceToken, paramTargetToken } from "../common/Constants";
|
||||
import { IConfigurationFile, LogLevel, Modes, ICommandLineOptions } from "../common/Interfaces";
|
||||
import { logger } from "../common/Logger";
|
||||
import { Utility } from "../common/Utilities";
|
||||
|
@ -14,7 +14,9 @@ export function ProcesCommandLine(): ICommandLineOptions {
|
|||
alias: {
|
||||
"help": "h",
|
||||
"mode": "m",
|
||||
"config": "c"
|
||||
"config": "c",
|
||||
"sourcetoken": "s",
|
||||
"targettoken": "t"
|
||||
}
|
||||
}
|
||||
const parsedArgs = minimist(process.argv, parseOptions);
|
||||
|
@ -33,7 +35,7 @@ export function ProcesCommandLine(): ICommandLineOptions {
|
|||
case Modes[Modes.export]: mode = Modes.export; break;
|
||||
case Modes[Modes.import]: mode = Modes.import; break;
|
||||
case Modes[Modes.migrate]: mode = Modes.migrate; break;
|
||||
default: logger.logError(`Invalid mode argument, allowed values are 'import','export' and 'migrate'.`); process.exit(1);
|
||||
default: logger.logError(`Invalid mode argument, allowed values are 'import', 'export' or 'migrate'.`); process.exit(1);
|
||||
}
|
||||
} else {
|
||||
mode = Modes.migrate;
|
||||
|
@ -42,15 +44,17 @@ export function ProcesCommandLine(): ICommandLineOptions {
|
|||
const ret = {};
|
||||
ret[paramMode] = mode;
|
||||
ret[paramConfig] = configFileName;
|
||||
ret[paramOverwriteProcessOnTarget] = !!parsedArgs[paramOverwriteProcessOnTarget];
|
||||
ret[paramSourceToken] = parsedArgs[paramSourceToken];
|
||||
ret[paramTargetToken] = parsedArgs[paramTargetToken];
|
||||
|
||||
return <ICommandLineOptions>ret;
|
||||
}
|
||||
|
||||
export async function ProcessConfigurationFile(configFilename: string, mode: Modes): Promise<IConfigurationFile> {
|
||||
export async function ProcessConfigurationFile(commandLineOptions: ICommandLineOptions): Promise<IConfigurationFile> {
|
||||
// Load configuration file
|
||||
if (!existsSync(configFilename)) {
|
||||
logger.logError(`Cannot find configuration file '${configFilename}'`);
|
||||
const configFile = commandLineOptions.config;
|
||||
if (!existsSync(configFile)) {
|
||||
logger.logError(`Cannot find configuration file '${configFile}'`);
|
||||
const normalizedConfiguraitonFilename = normalize(defaultConfigurationFilename);
|
||||
if (!existsSync(normalizedConfiguraitonFilename)) {
|
||||
writeFileSync(normalizedConfiguraitonFilename, defaultConfiguration);
|
||||
|
@ -59,8 +63,13 @@ export async function ProcessConfigurationFile(configFilename: string, mode: Mod
|
|||
process.exit(1);
|
||||
}
|
||||
|
||||
const configuration = jsoncParse(readFileSync(configFilename, defaultEncoding)) as IConfigurationFile;
|
||||
if (!Utility.validateConfiguration(configuration, mode)) {
|
||||
const configuration = jsoncParse(readFileSync(configFile, defaultEncoding)) as IConfigurationFile;
|
||||
|
||||
// replace token if overriden from command line
|
||||
configuration.sourceAccountToken = commandLineOptions.sourceToken ? commandLineOptions.sourceToken : configuration.sourceAccountToken;
|
||||
configuration.targetAccountToken = commandLineOptions.targetToken ? commandLineOptions.targetToken : configuration.targetAccountToken;
|
||||
|
||||
if (!Utility.validateConfiguration(configuration, commandLineOptions.mode)) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ import { logger } from "../common/Logger";
|
|||
import { InitializeFileLogger } from "./FileLogger";
|
||||
import { ProcessExporter } from "../common/ProcessExporter";
|
||||
import { ProcessImporter } from "../common/ProcessImporter";
|
||||
import { Utility } from "../common/Utilities";
|
||||
import { Engine } from "../common/Engine";
|
||||
import { NodeJsUtility } from "./NodeJsUtilities";
|
||||
|
||||
|
@ -20,7 +19,16 @@ async function main() {
|
|||
const commandLineOptions = ProcesCommandLine();
|
||||
|
||||
// Read configuration file
|
||||
const configuration = await ProcessConfigurationFile(commandLineOptions.config, commandLineOptions.mode)
|
||||
const configuration = await ProcessConfigurationFile(commandLineOptions)
|
||||
|
||||
// Overwrite token if specified on command line
|
||||
if (commandLineOptions.sourceToken) {
|
||||
configuration.sourceAccountToken = commandLineOptions.sourceToken;
|
||||
}
|
||||
|
||||
if (commandLineOptions.targetToken) {
|
||||
configuration.targetAccountToken = commandLineOptions.targetToken;
|
||||
}
|
||||
|
||||
// Initialize logger
|
||||
const maxLogLevel = configuration.options.logLevel ? LogLevel[configuration.options.logLevel] : LogLevel.information;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as vsts from "vso-node-api/WebApi";
|
||||
import * as vsts from "azure-devops-node-api/WebApi";
|
||||
import { existsSync, writeFileSync } from "fs";
|
||||
import { dirname, normalize } from "path";
|
||||
import { sync as mkdirpSync } from "mkdirp";
|
||||
|
|
Загрузка…
Ссылка в новой задаче