Skip to content
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
3f97bf8
Wip
MicroFish91 Nov 29, 2023
63327a8
Wip
MicroFish91 Nov 29, 2023
c141c41
Wip
MicroFish91 Dec 7, 2023
4d4d245
Update verbiage
MicroFish91 Dec 7, 2023
9a2ac95
Remove activity context for api
MicroFish91 Dec 7, 2023
dcfb0e0
Clean up misc
MicroFish91 Dec 7, 2023
0535237
Revert
MicroFish91 Dec 7, 2023
9bca1f4
Hide api command from palette
MicroFish91 Dec 7, 2023
d5f09fc
Api context
MicroFish91 Dec 7, 2023
cc614bf
Misc
MicroFish91 Dec 7, 2023
6238290
Skip checking workspace settings from api entry point
MicroFish91 Dec 9, 2023
3617d8e
Change to fsPath
MicroFish91 Dec 12, 2023
a4941db
invokedFromApi
MicroFish91 Dec 12, 2023
5aaa76e
Add api.d.ts
MicroFish91 Dec 13, 2023
63bc92a
Remove api loading prompt
MicroFish91 Dec 14, 2023
dd588b9
Add subscription ID support
MicroFish91 Dec 18, 2023
8b57bae
Update option name
MicroFish91 Dec 19, 2023
4c98107
Update deployWorkspaceProjectResults
MicroFish91 Dec 19, 2023
976aadb
Misc
MicroFish91 Dec 20, 2023
6cb885a
Updates with shared tools changes
MicroFish91 Dec 21, 2023
c8d93c3
Merge branch 'main' of https://github.com/microsoft/vscode-azureconta…
MicroFish91 Jan 2, 2024
5b04b68
Reset package deps
MicroFish91 Jan 2, 2024
dffdff2
Upgrade deps
MicroFish91 Jan 2, 2024
99c8007
Update comment
MicroFish91 Jan 2, 2024
9928198
Update comments
MicroFish91 Jan 2, 2024
fb52b44
Update comment
MicroFish91 Jan 3, 2024
b3ba7b6
Microsoft header
MicroFish91 Jan 3, 2024
f45ff07
suppressConfirmation
MicroFish91 Jan 3, 2024
645863c
No skip create message
MicroFish91 Jan 3, 2024
ca46995
Merge with main
MicroFish91 Jan 5, 2024
72f5bdc
Simplify output messages
MicroFish91 Jan 5, 2024
1b4c909
Misc
MicroFish91 Jan 5, 2024
64d237a
Add ignoreExistingDeploySettings
MicroFish91 Jan 5, 2024
1da6c7a
Decouple API from deployWorkspaceProject
MicroFish91 Jan 8, 2024
b889b70
Add promptForEnvironmentResources comments
MicroFish91 Jan 8, 2024
4d2afd2
Expose a proper API interface using api provider
MicroFish91 Jan 8, 2024
6436c7b
Update changelog
MicroFish91 Jan 8, 2024
1fd1c21
Remove comment
MicroFish91 Jan 8, 2024
bdcdb92
Change type
MicroFish91 Jan 8, 2024
27e2fa2
Add dwp internal
MicroFish91 Jan 8, 2024
fa02fd4
Revert
MicroFish91 Jan 8, 2024
3521e6f
Merge with internal branch
MicroFish91 Jan 9, 2024
19bee17
centralize getDeployWorkspaceProjectResults
MicroFish91 Jan 9, 2024
17dd935
Remove unused values
MicroFish91 Jan 9, 2024
cdd88f6
Remove unused values
MicroFish91 Jan 9, 2024
e22058d
Merge branch 'mwf/dwp-internal' of https://github.com/microsoft/vscod…
MicroFish91 Jan 9, 2024
ce947c3
Merge branch 'main' of https://github.com/microsoft/vscode-azureconta…
MicroFish91 Jan 9, 2024
8518640
Merge branch 'mwf/dwp-internal' of https://github.com/microsoft/vscod…
MicroFish91 Jan 9, 2024
283c86a
Merge with main
MicroFish91 Jan 12, 2024
e0d9e70
Feedback
MicroFish91 Jan 17, 2024
a1915da
Formatting
MicroFish91 Jan 19, 2024
db57811
newline
MicroFish91 Jan 24, 2024
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
4 changes: 2 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.organizeImports": true
"source.fixAll.eslint": "explicit",
"source.organizeImports": "explicit"
},
"editor.formatOnSave": true,
"editor.insertSpaces": true,
Expand Down
14 changes: 7 additions & 7 deletions package-lock.json

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

11 changes: 10 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@
"title": "%containerApps.deployWorkspaceProject%",
"category": "Azure Container Apps"
},
{
"command": "containerApps.deployWorkspaceProjectApi",
"title": "%containerApps.deployWorkspaceProjectApi%",
"category": "Azure Container Apps"
},
{
"command": "containerApps.deployWorkspaceProjectToContainerApp",
"title": "%containerApps.deployWorkspaceProjectToContainerApp%",
Expand Down Expand Up @@ -503,6 +508,10 @@
"command": "containerApps.deployWorkspaceProjectToContainerApp",
"when": "never"
},
{
"command": "containerApps.deployWorkspaceProjectApi",
"when": "never"
},
{
"command": "containerApps.deployImageApi",
"when": "never"
Expand Down Expand Up @@ -615,7 +624,7 @@
"@azure/container-registry": "1.0.0-beta.5",
"@azure/core-rest-pipeline": "1.10.3",
"@azure/storage-blob": "^12.4.1",
"@microsoft/vscode-azext-azureutils": "^2.0.0",
"@microsoft/vscode-azext-azureutils": "^2.0.3",
"@microsoft/vscode-azext-github": "^1.0.0",
"@microsoft/vscode-azext-utils": "^2.1.5",
"@microsoft/vscode-azureresources-api": "^2.0.2",
Expand Down
1 change: 1 addition & 0 deletions package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"containerApps.updateImage": "Update Container Image...",
"containerApps.deployImageApi": "Deploy Image to Container App (API)...",
"containerApps.deployWorkspaceProject": "Deploy Project from Workspace...",
"containerApps.deployWorkspaceProjectApi": "Deploy Project from Workspace (API)...",
"containerApps.deployWorkspaceProjectToContainerApp": "Deploy Workspace to Container App...",
"containerApps.deleteContainerApp": "Delete Container App...",
"containerApps.disableIngress": "Disable Ingress for Container App",
Expand Down
9 changes: 9 additions & 0 deletions src/commands/api/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Change Log

## 0.0.1

Comment thread
MicroFish91 marked this conversation as resolved.
Outdated
* Initial release

### Added

* Added an API entry-point to the `deployWorkspaceProject` command [#578](https://github.com/microsoft/vscode-azurecontainerapps/pull/578)
81 changes: 81 additions & 0 deletions src/commands/api/deployWorkspaceProjectApi.ts
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.md in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { type RegistryPassword } from "@azure/arm-containerregistry";
import { type ResourceGroup } from "@azure/arm-resources";
import { ResourceGroupListStep, parseAzureResourceGroupId } from "@microsoft/vscode-azext-azureutils";
import { createSubscriptionContext, subscriptionExperience, type IActionContext, type ISubscriptionActionContext, type ISubscriptionContext } from "@microsoft/vscode-azext-utils";
import { type AzureSubscription } from "@microsoft/vscode-azureresources-api";
import { Uri, type WorkspaceFolder } from "vscode";
import { ext } from "../../extensionVariables";
import { getWorkspaceFolderFromPath } from "../../utils/workspaceUtils";
import { deployWorkspaceProjectInternal, type DeployWorkspaceProjectInternalContext } from "../deployWorkspaceProject/deployWorkspaceProjectInternal";
import { listCredentialsFromRegistry } from "../image/imageSource/containerRegistry/acr/listCredentialsFromRegistry";
import type * as api from "./vscode-azurecontainerapps.api";

export async function deployWorkspaceProjectApi(context: IActionContext, deployWorkspaceProjectOptions: api.DeployWorkspaceProjectOptionsContract): Promise<api.DeployWorkspaceProjectResults> {
const { resourceGroupId, rootPath, dockerfilePath, srcPath, suppressConfirmation, suppressContainerAppCreation, ignoreExistingDeploySettings, shouldSaveDeploySettings } = deployWorkspaceProjectOptions;

const subscription: AzureSubscription = await subscriptionExperience(context, ext.rgApiV2.resources.azureResourceTreeDataProvider, {
selectBySubscriptionId: getSubscriptionIdFromOptions(deployWorkspaceProjectOptions),
showLoadingPrompt: false
});
const subscriptionContext: ISubscriptionContext = createSubscriptionContext(subscription);

const rootFolder: WorkspaceFolder | undefined = rootPath ? getWorkspaceFolderFromPath(rootPath) : undefined;
const resourceGroup: ResourceGroup | undefined = resourceGroupId ? await getResourceGroupFromId({ ...context, ...subscriptionContext }, resourceGroupId) : undefined;

const deployWorkspaceProjectInternalContext: DeployWorkspaceProjectInternalContext = Object.assign(context, {
...subscriptionContext,
subscription,
resourceGroup,
rootFolder,
srcPath: srcPath ? Uri.file(srcPath).fsPath : undefined,
Comment thread
nturinski marked this conversation as resolved.
Outdated
dockerfilePath: dockerfilePath ? Uri.file(dockerfilePath).fsPath : undefined,
suppressConfirmation,
ignoreExistingDeploySettings,
shouldSaveDeploySettings: !!shouldSaveDeploySettings,
});

const deployWorkspaceProjectResultContext = await deployWorkspaceProjectInternal(deployWorkspaceProjectInternalContext, undefined, {
// Don't show activity log updates in ACA when another client extension calls into this API.
// Let each client decide how it wants to show its own activity log updates.
suppressActivity: true,
suppressConfirmation,
suppressContainerAppCreation,
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Let me know if you think it would be a good idea to default some of these values

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Does this comment still make sense? A lot of this seems defaulted already.

suppressProgress: true,
suppressWizardTitle: true,
});

const registryCredentials: { username: string, password: RegistryPassword } | undefined = deployWorkspaceProjectResultContext.registry ?
await listCredentialsFromRegistry(deployWorkspaceProjectResultContext, deployWorkspaceProjectResultContext.registry) : undefined;

return {
resourceGroupId: deployWorkspaceProjectResultContext.resourceGroup?.id,
logAnalyticsWorkspaceId: deployWorkspaceProjectResultContext.logAnalyticsWorkspace?.id,
managedEnvironmentId: deployWorkspaceProjectResultContext.managedEnvironment?.id,
containerAppId: deployWorkspaceProjectResultContext.containerApp?.id,
registryId: deployWorkspaceProjectResultContext.registry?.id,
registryLoginServer: deployWorkspaceProjectResultContext.registry?.loginServer,
registryUsername: registryCredentials?.username,
registryPassword: registryCredentials?.password.value,
imageName: deployWorkspaceProjectResultContext.imageName
};
}

function getSubscriptionIdFromOptions(deployWorkspaceProjectOptions: api.DeployWorkspaceProjectOptionsContract): string | undefined {
if (deployWorkspaceProjectOptions.subscriptionId) {
return deployWorkspaceProjectOptions.subscriptionId;
} else if (deployWorkspaceProjectOptions.resourceGroupId) {
return parseAzureResourceGroupId(deployWorkspaceProjectOptions.resourceGroupId).subscriptionId as string;
} else {
return undefined;
}
}

async function getResourceGroupFromId(context: ISubscriptionActionContext, resourceGroupId: string): Promise<ResourceGroup | undefined> {
const resourceGroups: ResourceGroup[] = await ResourceGroupListStep.getResourceGroups(context);
return resourceGroups.find(rg => rg.id === resourceGroupId);
}
18 changes: 18 additions & 0 deletions src/commands/api/getAzureContainerAppsApiProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.md in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { callWithTelemetryAndErrorHandling, createApiProvider, type IActionContext, type apiUtils } from "@microsoft/vscode-azext-utils";
import { deployWorkspaceProjectApi } from "./deployWorkspaceProjectApi";
import type * as api from "./vscode-azurecontainerapps.api";

export function getAzureContainerAppsApiProvider(): apiUtils.AzureExtensionApiProvider {
return createApiProvider([<api.AzureContainerAppsExtensionApi>{
apiVersion: '0.0.1',

deployWorkspaceProject: async (options: api.DeployWorkspaceProjectOptionsContract) => await callWithTelemetryAndErrorHandling('containerApps.api.deployWorkspaceProject', async (context: IActionContext) => {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: I prefer that we keep the apiProvider looking clean like so:

deployWorkspaceProject: deployWorkspaceProjectApi

And then in deployWorkspaceProjectApi, wrap that whole command with callWithTelemetryAndErrorHandling

return await deployWorkspaceProjectApi(context, options);
})
}]);
}
41 changes: 41 additions & 0 deletions src/commands/api/vscode-azurecontainerapps.api.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

export interface AzureContainerAppsExtensionApi {
apiVersion: string;

deployWorkspaceProject(options: DeployWorkspaceProjectOptionsContract): Promise<DeployWorkspaceProjectResults>;
}

export interface DeployWorkspaceProjectOptionsContract {
// Existing resources
subscriptionId?: string;
resourceGroupId?: string;

// Workspace deployment paths (absolute fs path)
rootPath?: string;
srcPath?: string;
dockerfilePath?: string;

// Options
suppressConfirmation?: boolean; // Suppress any [resource] confirmation prompts
suppressContainerAppCreation?: boolean;
ignoreExistingDeploySettings?: boolean;
shouldSaveDeploySettings?: boolean;
}

export interface DeployWorkspaceProjectResults {
resourceGroupId?: string;
logAnalyticsWorkspaceId?: string;
managedEnvironmentId?: string;
containerAppId?: string;

// ACR
registryId?: string;
registryLoginServer?: string;
registryUsername?: string;
registryPassword?: string;
imageName?: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@ import { nonNullValue } from "@microsoft/vscode-azext-utils";
import { ext } from "../../extensionVariables";
import { localize } from "../../utils/localize";
import { OverwriteConfirmStepBase } from "../OverwriteConfirmStepBase";
import { type DeployWorkspaceProjectContext } from "./DeployWorkspaceProjectContext";
import { type DeployWorkspaceProjectContext } from "./DeployWorkspaceProjectContext";

export class DeployWorkspaceProjectConfirmStep extends OverwriteConfirmStepBase<DeployWorkspaceProjectContext> {
constructor(private readonly suppressConfirmation: boolean) {
super();
}

protected async promptCore(context: DeployWorkspaceProjectContext): Promise<void> {
const resourcesToCreate: string[] = [];
if (!context.resourceGroup) {
Expand Down Expand Up @@ -59,6 +63,6 @@ export class DeployWorkspaceProjectConfirmStep extends OverwriteConfirmStepBase<
}

public shouldPrompt(): boolean {
return true;
return !this.suppressConfirmation;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,27 @@
* Licensed under the MIT License. See License.md in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { type ExecuteActivityContext } from "@microsoft/vscode-azext-utils";
import { type SetTelemetryProps } from "../../telemetry/SetTelemetryProps";
import { type DeployWorkspaceProjectTelemetryProps as TelemetryProps } from "../../telemetry/commandTelemetryProps";
import { type CreateContainerAppBaseContext } from "../createContainerApp/CreateContainerAppContext";
import { type IManagedEnvironmentContext } from "../createManagedEnvironment/IManagedEnvironmentContext";
import { type BuildImageInAzureImageSourceBaseContext } from "../image/imageSource/buildImageInAzure/BuildImageInAzureImageSourceContext";
import { type CreateAcrContext } from "../image/imageSource/containerRegistry/acr/createAcr/CreateAcrContext";
import { type ExecuteActivityContext } from "@microsoft/vscode-azext-utils";
import { type SetTelemetryProps } from "../../telemetry/SetTelemetryProps";
import { type DeployWorkspaceProjectTelemetryProps as TelemetryProps } from "../../telemetry/commandTelemetryProps";
import { type IContainerAppContext } from "../IContainerAppContext";
import { type CreateContainerAppBaseContext } from "../createContainerApp/CreateContainerAppContext";
import { type IManagedEnvironmentContext } from "../createManagedEnvironment/IManagedEnvironmentContext";
import { type BuildImageInAzureImageSourceBaseContext } from "../image/imageSource/buildImageInAzure/BuildImageInAzureImageSourceContext";
import { type CreateAcrContext } from "../image/imageSource/containerRegistry/acr/createAcr/CreateAcrContext";

// Use intersection typing instead of an interface here to bypass some minor (relatively trivial) type mismatch issues introduced by having to use the 'Partial' utility
export type DeployWorkspaceProjectContext = IManagedEnvironmentContext & CreateContainerAppBaseContext & CreateAcrContext & Partial<BuildImageInAzureImageSourceBaseContext> & ExecuteActivityContext & DeployWorkspaceProjectTelemetryProps & {
shouldSaveDeploySettings?: boolean;
};
export type DeployWorkspaceProjectContext =
IContainerAppContext &
Partial<IManagedEnvironmentContext> &
Partial<CreateContainerAppBaseContext> &
Partial<CreateAcrContext> &
Partial<BuildImageInAzureImageSourceBaseContext> &
Partial<ExecuteActivityContext> &
DeployWorkspaceProjectTelemetryProps &
{
ignoreExistingDeploySettings?: boolean;
shouldSaveDeploySettings?: boolean;
};

type DeployWorkspaceProjectTelemetryProps = SetTelemetryProps<TelemetryProps>;
Loading