Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion extensions/azurePublish/src/botProjectDeployConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export interface BotProjectDeployConfig {
projPath: string;

// Logger
logger: (string) => any;
logger: (...args: any[]) => void;

// Deploy file path, default is .deployment file
deployFilePath?: string;
Expand Down
12 changes: 10 additions & 2 deletions extensions/azurePublish/src/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export class BotProjectDeploy {
private accessToken: string;
private projPath: string;
private zipPath: string;
private logger: (string) => any;
private logger: (...args: any[]) => void;
private runtime: any;

constructor(config: BotProjectDeployConfig) {
Expand Down Expand Up @@ -149,19 +149,27 @@ export class BotProjectDeploy {
const publishEndpoint = `https://${
hostname ? hostname : name + '-' + env
}.scm.azurewebsites.net/zipdeploy/?isAsync=true`;
const fileReadStream = fs.createReadStream(zipPath, { autoClose: true });
fileReadStream.on('error', function (err) {
this.logger('%O', err);
throw err;
});

try {
const response = await rp.post({
uri: publishEndpoint,
auth: {
bearer: token,
},
body: fs.createReadStream(zipPath),
body: fileReadStream,
});
this.logger({
status: BotProjectDeployLoggerType.DEPLOY_INFO,
message: response,
});
} catch (err) {
// close file read stream
fileReadStream.close();
if (err.statusCode === 403) {
throw new Error(
`Token expired, please run az account get-access-token, then replace the accessToken in your configuration`
Expand Down
101 changes: 63 additions & 38 deletions extensions/azurePublish/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,13 @@ export default async (composer: ExtensionRegistration): Promise<void> => {
* @param resourcekey
*/
private async cleanup(resourcekey: string) {
const projFolder = this.getRuntimeFolder(resourcekey);
await emptyDir(projFolder);
await rmdir(projFolder);
try {
const projFolder = this.getRuntimeFolder(resourcekey);
await emptyDir(projFolder);
await rmdir(projFolder);
} catch (error) {
this.logger('$O', error);
}
}

/**
Expand Down Expand Up @@ -196,15 +200,17 @@ export default async (composer: ExtensionRegistration): Promise<void> => {
// Create the BotProjectDeploy object, which is used to carry out the deploy action.
const azDeployer = new BotProjectDeploy({
subId: subscriptionID, // deprecate - not used
logger: (msg: any) => {
this.logger(msg);
this.logMessages.push(JSON.stringify(msg, null, 2));
logger: (msg: any, ...args: any[]) => {
this.logger(msg, ...args);
if (msg?.status || msg?.message) {
this.logMessages.push(JSON.stringify(msg, null, 2));

// update the log messages provided to Composer via the status API.
const status = this.getLoadingStatus(botId, profileName, jobId);
status.result.log = this.logMessages.join('\n');
// update the log messages provided to Composer via the status API.
const status = this.getLoadingStatus(botId, profileName, jobId);
status.result.log = this.logMessages.join('\n');

this.updateLoadingStatus(botId, profileName, jobId, status);
this.updateLoadingStatus(botId, profileName, jobId, status);
}
},
accessToken: accessToken,
projPath: this.getProjectFolder(resourcekey, this.mode),
Expand All @@ -226,7 +232,7 @@ export default async (composer: ExtensionRegistration): Promise<void> => {
await this.cleanup(resourcekey);
}
} catch (error) {
this.logger(error);
this.logger('%O', error);
if (error instanceof Error) {
this.logMessages.push(error.message);
} else if (typeof error === 'object') {
Expand Down Expand Up @@ -334,34 +340,53 @@ export default async (composer: ExtensionRegistration): Promise<void> => {
runtimeCodePath = project.settings.runtime.path;
}

// Prepare the temporary project
// this writes all the settings to the root settings/appsettings.json file
await this.init(project, runtimeCodePath, resourcekey, runtime);
try {
// Prepare the temporary project
// this writes all the settings to the root settings/appsettings.json file
await this.init(project, runtimeCodePath, resourcekey, runtime);

// Merge all the settings
// this combines the bot-wide settings, the environment specific settings, and 2 new fields needed for deployed bots
// these will be written to the appropriate settings file inside the appropriate runtime plugin.
const mergedSettings = mergeDeep(fullSettings, settings);

// Prepare parameters and then perform the actual deployment action
const customizeConfiguration: CreateAndDeployResources = {
accessToken,
subscriptionID,
name,
environment,
hostname,
luisResource,
};
await this.performDeploymentAction(
project,
mergedSettings,
runtime,
project.id,
profileName,
jobId,
resourcekey,
customizeConfiguration
);
} catch (err) {
this.logger('%O', err);
if (err instanceof Error) {
this.logMessages.push(err.message);
} else if (typeof err === 'object') {
this.logMessages.push(JSON.stringify(err));
} else {
this.logMessages.push(err);
}

// Merge all the settings
// this combines the bot-wide settings, the environment specific settings, and 2 new fields needed for deployed bots
// these will be written to the appropriate settings file inside the appropriate runtime plugin.
const mergedSettings = mergeDeep(fullSettings, settings);
const response = this.getLoadingStatus(project.id, profileName, jobId);
response.status = 500;
response.result.message = this.logMessages[this.logMessages.length - 1];

// Prepare parameters and then perform the actual deployment action
const customizeConfiguration: CreateAndDeployResources = {
accessToken,
subscriptionID,
name,
environment,
hostname,
luisResource,
};
await this.performDeploymentAction(
project,
mergedSettings,
runtime,
project.id,
profileName,
jobId,
resourcekey,
customizeConfiguration
);
await this.updateHistory(project.id, profileName, { status: response.status, ...response.result });
this.removeLoadingStatus(project.id, profileName, jobId);
this.cleanup(resourcekey);
}
};

/**************************************************************************************************
Expand Down Expand Up @@ -414,7 +439,7 @@ export default async (composer: ExtensionRegistration): Promise<void> => {

this.asyncPublish(config, project, resourcekey, jobId);
} catch (err) {
console.log(err);
this.logger('%O', err);
if (err instanceof Error) {
this.logMessages.push(err.message);
} else if (typeof err === 'object') {
Expand Down
2 changes: 1 addition & 1 deletion extensions/azurePublish/src/luisAndQnA.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { ILuisConfig, FileInfo, IQnAConfig } from '@botframework-composer/types'

import { ICrossTrainConfig, createCrossTrainConfig } from './utils/crossTrainUtil';
import { BotProjectDeployLoggerType } from './botProjectLoggerType';
import { luImportResolverGenerator } from '@bfc/shared/lib/luBuildResolver'
import { luImportResolverGenerator } from '@bfc/shared/lib/luBuildResolver';

const crossTrainer = require('@microsoft/bf-lu/lib/parser/cross-train/crossTrainer.js');
const luBuild = require('@microsoft/bf-lu/lib/parser/lubuild/builder.js');
Expand Down
3 changes: 2 additions & 1 deletion extensions/azurePublish/src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ const schema: JSONSchema7 = {
},
runtimeIdentifier: {
type: 'string',
title: 'Runtime identifier for hosting bot, default to win-x64, please refer to https://docs.microsoft.com/en-us/dotnet/core/rid-catalog'
title:
'Runtime identifier for hosting bot, default to win-x64, please refer to https://docs.microsoft.com/en-us/dotnet/core/rid-catalog',
},
settings: {
type: 'object',
Expand Down