diff --git a/docs/howto/skills/botskills.md b/docs/howto/skills/botskills.md index 730b3b986e..96f2e6cba2 100644 --- a/docs/howto/skills/botskills.md +++ b/docs/howto/skills/botskills.md @@ -24,6 +24,7 @@ The CLI performs the following operations on your behalf: > Your Virtual Assistant must have been deployed using the [deployment tutorial](/docs/tutorials/assistantandskilldeploymentsteps.md) before using the `botskills` CLI as it relies on the Dispatch models being available and a deployed Bot for authentication connection information. ## Prerequisites +- Install the [Azure Command Line Tools (CLI)](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli-windows?view=azure-cli-latest) - [Node.js](https://nodejs.org/) version 10.8 or higher - Install the Dispatch, LUDown and LUISGen CLI tools diff --git a/tools/botskills/src/utils/authenticationUtils.ts b/tools/botskills/src/utils/authenticationUtils.ts index 6124a43cc4..366211ef44 100644 --- a/tools/botskills/src/utils/authenticationUtils.ts +++ b/tools/botskills/src/utils/authenticationUtils.ts @@ -14,7 +14,7 @@ import { IOauthConnection, IScopeManifest, ISkillManifest } from '../models'; -import { ChildProcessUtils } from './'; +import { ChildProcessUtils, isValidAzVersion } from './'; export class AuthenticationUtils { public childProcessUtils: ChildProcessUtils; @@ -95,6 +95,13 @@ export class AuthenticationUtils { }]; } + private async validateAzVersion(logger: ILogger): Promise { + // Validating the version of az that the user has (due to preview tag issue) + if (await isValidAzVersion()) { + logger.warning(`This az version may contain issues during the execution of internal az commands`); + } + } + // tslint:disable-next-line:max-func-body-length export-name public async authenticate(configuration: IConnectConfiguration, manifest: ISkillManifest, logger: ILogger): Promise { let currentCommand: string[] = []; @@ -105,6 +112,7 @@ export class AuthenticationUtils { const aadConfig: IAuthenticationConnection | undefined = manifest.authenticationConnections.find( (connection: IAuthenticationConnection) => connection.serviceProviderId === 'Azure Active Directory v2'); if (aadConfig) { + this.validateAzVersion(logger); logger.message('Configuring Azure AD connection ...'); let connectionName: string = aadConfig.id; diff --git a/tools/botskills/src/utils/azUtils.ts b/tools/botskills/src/utils/azUtils.ts new file mode 100644 index 0000000000..fbac48c219 --- /dev/null +++ b/tools/botskills/src/utils/azUtils.ts @@ -0,0 +1,38 @@ +/** + * Copyright(c) Microsoft Corporation.All rights reserved. + * Licensed under the MIT License. + */ + +import { gte } from 'semver'; +import { ChildProcessUtils } from './childProcessUtils'; + +const azPreviewMessage: string = `Command group 'bot' is in preview. It may be changed/removed in a future release.\r\n`; + +/** + * @returns Returns if it is a preview message (az version greater than 2.0.66) + */ +export function isAzPreviewMessage(message: string): boolean { + return message === azPreviewMessage; +} + +/** + * @returns Returns if it is a valid azure-cli version (lower than 2.0.66) + */ +const childProcess: ChildProcessUtils = new ChildProcessUtils(); +// tslint:disable-next-line:export-name +export async function isValidAzVersion(): Promise { + const azVersionCommand: string[] = ['az', '--version']; + const azVersion: string = await childProcess.tryExecute(azVersionCommand); + const azVersionArr: string | undefined = azVersion.split('\r\n') + .find((val: string) => { + return val.includes('azure-cli'); + }); + if (azVersionArr) { + const azVersionNum: string = azVersionArr.split(' ') + .filter((elem: string) => elem)[1]; + + return gte(azVersionNum, '2.0.67'); + } + + return false; +} diff --git a/tools/botskills/src/utils/childProcessUtils.ts b/tools/botskills/src/utils/childProcessUtils.ts index 2c2569e34a..992fb2f97c 100644 --- a/tools/botskills/src/utils/childProcessUtils.ts +++ b/tools/botskills/src/utils/childProcessUtils.ts @@ -5,6 +5,7 @@ import * as child_process from 'child_process'; import { join } from 'path'; +import { isAzPreviewMessage } from './'; export class ChildProcessUtils { @@ -48,7 +49,7 @@ export class ChildProcessUtils { child_process.exec( `${command.join(' ')}`, (err: child_process.ExecException | null, stdout: string, stderr: string) => { - if (stderr) { + if (stderr && !isAzPreviewMessage(stderr)) { pReject(stderr); } pResolve(stdout); diff --git a/tools/botskills/src/utils/index.ts b/tools/botskills/src/utils/index.ts index 50626aae73..bbd3e5743a 100644 --- a/tools/botskills/src/utils/index.ts +++ b/tools/botskills/src/utils/index.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. */ +export { isAzPreviewMessage, isValidAzVersion } from './azUtils'; export { ChildProcessUtils } from './childProcessUtils'; export { AuthenticationUtils } from './authenticationUtils'; export { sanitizePath, wrapPathWithQuotes } from './sanitizationUtils'; diff --git a/tools/botskills/test/authentication.test.js b/tools/botskills/test/authentication.test.js index 594992f8d4..dd5ce48290 100644 --- a/tools/botskills/test/authentication.test.js +++ b/tools/botskills/test/authentication.test.js @@ -129,6 +129,7 @@ https://github.com/microsoft/botframework-solutions/blob/master/docs/howto/assis logger: new TestLogger() }; + sandbox.replace(authenticationUtils, "validateAzVersion", (logger) => {}); // Mock the execution of az bot authsetting list (listAuthSettingsCommand) this.callback.onCall(0).returns(Promise.resolve(emptyAzureAuthSettings)); // Mock the execution of az ad app show (azureAppShowCommand)