Skip to content

Create New Project design improvements#4964

Open
gavin-aguiar wants to merge 17 commits into
microsoft:mainfrom
gavin-aguiar:gaaguiar/getting_started
Open

Create New Project design improvements#4964
gavin-aguiar wants to merge 17 commits into
microsoft:mainfrom
gavin-aguiar:gaaguiar/getting_started

Conversation

@gavin-aguiar
Copy link
Copy Markdown
Contributor

@gavin-aguiar gavin-aguiar commented Apr 7, 2026

Summary

Introduces an opt-in Template Gallery experience for "Create New Project" that consumes the new shared webview package from microsoft/vscode-azuretools. All UI lives in the shared package; this extension only owns:

  • Configuration (header text, supported languages, AI generation flag)
  • Business logic (template fetching, project creation, Copilot generation, README fetching)
  • Wiring into existing commands

The extension's previous in-repo Template Gallery (HTML/CSS/JS in resources/webviews/templateGallery/ from PR #4964, and the React port in src/webview/) is removed in favor of the shared package.

🔗 Companion PR in vscode-azuretools: microsoft/vscode-azuretools#2278 — must be merged and published before this PR can switch from file: to a versioned dependency.


How to enable

The gallery is gated behind an opt-in setting and does not affect the default Create-Project wizard:

  1. Open Command Palette → Preferences: Open Settings (JSON)
  2. Add "azureFunctions.enableTemplateGallery": true
  3. Run Azure Functions: Create New Project... — the gallery webview opens

Architecture

┌────────────────────────────────────────────────────┐
│  @microsoft/vscode-azext-webview  (shared)         │
│  ─────────────────────────────────────────────     │
│  • TemplateGalleryController   (abstract)          │
│  • React UI (browse, details, AI, creating)        │
│  • TemplateGalleryConfig + types                   │
└──────────────────────▲─────────────────────────────┘
                       │ extends
┌──────────────────────┴─────────────────────────────┐
│  FunctionsTemplateGalleryController                │
│  ─────────────────────────────────────────────     │
│  • fetchTemplates()  → ProjectTemplateProvider     │
│  • createProject()   → git clone + scaffold        │
│  • getReadme()       → GitHub raw fetch            │
│  • generateWithCopilot() → vscode.lm chat          │
│  • createAiProject()    → write files to disk      │
│  • continueInChat()     → workbench.action.chat    │
└────────────────────────────────────────────────────┘

The shared controller creates the WebviewPanel, routes typed messages between the webview and the subclass, and renders the React UI bundled in the package. The subclass implements fetchTemplates, createProject, getReadme, and optionally the three AI methods.


Notable behaviors

Behavior Where
Opt-in via azureFunctions.enableTemplateGallery setting createNewProject.ts
Default project location = workspace folder controller config
"Use Template" button on card → create immediately UI handles default location/language
Card click → Template Details (with README preview) UI
Detected non-empty target folder → modal confirmation before clobbering createProject()
Hidden / metadata files (.vscode, .git, .DS_Store, Thumbs.db) ignored when assessing emptiness createProject()
Cloned .git folder removed; git init creates a fresh history (no template author commits) createProject()
README.md auto-opened in markdown preview after creation _tryOpenReadme()
Telemetry events: templateGallery.getTemplates, templateGallery.createProject, templateGallery.generateWithCopilot, templateGallery.createAiProject wrapped via callWithTelemetryAndErrorHandling

Changes

Added

File Purpose
src/commands/createNewProject/FunctionsTemplateGalleryController.ts Subclass of shared TemplateGalleryController; ports all gallery business logic
scripts/copyWebviewAssets.mjs Copies views.js/views.css from the shared package into dist/webview/ at build time so the VSIX ships the bundle
.npmrc (install-links=true) Forces npm to install the local file: dependency as a copy (not a symlink) so vsce package doesn't traverse outside the extension folder

Modified

File Change
src/extension.ts Calls registerWebviewExtensionVariables({ context, webviewAssetsDir }) so the shared WebviewBaseController can locate the bundled assets
src/commands/createNewProject/createNewProject.ts Routes opt-in flow to FunctionsTemplateGalleryController.createOrShow(ext.context)
src/commands/createNewProject/NewProjectLanguageStep.ts "Browse Template Gallery (Preview)..." quick pick item routes to the same controller
package.json Adds @microsoft/vscode-azext-webview dependency; replaces build:webview script (esbuild → copy assets); adds --no-dependencies to vsce package (extension is fully bundled by esbuild)
.vscodeignore Removed obsolete codicons whitelist (font is no longer shipped from this extension)
tsconfig.json Removed "src/webview" from exclude (the folder is gone)

Copilot AI review requested due to automatic review settings April 7, 2026 23:11
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a new opt-in “Create New Project” template gallery (webview + template manifest provider) and introduces smarter local workflows (Run Function App pre-start steps, Copilot-based validation, and Smart Deploy) to improve project creation, run, validate, and deploy experiences in the Azure Functions VS Code extension.

Changes:

  • Added a template-gallery-driven project creation flow (webview UI + remote/bundled manifest provider + clone/copy steps).
  • Added new commands: Run Function App (runtime-aware setup), Validate Function App (Copilot + diagnostics), and Smart Deploy (AZD-aware routing).
  • Improved activation/init behavior by detecting and persisting the project language model when missing.

Reviewed changes

Copilot reviewed 27 out of 28 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
src/vsCodeConfig/verifyVSCodeConfigOnActivate.ts Detects and persists projectLanguageModel during activation when missing.
src/vsCodeConfig/verifyInitForVSCode.ts Detects and persists projectLanguageModel during init verification when missing.
src/templates/projectTemplates/ProjectTemplateProvider.ts Fetches/merges/caches template manifests and filters templates by language/model.
src/templates/projectTemplates/IProjectTemplate.ts Defines template/manifest types used by the template gallery and wizard flow.
src/extensionVariables.ts Adds a shared diagnostic collection handle to extension globals.
src/extension.ts Initializes and disposes the Azure Functions diagnostic collection on activation.
src/commands/validateFunctionApp/FunctionAppValidator.ts Implements Copilot-based project validation and publishes results as VS Code diagnostics.
src/commands/runFunctionApp/RunFunctionApp.ts Adds runtime-aware “Run Function App” behavior (venv/npm/dotnet build + func start).
src/commands/registerCommands.ts Registers new commands (validate, smart deploy, run function app).
src/commands/deploy/SmartDeploy.ts Adds deploy routing logic (AZD-aware) while delegating to existing deploy where appropriate.
src/commands/createNewProject/TemplateListStep.ts Adds Quick Pick template selection (category-grouped) for the wizard template flow.
src/commands/createNewProject/TemplateGalleryPanel.ts Implements the template gallery webview controller, template cloning, and AI project creation.
src/commands/createNewProject/StartingPointStep.ts Adds “template vs scratch” starting point step to the classic wizard flow.
src/commands/createNewProject/PostCloneStep.ts Adds post-clone analysis (Bicep/README detection) and follow-up notifications.
src/commands/createNewProject/NewProjectLanguageStep.ts Adds a “Browse Template Gallery…” discovery option in the classic language picker.
src/commands/createNewProject/IProjectWizardContext.ts Extends wizard context with template-flow-specific properties.
src/commands/createNewProject/createNewProject.ts Branches between classic wizard and new gallery flow based on an opt-in setting.
src/commands/createNewProject/CloneTemplateStep.ts Adds a wizard execute step to clone/copy a template repo (including sparse checkout).
resources/webviews/templateGallery/styles.css Adds styling for the template gallery and AI generation UI.
resources/webviews/templateGallery/main.js Implements template gallery filtering, selection, and AI-generation UX in the webview.
resources/webviews/templateGallery/index.html Static template gallery HTML used as a webview resource.
resources/skills/functionapp.md Adds common (all runtimes) validator “skill” rules/prompting schema.
resources/skills/python.md Adds Python-specific validator rules/prompting guidance.
resources/backupProjectTemplates/manifest.json Adds an offline fallback template manifest.
package.json Contributes new commands/menus and new project template settings; adds codicons dependency.
package.nls.json Adds localized strings for new commands and project template settings.
package-lock.json Updates lockfile for new dependency additions and version bump.
.vscodeignore Ensures codicons assets are packaged for the webview.

Comment thread src/templates/projectTemplates/ProjectTemplateProvider.ts
Comment thread src/templates/projectTemplates/ProjectTemplateProvider.ts
Comment thread src/templates/projectTemplates/ProjectTemplateProvider.ts Outdated
Comment thread resources/webviews/templateGallery/styles.css Outdated
Comment thread src/commands/createNewProject/TemplateGalleryPanel.ts Outdated
Comment thread src/commands/createNewProject/StartingPointStep.ts Outdated
Comment thread src/commands/deploy/SmartDeploy.ts
Comment thread package.json
Comment thread src/templates/projectTemplates/ProjectTemplateProvider.ts
Comment thread src/commands/validateFunctionApp/FunctionAppValidator.ts Outdated
@gavin-aguiar gavin-aguiar marked this pull request as ready for review April 13, 2026 18:35
@gavin-aguiar gavin-aguiar requested a review from a team as a code owner April 13, 2026 18:35
@fiveisprime
Copy link
Copy Markdown
Member

fiveisprime commented May 13, 2026

Alright, I have some feedback on this and I'm happy to provide more info for any
of these items if needed.

First of all, I tested TypeScript and JavaScript templates on both Windows and
Linux via WSL. I created from a template, ran the project with breakpoints,
added additional functions, and deployed the app via the AZD integration in the
workspace view. I did not test any of the Copilot functionality so far.

It's worth noting that the "create new function" command is available and works
even when a project is created via a template. 🎉

  • Template Gallery Usability: The template gallery allows changing location
    after it was already chosen, which is unnecessary.
  • Theme Compatibility: Some themes lack sufficient contrast in inputs and
    checkboxes, affecting usability.
  • Template Editability: The Language input appears editable but is not,
    which is confusing for users.
  • Workspace Redundancy: The notification to open the workspace at the end
    feels redundant since the location is chosen prior to launching the template
    gallery.
  • UI Element Placement: The notification content is positioned below where
    it should be – the “Source: Azure Functions extension” is cut off in a weird
    way.
  • Project Initialization Experience: After project creation, nothing opens
    (e.g., rendered readme or source functions), and consider improving this
    experience.
  • Pre-Launch Task Automation: Consider running npm install automatically for
    JavaScript and TypeScript projects to prevent errors on first launch.
  • User Guidance: Add a suggestion to guide the customer to the next step
    after project creation.
  • Test File Placement and Extension Recommendation: Evaluate whether
    test.http should be nested in src or at a higher level, and update
    extensions.json to recommend the appropriate HTTP testing extension.
  • Git History Initialization: Git history is inherited from the template
    repo and recommend performing a fresh git init to remove tracking.
  • Contributing and License Files: Update contributing.md to remove
    references to CLA bot and ensure license.md reflects the correct license for
    customer projects.
  • Responsive UI: Opening the integrated terminal results in multiple scroll
    bars.
  • Project Overwrite Prompt: Creating a project from a template over an
    existing workspace does not prompt for overwrite and ensure the prompt matches
    existing project behavior.

@gavin-aguiar
Copy link
Copy Markdown
Contributor Author

Alright, I have some feedback on this and I'm happy to provide more info for any of these items if needed.

First of all, I tested TypeScript and JavaScript templates on both Windows and Linux via WSL. I created from a template, ran the project with breakpoints, added additional functions, and deployed the app via the AZD integration in the workspace view. I did not test any of the Copilot functionality so far.

It's worth noting that the "create new function" command is available and works even when a project is created via a template. 🎉

  • Template Gallery Usability: The template gallery allows changing location
    after it was already chosen, which is unnecessary.
  • Theme Compatibility: Some themes lack sufficient contrast in inputs and
    checkboxes, affecting usability.
  • Template Editability: The Language input appears editable but is not,
    which is confusing for users.
  • Workspace Redundancy: The notification to open the workspace at the end
    feels redundant since the location is chosen prior to launching the template
    gallery.
  • UI Element Placement: The notification content is positioned below where
    it should be – the “Source: Azure Functions extension” is cut off in a weird
    way.
  • Project Initialization Experience: After project creation, nothing opens
    (e.g., rendered readme or source functions), and consider improving this
    experience.
  • Pre-Launch Task Automation: Consider running npm install automatically for
    JavaScript and TypeScript projects to prevent errors on first launch.
  • User Guidance: Add a suggestion to guide the customer to the next step
    after project creation.
  • Test File Placement and Extension Recommendation: Evaluate whether
    test.http should be nested in src or at a higher level, and update
    extensions.json to recommend the appropriate HTTP testing extension.
  • Git History Initialization: Git history is inherited from the template
    repo and recommend performing a fresh git init to remove tracking.
  • Contributing and License Files: Update contributing.md to remove
    references to CLA bot and ensure license.md reflects the correct license for
    customer projects.
  • Responsive UI: Opening the integrated terminal results in multiple scroll
    bars.
  • Project Overwrite Prompt: Creating a project from a template over an
    existing workspace does not prompt for overwrite and ensure the prompt matches
    existing project behavior.

Hi @fiveisprime, Thanks for testing this new change. I have addressed your comments in microsoft/vscode-azuretools#2278 since the webview is moved to the other repo. Let me know if you have any other feedback, Thanks.

Comment thread package.json
"@microsoft/vscode-azext-azureappsettings": "^1.0.0",
"@microsoft/vscode-azext-azureutils": "^4.0.1",
"@microsoft/vscode-azext-utils": "^4.0.5",
"@microsoft/vscode-azext-webview": "file:../vscode-azuretools/webview",
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.

Will replace with the correct build before merging..

Copy link
Copy Markdown
Member

@nturinski nturinski left a comment

Choose a reason for hiding this comment

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

Reviewed for blocking issues only — inline comments cover them. High level:

  • The PR description only covers the webview Template Gallery, but the diff also adds (1) an entirely new quick-pick template flow (StartingPointStep + 5 supporting files + 846-line bundled manifest) that is dead code, and (2) two brand-new top-level commands (smartDeploy, runFunctionApp) that overlap existing commands. Strongly recommend splitting into separate PRs — they have very different review surfaces.
  • package.nls.json doesn't parse.
  • file: sibling dep + --no-dependencies packaging will both fail outside the author's local checkout.
  • The new editor-title menu items appear on every open editor in VS Code.
  • Two security issues in the AI/clone code paths (path-traversal check, shell quoting).

Happy to look at a follow-up once the dead code is removed and the gallery is split out.

Comment thread package.nls.json
"azureFunctions.projectTemplates.additionalManifestUrls": "Additional template manifest URLs to merge with the primary manifest.",
"azureFunctions.projectTemplates.cacheExpirationHours": "Template manifest cache expiration time in hours.",
"azureFunctions.projectTemplates.preferTemplateFlow": "Pre-select 'Start from template' in the project creation wizard.",
"azureFunctions.projectTemplates.showBicepPrompt": "Prompt to deploy infrastructure when templates include Bicep files."
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.

Missing trailing comma — this breaks package.nls.json parsing and all NLS resolution.

Comment thread package.json
"version": "tsc --version",
"cleanReadme": "node scripts/cleanReadme.mjs",
"package": "vsce package --githubBranch main",
"package": "vsce package --githubBranch main --no-dependencies",
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.

--no-dependencies ships the VSIX without node_modules, so anything not bundled by esbuild will fail at runtime. This repo's esbuild.mjs wasn't extended to verify every entry under dependencies is bundled. Please install the packaged VSIX and exercise activation before merging, or drop this flag.

Comment thread package.json
Comment on lines 1123 to +1132
"editor/title": [
{
"command": "azureFunctions.runFunctionApp",
"when": "editorIsOpen",
"group": "navigation@0"
},
{
"command": "azureFunctions.smartDeploy",
"when": "editorIsOpen",
"group": "navigation@1"
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.

"when": "editorIsOpen" adds a "Run Function App" and "Deploy Function App" icon to the title bar of every open editor in VS Code, including unrelated workspaces. Needs to be gated on a Functions-project context (e.g. azureFunctions.projectLanguage), and arguably shouldn't be in editor/title at all.

Comment thread package.json
Comment on lines +637 to +646
{
"command": "azureFunctions.smartDeploy",
"when": "view == azureWorkspace && viewItem =~ /azFuncLocalProject/i",
"group": "inline"
},
{
"command": "azureFunctions.smartDeploy",
"when": "view == azureWorkspace && viewItem =~ /azFuncLocalProject/i",
"group": "1@2b"
},
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.

smartDeploy is registered twice for the same view item (inline + 1@2b); runFunctionApp below is duplicated the same way. Each command will appear twice in the context menu.

Comment on lines +340 to +344
const safePath = file.path.replace(/^[/\\]/, '');
const filePath = path.resolve(targetDir, safePath);
if (!filePath.startsWith(path.resolve(targetDir))) {
continue;
}
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.

Path-traversal check is unsafe:

  • replace(/^[/\\]/, '') strips only one leading separator, so ..\..\evil still escapes.
  • startsWith(path.resolve(targetDir)) without a trailing path.sep accepts e.g. targetDir = C:\fooC:\foobar\evil.txt.
  • Silently continue-ing leaves no signal that the AI's output was partially dropped.

Suggest:

const rel = path.relative(targetDir, filePath);
if (rel.startsWith('..') || path.isAbsolute(rel)) {
    throw new Error(`Refusing to write outside project: ${file.path}`);
}

Comment on lines +485 to +491
await cpUtils.executeCommandLine(undefined, undefined, `tar -xf "${zipPath}" -C "${path.dirname(destDir)}"`);
} catch {
if (process.platform === 'win32') {
await cpUtils.executeCommandLine(undefined, undefined,
`powershell -Command "Expand-Archive -Path '${zipPath}' -DestinationPath '${path.dirname(destDir)}' -Force"`);
} else {
await cpUtils.executeCommandLine(undefined, undefined, `unzip -q "${zipPath}" -d "${path.dirname(destDir)}"`);
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.

String-interpolated shell commands are a quoting-injection class bug — os.tmpdir() contains the username on Windows, so a ' or " in the path breaks PowerShell's single-quoted args. Use cpUtils.executeCommand with an argv array, or extract the zip with a Node library (yauzl/adm-zip) so no shell is involved.

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.

This whole file (along with TemplateListStep, CloneTemplateStep, PostCloneStep, IProjectTemplate, ProjectTemplateProvider, and the 846-line bundled manifest.json) is dead code — nothing in createNewProjectInternal is modified to insert StartingPointStep into the wizard, and no other call site references it. Either wire it in or remove it from this PR.

@@ -0,0 +1,511 @@
/*---------------------------------------------------------------------------------------------
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.

Could you explain the intention behind RunFunctionApp.ts being added to this PR? This seems similar to what the extension already ships using VS Code's task and debug APIs. For example:

FuncTaskProvider auto-contributes func: host start (plus func: extensions install and Python pack / pack --build-native-deps) tasks for every Functions project.

The per-language FuncDebugProviderBase subclasses wire those tasks up as the preLaunchTask for F5.
validatePreDebug runs the necessary pre-flight checks (Core Tools installed and version-compatible, FUNCTIONS_WORKER_RUNTIME present, durable-storage connections, AzureWebJobsStorage and Azurite actually running).

PythonVenvCreateStep, PythonAliasListStep, and venvUtils (venvExists, runPipInstallCommandIfPossible, convertToVenvCommand) own venv lifecycle.

The language-specific init steps (JavaScriptInitVSCodeStep, TypeScriptInitVSCodeStep, PythonInitVSCodeStep, Script/C# variants) already declare npm install / npm run build / dotnet build / pip install as dependsOn tasks for host start.
funcHostTask tracks the running host so the FunctionHostDebugView can surface logs, errors, and the host
PID.

However, RunFunctionApp.ts ignores every one of those systems and reimplements each one inline — project-root discovery (a worse copy of tryGetFunctionProjectRoot), runtime detection (a worse copy of tryGetFunctionsWorkerRuntimeForProject that only knows three languages and silently falls through to "generic" for Java/PowerShell/Ballerina/Custom), Python alias probing, venv creation, pip install, npm install/build, and dotnet build. Any bug fix or new language now has two places to update, with the new copy guaranteed to drift.

It is also strictly less flexible. It hardcodes .venv while the rest of the extension respects the azureFunctions.pythonVenv workspace setting. It ignores user customizations to the func: host start task in tasks.json (custom args, env vars, problem matchers, working directory), the azureFunctions.projectLanguage / azureFunctions.preDeployTask / validateEmulators settings, custom preDeployTask hooks, and the Functions Core Tools path resolved by getFuncCliPath. It bypasses Azurite validation, durable-storage connection setup, and the worker-runtime auto-repair that preDebugValidate does.

Because it spawns func and npm / dotnet directly, the host doesn't show up in the Function Host Debug view, has no problem matcher integration, no port detection, no pickFuncProcess support, and no Activity Log entries.

Its Python workaround — a custom Pseudoterminal that silently swallows all stdin to dodge the Python extension's auto-activation injection — is a workaround for a problem the existing convertToVenvCommand-based ShellExecution path doesn't have, and it solves it by breaking every legitimate stdin use case (Ctrl+C is handled, but anything else a user types is dropped on the floor).

On top of that it ships several anti-patterns the rest of the codebase has long since moved past:

Synchronous fall-through try/catch blocks that swallow pip install / npm install / npm run build / dotnet build failures and continue to func start anyway, so the user sees a broken host instead of the real error.
JSON.parse on local.settings.json instead of the existing getLocalSettingsJson helper that handles JSONC and connection-string parsing.

A hand-rolled Windows process-tree kill via taskkill instead of the shared process utilities.
An entirely new top-level command and toolbar button that overlaps in purpose with the existing F5 debug entry point and the run icon already wired into the Functions walkthrough — adding user-visible surface area, telemetry, localization strings, and a maintenance burden for a capability the extension already provides more correctly.

// Public entry point
// ---------------------------------------------------------------------------

export async function smartDeploy(_context: IActionContext, resourceUri?: vscode.Uri): Promise<void> {
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.

I’d consider folding the smartDeploy behavior into the existing azureFunctions.deployProject command rather than adding it as a parallel deploy command.

The main reason is that smartDeploy doesn’t seem like a fundamentally different deploy path. It’s more of an AZD-aware layer on top of the existing deploy flow. In the non-AZD case, it already falls back to:

vscode.commands.executeCommand('azureFunctions.deployProject', resourceUri)

So structurally, it feels like the AZD detection belongs inside deployProject itself.

Having both commands registered side by side also introduces a few downsides:

  • User choice becomes less clear. Two similar “Deploy…” entries make the user decide which deploy path is the right one. The AZD-aware behavior feels like the thing most users would expect from the normal Deploy command.
  • Existing entry points may miss the new behavior. Tree-view menus, walkthroughs, internal callers, post-deploy flows, slot deploy, and the public extension API already point at azureFunctions.deployProject. Those would bypass AZD detection unless deployProject becomes the smart default.
  • Telemetry and debugging get split. Separate command IDs make it harder to understand which deploy path a user took when looking at telemetry or investigating issues.
  • The two paths may drift over time. Project-root resolution, validation, sign-in handling, slot handling, and post-deploy tasks are all areas where keeping two paths aligned could become easy to miss.

A possible shape would be:

  1. In deployProject, resolve the project root as usual.
  2. Before launching the normal wizard, call detectAzdProject.
  3. If an azure.yaml or azure.yml is found, prompt with something like:
    • Deploy with azd up
    • Use Functions deploy
    • Cancel
  4. Gate that with a setting like:
    azureFunctions.deploy.azdPromptBehavior: 'prompt' | 'azd' | 'functions'

and include a “Don’t ask again” option.

With that structure, azureFunctions.deployProject remains the main deploy entry point, but becomes AZD-aware. SmartDeploy.ts can still exist as the place for detectAzdProject and runAzd* helpers; it just wouldn’t need to register a separate command/menu item.

// AZD invocation
// ---------------------------------------------------------------------------

async function runAzdDeploy(context: IActionContext, projectRoot: string): Promise<void> {
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.

I’d also simplify the AZD execution path by relying on the AZD extension rather than maintaining our own CLI fallback.

Right now, SmartDeploy has a few layers:

  • Try azure-dev.commands.cli.*
  • Fall back to spawning azd in a terminal
  • If that fails, show docs/install guidance

I don’t think we need all three. The AZD extension already exposes the CLI surface through commands like:

azure-dev.commands.cli.up
azure-dev.commands.cli.init
azure-dev.commands.cli.provision
azure-dev.commands.cli.deploy
azure-dev.commands.cli.down
azure-dev.commands.cli.install

Since the AZD extension owns the install and CLI-missing experience, we can route through it instead of duplicating CLI detection and terminal handling.

}

function detectAzdProject(projectRoot: string): AzdStatus {
const azureYamlPath = path.join(projectRoot, 'azure.yaml');
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.

I think technically azd handles both azure.yaml and azure.yml.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants