Skip to content

Add DTS deploy activity log integration #4574

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 61 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
f858697
Add new storage type pick and host/local settings logic
MicroFish91 May 27, 2025
c84b288
Update host.json preview dep
MicroFish91 May 27, 2025
eb005a9
Install deps
MicroFish91 May 27, 2025
cbe1707
Update extension bundle
MicroFish91 May 27, 2025
4cb51ba
Update durable detection logic
MicroFish91 May 27, 2025
5d5e2dd
Remove extra prop
MicroFish91 May 29, 2025
8cb081c
Add .NET deps
MicroFish91 May 30, 2025
ffb7b43
Fix accidental change
MicroFish91 May 30, 2025
bd1c815
Revert todo
MicroFish91 May 30, 2025
d89c079
Add todo
MicroFish91 May 30, 2025
e201fe5
Update comment
MicroFish91 May 30, 2025
dece3e9
Update comment
MicroFish91 Jun 5, 2025
0e94b73
Fully working implementation
MicroFish91 Jun 10, 2025
e43c2aa
Update comment
MicroFish91 Jun 11, 2025
e96ceb9
Update comment again
MicroFish91 Jun 11, 2025
0529729
Formatting
MicroFish91 Jun 11, 2025
96eae40
Make storage connection type reuse logic more simple
MicroFish91 Jun 11, 2025
98dc295
Merge with main
MicroFish91 Jun 11, 2025
3a3512d
Merge branch 'main' of https://github.com/microsoft/vscode-azurefunct…
MicroFish91 Jun 12, 2025
612ec9c
Update connection types
MicroFish91 Jun 12, 2025
c676ce9
Revert autoformatting change
MicroFish91 Jun 12, 2025
2537cc2
Revert more autoformatting
MicroFish91 Jun 12, 2025
0da96c1
Add dts connection validation for azure deployment
MicroFish91 Jun 13, 2025
616f84b
Remove extra step
MicroFish91 Jun 13, 2025
a0f194b
Don't need to update this file
MicroFish91 Jun 13, 2025
5dfb869
Standardize name casing
MicroFish91 Jun 13, 2025
be7032e
Unexpected code path
MicroFish91 Jun 14, 2025
4284d23
Misc
MicroFish91 Jun 14, 2025
6d19b79
Fix some stuff, add location + todo
MicroFish91 Jun 14, 2025
34258ac
Misc
MicroFish91 Jun 16, 2025
7ba0ef6
WIP
MicroFish91 Jun 17, 2025
b9d4583
WIP
MicroFish91 Jun 21, 2025
414576e
Entire flow is working
MicroFish91 Jun 23, 2025
9a090e4
Add validation notes
MicroFish91 Jun 23, 2025
9942756
Rename step
MicroFish91 Jun 23, 2025
7282e90
Update validation logic for name availability
MicroFish91 Jun 23, 2025
b56e20a
Address todo
MicroFish91 Jun 23, 2025
9c96414
Update location logic
MicroFish91 Jun 23, 2025
71f11b7
Remove comment
MicroFish91 Jun 23, 2025
55169b8
Update location logic
MicroFish91 Jun 23, 2025
c73c58e
Add comment to validateDTSConnection
MicroFish91 Jun 24, 2025
8173f6a
Update comment
MicroFish91 Jun 24, 2025
1e34b0b
Revert deps
MicroFish91 Jun 25, 2025
4828629
Upgrade azure utils
MicroFish91 Jun 25, 2025
9cff4b3
Merge branch 'main' of https://github.com/microsoft/vscode-azurefunct…
MicroFish91 Jun 25, 2025
5f299ae
Merge with main
MicroFish91 Jun 26, 2025
08ff543
Revert accidental autoformatting
MicroFish91 Jun 26, 2025
6829729
Improve comment
MicroFish91 Jun 26, 2025
6874d6d
Update comment
MicroFish91 Jun 26, 2025
1f3810c
Add activity log integration
MicroFish91 Jun 26, 2025
181e7bc
Update title
MicroFish91 Jun 27, 2025
f2cd1a4
Improve activity log info items
MicroFish91 Jun 27, 2025
b594736
Update wizard title
MicroFish91 Jun 27, 2025
e83b450
Merge branch 'main' of https://github.com/microsoft/vscode-azurefunct…
MicroFish91 Jul 14, 2025
2691c1d
Update connection prompts
MicroFish91 Jul 14, 2025
ad25e4f
Add emulator started message
MicroFish91 Jul 14, 2025
cd67792
Merge with mwf/convinced-gray
MicroFish91 Jul 14, 2025
0c5afcd
Merge branch 'mwf/deploy-dts' of https://github.com/microsoft/vscode-…
MicroFish91 Jul 14, 2025
a1e2798
Merge with main
MicroFish91 Jul 15, 2025
59186c4
Re-upgrade package
MicroFish91 Jul 15, 2025
e03fe11
Fix merge
MicroFish91 Jul 15, 2025
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 package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1484,7 +1484,7 @@
"@microsoft/vscode-azext-azureappservice": "^3.6.4",
"@microsoft/vscode-azext-azureappsettings": "^0.2.8",
"@microsoft/vscode-azext-azureutils": "^3.4.0",
"@microsoft/vscode-azext-utils": "^3.1.1",
"@microsoft/vscode-azext-utils": "^3.2.0",
"@microsoft/vscode-azureresources-api": "^2.0.4",
"@microsoft/vscode-container-client": "^0.1.2",
"cross-fetch": "^4.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { nonNullProp } from '@microsoft/vscode-azext-utils';
import { ActivityChildItem, ActivityChildType, activityFailContext, activityFailIcon, activityProgressContext, activityProgressIcon, activitySuccessContext, activitySuccessIcon, createContextValue, nonNullProp, type ExecuteActivityOutput } from '@microsoft/vscode-azext-utils';
import { ConnectionKey } from '../../../../constants';
import { localize } from '../../../../localize';
import { clientIdKey } from '../../../durableTaskScheduler/copySchedulerConnectionString';
import { SetConnectionSettingStepBase } from '../SetConnectionSettingStepBase';
import { type IDTSAzureConnectionWizardContext, type IDTSConnectionWizardContext } from './IDTSConnectionWizardContext';

export class DTSConnectionSetSettingStep<T extends IDTSConnectionWizardContext | IDTSAzureConnectionWizardContext> extends SetConnectionSettingStepBase<T> {
public priority: number = 240;
public stepName: string = 'dtsConnectionSetSettingStep';
public debugDeploySetting: ConnectionKey = ConnectionKey.DTS;

public async execute(context: T): Promise<void> {
Expand All @@ -24,4 +26,39 @@ export class DTSConnectionSetSettingStep<T extends IDTSConnectionWizardContext |
public shouldExecute(context: T): boolean {
return !!context.newDTSConnectionSetting;
}

public createSuccessOutput(context: T): ExecuteActivityOutput {
return {
item: new ActivityChildItem({
label: localize('prepareDTSConnectionProgressLabel', 'Prepare DTS connection: "{0}"', 'Endpoint=...'),
contextValue: createContextValue([`${this.stepName}Item`, activitySuccessContext]),
activityType: ActivityChildType.Success,
iconPath: activitySuccessIcon,
}),
message: localize('prepareDTSConnectionSuccess', 'Successfully prepared DTS connection: "{0}".', context.newDTSConnectionSetting),
};
}

public createProgressOutput(): ExecuteActivityOutput {
return {
item: new ActivityChildItem({
label: localize('prepareDTSConnectionProgressLabel', 'Prepare DTS connection: "{0}"', 'Endpoint=...'),
contextValue: createContextValue([`${this.stepName}Item`, activityProgressContext]),
activityType: ActivityChildType.Progress,
iconPath: activityProgressIcon,
}),
};
}

public createFailOutput(context: T): ExecuteActivityOutput {
return {
item: new ActivityChildItem({
label: localize('prepareDTSConnectionProgressLabel', 'Prepare DTS connection: "{0}"', 'Endpoint=...'),
contextValue: createContextValue([`${this.stepName}Item`, activityFailContext]),
activityType: ActivityChildType.Fail,
iconPath: activityFailIcon,
}),
message: localize('prepareDTSConnectionFail', 'Failed to prepare DTS connection: "{0}".', context.newDTSConnectionSetting),
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { nonNullProp } from '@microsoft/vscode-azext-utils';
import { ActivityChildItem, ActivityChildType, activityFailIcon, activityProgressContext, activityProgressIcon, activitySuccessContext, activitySuccessIcon, createContextValue, nonNullProp, type ExecuteActivityOutput } from '@microsoft/vscode-azext-utils';
import { ConnectionKey } from '../../../../constants';
import { localize } from '../../../../localize';
import { SetConnectionSettingStepBase } from '../SetConnectionSettingStepBase';
import { type IDTSConnectionWizardContext } from './IDTSConnectionWizardContext';

export class DTSHubNameSetSettingStep<T extends IDTSConnectionWizardContext> extends SetConnectionSettingStepBase<T> {
public priority: number = 241;
public stepName: string = 'dtsHubNameSetSettingStep';
public debugDeploySetting: ConnectionKey = ConnectionKey.DTSHub;

public async execute(context: T): Promise<void> {
Expand All @@ -19,4 +21,39 @@ export class DTSHubNameSetSettingStep<T extends IDTSConnectionWizardContext> ext
public shouldExecute(context: T): boolean {
return !!context.newDTSHubNameConnectionSetting;
}

public createSuccessOutput(context: T): ExecuteActivityOutput {
return {
item: new ActivityChildItem({
label: localize('prepareDTSHubNameLabel', 'Prepare DTS hub connection: "{0}"', context.newDTSHubNameConnectionSetting),
contextValue: createContextValue([`${this.stepName}Item`, activitySuccessContext]),
activityType: ActivityChildType.Success,
iconPath: activitySuccessIcon,
}),
message: localize('prepareDTSHubNameSuccess', 'Successfully prepared DTS hub connection: "{0}".', context.newDTSConnectionSetting),
};
}

public createProgressOutput(): ExecuteActivityOutput {
return {
item: new ActivityChildItem({
label: localize('prepareDTSHubNameProgressLabel', 'Prepare DTS hub connection: "..."'),
contextValue: createContextValue([`${this.stepName}Item`, activityProgressContext]),
activityType: ActivityChildType.Progress,
iconPath: activityProgressIcon,
}),
};
}

public createFailOutput(context: T): ExecuteActivityOutput {
return {
item: new ActivityChildItem({
label: localize('prepareDTSHubNameLabel', 'Prepare DTS hub connection: "{0}"', context.newDTSHubNameConnectionSetting),
contextValue: createContextValue([`${this.stepName}Item`, activitySuccessContext]),
activityType: ActivityChildType.Fail,
iconPath: activityFailIcon,
}),
message: localize('prepareDTSHubNameFail', 'Failed to prepare DTS hub connection: "{0}".', context.newDTSConnectionSetting),
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { type IActionContext } from "@microsoft/vscode-azext-utils";
import { type ExecuteActivityContext, type IActionContext } from "@microsoft/vscode-azext-utils";
import { type AzureSubscription } from "@microsoft/vscode-azureresources-api";
import { type ConnectionType } from "../../../../constants";
import { type DurableTaskHubResource, type DurableTaskSchedulerResource } from "../../../../tree/durableTaskScheduler/DurableTaskSchedulerClient";
Expand All @@ -20,7 +20,7 @@ export interface IDTSConnectionWizardContext extends IActionContext, ISetConnect
newDTSHubNameConnectionSetting?: string;
}

export interface IDTSAzureConnectionWizardContext extends IFunctionAppUserAssignedIdentitiesContext, IDTSConnectionWizardContext {
export interface IDTSAzureConnectionWizardContext extends IFunctionAppUserAssignedIdentitiesContext, IDTSConnectionWizardContext, Partial<ExecuteActivityContext> {
subscription?: AzureSubscription;

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { ActivityChildItem, ActivityChildType, activityInfoContext, activityInfoIcon, AzureWizardPromptStep, createContextValue, prependOrInsertAfterLastInfoChild, type ActivityInfoChild } from "@microsoft/vscode-azext-utils";
import { ext } from "../../../../../extensionVariables";
import { localize } from "../../../../../localize";
import { type IDTSAzureConnectionWizardContext } from "../IDTSConnectionWizardContext";

const startingResourcesContext: string = 'startingResourcesLogStepItem';

export class DTSStartingResourcesLogStep<T extends IDTSAzureConnectionWizardContext> extends AzureWizardPromptStep<T> {
public hideStepCount: boolean = true;
protected hasLogged: boolean = false;

public async configureBeforePrompt(context: T): Promise<void> {
if (this.hasLogged) {
return;
}

if (context.resourceGroup) {
prependOrInsertAfterLastInfoChild(context,
new ActivityChildItem({
contextValue: createContextValue([startingResourcesContext, activityInfoContext]),
label: localize('useResourceGroup', 'Use resource group "{0}"', context.resourceGroup.name),
activityType: ActivityChildType.Info,
iconPath: activityInfoIcon
}) as ActivityInfoChild
);
ext.outputChannel.appendLog(localize('usingResourceGroup', 'Using resource group "{0}".', context.resourceGroup.name));
}

if (context.site) {
prependOrInsertAfterLastInfoChild(context,
new ActivityChildItem({
label: localize('useFunctionApp', 'Use function app "{0}"', context.site.fullName),
contextValue: createContextValue([startingResourcesContext, activityInfoContext]),
activityType: ActivityChildType.Info,
iconPath: activityInfoIcon,
}) as ActivityInfoChild,
);
ext.outputChannel.appendLog(localize('usingFunctionApp', 'Using function app "{0}".', context.site.fullName));
}

if (context.dts) {
prependOrInsertAfterLastInfoChild(context,
new ActivityChildItem({
label: localize('useDTS', 'Use durable task scheduler "{0}"', context.dts.name),
contextValue: createContextValue([startingResourcesContext, activityInfoContext]),
activityType: ActivityChildType.Info,
iconPath: activityInfoIcon
}) as ActivityInfoChild,
);
ext.outputChannel.appendLog(localize('usingDTS', 'Using durable task scheduler "{0}".', context.dts.name));
}

if (context.dtsHub) {
prependOrInsertAfterLastInfoChild(context,
new ActivityChildItem({
label: localize('useDTSHub', 'Use durable task hub "{0}"', context.dtsHub.name),
contextValue: createContextValue([startingResourcesContext, activityInfoContext]),
activityType: ActivityChildType.Info,
iconPath: activityInfoIcon,
}) as ActivityInfoChild,
);
ext.outputChannel.appendLog(localize('usingDTSHub', 'Using durable task hub "{0}".', context.dtsHub.name));
}

ext.outputChannel.appendLog(localize('prioritizingSiteLocation', 'Prioritizing site location: "{0}".', context.site?.location));
this.hasLogged = true;
}

public async prompt(): Promise<void> {
// Don't prompt, just use to log starting resources
}

public shouldPrompt(): boolean {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,31 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { AzureWizardExecuteStep, nonNullProp, nonNullValueAndProp } from "@microsoft/vscode-azext-utils";
import { AzureWizardExecuteStepWithActivityOutput, nonNullProp, nonNullValueAndProp } from "@microsoft/vscode-azext-utils";
import { type Progress } from "vscode";
import { localize } from "../../../../../localize";
import { HttpDurableTaskSchedulerClient, type DurableTaskSchedulerClient } from "../../../../../tree/durableTaskScheduler/DurableTaskSchedulerClient";
import { type IDTSAzureConnectionWizardContext } from "../IDTSConnectionWizardContext";

export class DurableTaskHubCreateStep<T extends IDTSAzureConnectionWizardContext> extends AzureWizardExecuteStep<T> {
priority: number = 160;
private readonly schedulerClient: DurableTaskSchedulerClient;
export class DurableTaskHubCreateStep<T extends IDTSAzureConnectionWizardContext> extends AzureWizardExecuteStepWithActivityOutput<T> {
public priority: number = 160;
public stepName: string = 'durableTaskHubCreateStep';

protected getOutputLogSuccess = (context: T) => localize('createTaskHubSuccess', 'Created durable task hub "{0}"', context.dtsHub?.name);
protected getOutputLogFail = (context: T) => localize('createTaskHubFail', 'Failed to create durable task hub "{0}"', context.newDTSHubName);
protected getTreeItemLabel = (context: T) => localize('createTaskHubLabel', 'Create durable task hub "{0}"', context.newDTSHubName);

private readonly _schedulerClient: DurableTaskSchedulerClient;

constructor(schedulerClient?: DurableTaskSchedulerClient) {
super();
this.schedulerClient = schedulerClient ?? new HttpDurableTaskSchedulerClient();
this._schedulerClient = schedulerClient ?? new HttpDurableTaskSchedulerClient();
}

public async execute(context: T, progress: Progress<{ message?: string; increment?: number; }>): Promise<void> {
progress.report({ message: localize('createTaskHub', 'Creating durable task hub...') });

context.dtsHub = await this.schedulerClient.createTaskHub(
context.dtsHub = await this._schedulerClient.createTaskHub(
nonNullProp(context, 'subscription'),
nonNullValueAndProp(context.resourceGroup, 'name'),
nonNullValueAndProp(context.dts, 'name'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,33 @@
*--------------------------------------------------------------------------------------------*/

import { LocationListStep } from "@microsoft/vscode-azext-azureutils";
import { AzureWizardExecuteStep, nonNullProp, nonNullValueAndProp } from "@microsoft/vscode-azext-utils";
import { ActivityChildItem, ActivityChildType, activityProgressContext, activityProgressIcon, AzureWizardExecuteStepWithActivityOutput, createContextValue, nonNullProp, nonNullValueAndProp, type ExecuteActivityOutput } from "@microsoft/vscode-azext-utils";
import { type Progress } from "vscode";
import { localize } from "../../../../../localize";
import { HttpDurableTaskSchedulerClient, type DurableTaskSchedulerClient } from "../../../../../tree/durableTaskScheduler/DurableTaskSchedulerClient";
import { withCancellation } from "../../../../../utils/cancellation";
import { getSchedulerConnectionString, SchedulerAuthenticationType } from "../../../../durableTaskScheduler/copySchedulerConnectionString";
import { type IDTSAzureConnectionWizardContext } from "../IDTSConnectionWizardContext";

export class DurableTaskSchedulerCreateStep<T extends IDTSAzureConnectionWizardContext> extends AzureWizardExecuteStep<T> {
priority: number = 150;
private readonly schedulerClient: DurableTaskSchedulerClient;
export class DurableTaskSchedulerCreateStep<T extends IDTSAzureConnectionWizardContext> extends AzureWizardExecuteStepWithActivityOutput<T> {
public priority: number = 150;
public stepName: string = 'durableTaskSchedulerCreateStep';

protected getOutputLogSuccess = (context: T) => localize('createTaskSchedulerSuccess', 'Created durable task scheduler "{0}"', context.dts?.name);
protected getOutputLogFail = (context: T) => localize('createTaskSchedulerFail', 'Failed to create durable task scheduler "{0}"', context.newDTSName);
protected getTreeItemLabel = (context: T) => localize('createTaskSchedulerLabel', 'Create durable task scheduler "{0}"', context.newDTSName);

private readonly _schedulerClient: DurableTaskSchedulerClient;

public constructor(schedulerClient?: DurableTaskSchedulerClient) {
super();
this.schedulerClient = schedulerClient ?? new HttpDurableTaskSchedulerClient();
this._schedulerClient = schedulerClient ?? new HttpDurableTaskSchedulerClient();
}

public async execute(context: T, progress: Progress<{ message?: string; increment?: number; }>): Promise<void> {
progress.report({ message: localize('createTaskScheduler', 'Creating durable task scheduler...') });

const response = (await this.schedulerClient.createScheduler(
const response = (await this._schedulerClient.createScheduler(
nonNullProp(context, 'subscription'),
nonNullValueAndProp(context.resourceGroup, 'name'),
(await LocationListStep.getLocation(context)).name,
Expand All @@ -44,4 +50,16 @@ export class DurableTaskSchedulerCreateStep<T extends IDTSAzureConnectionWizardC
public shouldExecute(context: T): boolean {
return !context.dts;
}

public createProgressOutput(context: T): ExecuteActivityOutput {
return {
item: new ActivityChildItem({
label: this.getTreeItemLabel(context),
description: localize('dtsCreateWarning', 'This could take a while...'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haha, sounds a little casual (and ominous) to me.
"Resource provisioning is in progress. This operation may take several minutes to complete."

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's pretty ominous, it took almost 30 min for me once 🙃

contextValue: createContextValue([`${this.stepName}Item`, activityProgressContext]),
activityType: ActivityChildType.Progress,
iconPath: activityProgressIcon,
}),
};
}
}
Loading