Skip to content

Commit a58a82c

Browse files
authored
Add an API entry-point to the deployWorkspaceProject command (#578)
1 parent 3270794 commit a58a82c

20 files changed

+248
-63
lines changed

package-lock.json

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,11 @@
9595
"title": "%containerApps.deployWorkspaceProject%",
9696
"category": "Azure Container Apps"
9797
},
98+
{
99+
"command": "containerApps.deployWorkspaceProjectApi",
100+
"title": "%containerApps.deployWorkspaceProjectApi%",
101+
"category": "Azure Container Apps"
102+
},
98103
{
99104
"command": "containerApps.deployWorkspaceProjectToContainerApp",
100105
"title": "%containerApps.deployWorkspaceProjectToContainerApp%",
@@ -503,6 +508,10 @@
503508
"command": "containerApps.deployWorkspaceProjectToContainerApp",
504509
"when": "never"
505510
},
511+
{
512+
"command": "containerApps.deployWorkspaceProjectApi",
513+
"when": "never"
514+
},
506515
{
507516
"command": "containerApps.deployImageApi",
508517
"when": "never"
@@ -621,7 +630,7 @@
621630
"@azure/container-registry": "1.0.0-beta.5",
622631
"@azure/core-rest-pipeline": "1.10.3",
623632
"@azure/storage-blob": "^12.4.1",
624-
"@microsoft/vscode-azext-azureutils": "^2.0.0",
633+
"@microsoft/vscode-azext-azureutils": "^2.0.3",
625634
"@microsoft/vscode-azext-github": "^1.0.0",
626635
"@microsoft/vscode-azext-utils": "^2.1.5",
627636
"@microsoft/vscode-azureresources-api": "^2.0.2",

package.nls.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"containerApps.updateImage": "Update Container Image...",
1313
"containerApps.deployImageApi": "Deploy Image to Container App (API)...",
1414
"containerApps.deployWorkspaceProject": "Deploy Project from Workspace...",
15+
"containerApps.deployWorkspaceProjectApi": "Deploy Project from Workspace (API)...",
1516
"containerApps.deployWorkspaceProjectToContainerApp": "Deploy Workspace to Container App...",
1617
"containerApps.deleteContainerApp": "Delete Container App...",
1718
"containerApps.disableIngress": "Disable Ingress for Container App",

src/commands/api/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Change Log
2+
3+
## 0.0.1
4+
* Initial release
5+
6+
### Added
7+
8+
* Added an API entry-point to the `deployWorkspaceProject` command [#578](https://github.com/microsoft/vscode-azurecontainerapps/pull/578)
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.md in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { type ResourceGroup } from "@azure/arm-resources";
7+
import { ResourceGroupListStep, parseAzureResourceGroupId } from "@microsoft/vscode-azext-azureutils";
8+
import { callWithTelemetryAndErrorHandling, createSubscriptionContext, subscriptionExperience, type IActionContext, type ISubscriptionActionContext, type ISubscriptionContext } from "@microsoft/vscode-azext-utils";
9+
import { type AzureSubscription } from "@microsoft/vscode-azureresources-api";
10+
import { Uri, type WorkspaceFolder } from "vscode";
11+
import { ext } from "../../extensionVariables";
12+
import { getWorkspaceFolderFromPath } from "../../utils/workspaceUtils";
13+
import { deployWorkspaceProjectInternal, type DeployWorkspaceProjectInternalContext } from "../deployWorkspaceProject/deployWorkspaceProjectInternal";
14+
import { getDeployWorkspaceProjectResults, type DeployWorkspaceProjectResults } from "../deployWorkspaceProject/getDeployWorkspaceProjectResults";
15+
import type * as api from "./vscode-azurecontainerapps.api";
16+
17+
export async function deployWorkspaceProjectApi(deployWorkspaceProjectOptions: api.DeployWorkspaceProjectOptionsContract): Promise<DeployWorkspaceProjectResults> {
18+
return await callWithTelemetryAndErrorHandling('containerApps.api.deployWorkspaceProject', async (context: IActionContext): Promise<DeployWorkspaceProjectResults> => {
19+
const { resourceGroupId, rootPath, dockerfilePath, srcPath, suppressConfirmation, suppressContainerAppCreation, ignoreExistingDeploySettings, shouldSaveDeploySettings } = deployWorkspaceProjectOptions;
20+
21+
const subscription: AzureSubscription = await subscriptionExperience(context, ext.rgApiV2.resources.azureResourceTreeDataProvider, {
22+
selectBySubscriptionId: getSubscriptionIdFromOptions(deployWorkspaceProjectOptions),
23+
showLoadingPrompt: false
24+
});
25+
const subscriptionContext: ISubscriptionContext = createSubscriptionContext(subscription);
26+
27+
const rootFolder: WorkspaceFolder | undefined = rootPath ? getWorkspaceFolderFromPath(rootPath) : undefined;
28+
const resourceGroup: ResourceGroup | undefined = resourceGroupId ? await getResourceGroupFromId({ ...context, ...subscriptionContext }, resourceGroupId) : undefined;
29+
30+
const deployWorkspaceProjectInternalContext: DeployWorkspaceProjectInternalContext = Object.assign(context, {
31+
...subscriptionContext,
32+
subscription,
33+
resourceGroup,
34+
rootFolder,
35+
srcPath: srcPath ? Uri.file(srcPath).fsPath : undefined,
36+
dockerfilePath: dockerfilePath ? Uri.file(dockerfilePath).fsPath : undefined,
37+
ignoreExistingDeploySettings,
38+
shouldSaveDeploySettings: !!shouldSaveDeploySettings,
39+
});
40+
41+
const deployWorkspaceProjectResultContext = await deployWorkspaceProjectInternal(deployWorkspaceProjectInternalContext, undefined, {
42+
suppressActivity: true,
43+
suppressConfirmation,
44+
suppressContainerAppCreation,
45+
suppressProgress: true,
46+
suppressWizardTitle: true,
47+
});
48+
49+
return await getDeployWorkspaceProjectResults(deployWorkspaceProjectResultContext);
50+
}) ?? {};
51+
}
52+
53+
function getSubscriptionIdFromOptions(deployWorkspaceProjectOptions: api.DeployWorkspaceProjectOptionsContract): string | undefined {
54+
if (deployWorkspaceProjectOptions.subscriptionId) {
55+
return deployWorkspaceProjectOptions.subscriptionId;
56+
} else if (deployWorkspaceProjectOptions.resourceGroupId) {
57+
return parseAzureResourceGroupId(deployWorkspaceProjectOptions.resourceGroupId).subscriptionId as string;
58+
} else {
59+
return undefined;
60+
}
61+
}
62+
63+
async function getResourceGroupFromId(context: ISubscriptionActionContext, resourceGroupId: string): Promise<ResourceGroup | undefined> {
64+
const resourceGroups: ResourceGroup[] = await ResourceGroupListStep.getResourceGroups(context);
65+
return resourceGroups.find(rg => rg.id === resourceGroupId);
66+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.md in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { createApiProvider, type apiUtils } from "@microsoft/vscode-azext-utils";
7+
import { deployWorkspaceProjectApi } from "./deployWorkspaceProjectApi";
8+
import type * as api from "./vscode-azurecontainerapps.api";
9+
10+
export function getAzureContainerAppsApiProvider(): apiUtils.AzureExtensionApiProvider {
11+
return createApiProvider([<api.AzureContainerAppsExtensionApi>{
12+
apiVersion: '0.0.1',
13+
deployWorkspaceProject: deployWorkspaceProjectApi
14+
}]);
15+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
export interface AzureContainerAppsExtensionApi {
7+
apiVersion: string;
8+
deployWorkspaceProject(options: DeployWorkspaceProjectOptionsContract): Promise<DeployWorkspaceProjectResults>;
9+
}
10+
11+
export interface DeployWorkspaceProjectOptionsContract {
12+
// Existing resources
13+
subscriptionId?: string;
14+
resourceGroupId?: string;
15+
16+
// Workspace deployment paths (absolute fs path)
17+
rootPath?: string;
18+
srcPath?: string;
19+
dockerfilePath?: string;
20+
21+
// Options
22+
suppressConfirmation?: boolean; // Suppress any [resource] confirmation prompts
23+
suppressContainerAppCreation?: boolean;
24+
ignoreExistingDeploySettings?: boolean;
25+
shouldSaveDeploySettings?: boolean;
26+
}
27+
28+
export interface DeployWorkspaceProjectResults {
29+
resourceGroupId?: string;
30+
logAnalyticsWorkspaceId?: string;
31+
managedEnvironmentId?: string;
32+
containerAppId?: string;
33+
34+
// ACR
35+
registryId?: string;
36+
registryLoginServer?: string;
37+
registryUsername?: string;
38+
registryPassword?: string;
39+
imageName?: string;
40+
}

src/commands/deployWorkspaceProject/deployWorkspaceProject.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ import { type DeployWorkspaceProjectNotificationTelemetryProps as NotificationTe
1212
import { ContainerAppItem, isIngressEnabled, type ContainerAppModel } from "../../tree/ContainerAppItem";
1313
import { ManagedEnvironmentItem } from "../../tree/ManagedEnvironmentItem";
1414
import { localize } from "../../utils/localize";
15+
import { type DeployWorkspaceProjectResults } from "../api/vscode-azurecontainerapps.api";
1516
import { browseContainerApp } from "../browseContainerApp";
1617
import { type DeployWorkspaceProjectContext } from "./DeployWorkspaceProjectContext";
1718
import { deployWorkspaceProjectInternal, type DeployWorkspaceProjectInternalContext } from "./deployWorkspaceProjectInternal";
19+
import { getDeployWorkspaceProjectResults } from "./getDeployWorkspaceProjectResults";
1820

19-
export async function deployWorkspaceProject(context: IActionContext & Partial<DeployWorkspaceProjectContext>, item?: ContainerAppItem | ManagedEnvironmentItem): Promise<void> {
21+
export async function deployWorkspaceProject(context: IActionContext & Partial<DeployWorkspaceProjectContext>, item?: ContainerAppItem | ManagedEnvironmentItem): Promise<DeployWorkspaceProjectResults> {
2022
// If an incompatible tree item is passed, treat it as if no item was passed
2123
if (item && !ContainerAppItem.isContainerAppItem(item) && !ManagedEnvironmentItem.isManagedEnvironmentItem(item)) {
2224
item = undefined;
@@ -39,6 +41,7 @@ export async function deployWorkspaceProject(context: IActionContext & Partial<D
3941
});
4042

4143
displayNotification(deployWorkspaceProjectResultContext);
44+
return await getDeployWorkspaceProjectResults(deployWorkspaceProjectResultContext);
4245
}
4346

4447
function displayNotification(context: DeployWorkspaceProjectContext): void {

src/commands/deployWorkspaceProject/getDefaultValues/DefaultResourcesNameStep.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,11 @@ export class DefaultResourcesNameStep extends AzureWizardPromptStep<DeployWorksp
135135
isAvailable['resourceGroup'] = true;
136136
}
137137

138-
if (context.managedEnvironment || await ManagedEnvironmentNameStep.isNameAvailable(context, workspaceName, workspaceName)) {
138+
if (context.managedEnvironment || await ManagedEnvironmentNameStep.isNameAvailable(context, context.resourceGroup?.name ?? workspaceName, workspaceName)) {
139139
isAvailable['managedEnvironment'] = true;
140140
}
141141

142-
if (context.containerApp || await ContainerAppNameStep.isNameAvailable(context, workspaceName, workspaceName)) {
142+
if (context.containerApp || await ContainerAppNameStep.isNameAvailable(context, context.resourceGroup?.name ?? workspaceName, workspaceName)) {
143143
isAvailable['containerApp'] = true;
144144
}
145145

src/commands/deployWorkspaceProject/getDefaultValues/getDefaultContainerAppsResources/getDefaultContainerAppsResources.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@
66
import { type ManagedEnvironment } from "@azure/arm-appcontainers";
77
import { type ResourceGroup } from "@azure/arm-resources";
88
import { type ISubscriptionActionContext } from "@microsoft/vscode-azext-utils";
9-
import { type SetTelemetryProps } from "../../../../telemetry/SetTelemetryProps";
10-
import { type DeployWorkspaceProjectTelemetryProps as TelemetryProps } from "../../../../telemetry/commandTelemetryProps";
119
import { type ContainerAppItem, type ContainerAppModel } from "../../../../tree/ContainerAppItem";
1210
import { type ManagedEnvironmentItem } from "../../../../tree/ManagedEnvironmentItem";
11+
import { type DeployWorkspaceProjectContext } from "../../DeployWorkspaceProjectContext";
1312
import { type DeployWorkspaceProjectSettings } from "../../deployWorkspaceProjectSettings";
1413
import { getContainerAppResourcesFromItem, getContainerAppResourcesFromSettings } from "./getDefaultResourcesFrom";
1514
import { promptForEnvironmentResources } from "./promptForEnvironmentResources";
@@ -21,7 +20,7 @@ export interface DefaultContainerAppsResources {
2120
}
2221

2322
export async function getDefaultContainerAppsResources(
24-
context: ISubscriptionActionContext & SetTelemetryProps<TelemetryProps>,
23+
context: ISubscriptionActionContext & Partial<DeployWorkspaceProjectContext>,
2524
settings: DeployWorkspaceProjectSettings,
2625
item?: ContainerAppItem | ManagedEnvironmentItem
2726
): Promise<DefaultContainerAppsResources> {
@@ -33,9 +32,11 @@ export async function getDefaultContainerAppsResources(
3332
}
3433

3534
// Otherwise try to obtain container app resources using any saved workspace settings
36-
const { resourceGroup, managedEnvironment, containerApp } = await getContainerAppResourcesFromSettings(context, settings);
37-
if (resourceGroup && managedEnvironment && containerApp) {
38-
return { resourceGroup, managedEnvironment, containerApp };
35+
if (!context.ignoreExistingDeploySettings) {
36+
const { resourceGroup, managedEnvironment, containerApp } = await getContainerAppResourcesFromSettings(context, settings);
37+
if (resourceGroup && managedEnvironment && containerApp) {
38+
return { resourceGroup, managedEnvironment, containerApp };
39+
}
3940
}
4041

4142
// Otherwise prompt the user for managed environment resources to use

0 commit comments

Comments
 (0)