Skip to content

fix(app-service-templates): address review feedback — discoverability, auth IaC, token refresh, source splits - #1635

Merged
JasonYeMSFT (JasonYeMSFT) merged 4 commits into
mainfrom
pass-equity-gap-1
May 4, 2026
Merged

fix(app-service-templates): address review feedback — discoverability, auth IaC, token refresh, source splits#1635
JasonYeMSFT (JasonYeMSFT) merged 4 commits into
mainfrom
pass-equity-gap-1

Conversation

@paulyuk

@paulyuk Paul Yuknewicz (paulyuk) commented Apr 1, 2026

Copy link
Copy Markdown
Member

PR review surfaced discoverability gaps, an auth recipe misclassification, token expiry bugs, and inconsistent source code organization across 11 reference files.

Discoverability & Navigation

  • app-service/README.md — added ## Templates section linking to templates/selection.md (entire templates tree was unreachable via JIT loading)
  • selection.md — converted plain-text (see web-api.md) references to markdown links; replaced duplicate Critical Rules block with a reference to the canonical list in composition.md

Auth Recipe Fixes

  • composition.md — reclassified auth from "Config recipe" (skipped Step 3) to "Full recipe" (routes through IaC step); auth requires authsettingsV2 + Microsoft.Graph/applications Bicep resources
  • auth/README.md — fixed openIdIssuer from sts.windows.net to login.microsoftonline.com/v2.0; added extension microsoftGraphV1_0 declaration above appRegistration; added mcp_bicep_get_az_resource_type_schema tips on both Bicep blocks

Bicep Schema Tool Instructions

Added > 💡 Call mcp_bicep_get_az_resource_type_schema with <type>… notes before hardcoded Bicep blocks in auth/README.md (×2) and web-api.md to prevent schema drift.

Source Code Organization

Split inline language examples out of auth/README.md, cosmos/README.md, and redis/README.md into source/{dotnet,python,nodejs}.md sub-files — matching the existing sql/ pattern and bringing all READMEs under the 1,000-token soft limit.

Token Expiry (Redis)

Python and Node.js Redis examples were acquiring a single Entra ID token at startup with no refresh. Replaced with a connection factory that proactively re-authenticates 5 minutes before expiry:

def _get_token():
    now = time.time()
    if not _token_cache or now >= _token_cache["expires_on"] - _TOKEN_REFRESH_MARGIN:
        tok = _credential.get_token(_TOKEN_SCOPE)
        _token_cache.update({"token": tok.token, "expires_on": tok.expires_on})
    return _token_cache["token"]

SQL Recipe

  • sql/source/python.md — fixed get_connection_string() inconsistent return type (string vs tuple) that caused runtime crash when AZURE_SQL_CONNECTION_STRING was set; consolidated into a single create_db_engine() that branches on env var presence
  • sql/source/dotnet.md — added app.MapHealthChecks("/health") so DB health checks are actually reachable by App Service probes
  • Added sql/source/nodejs.md with Prisma + Azure SQL managed identity example

Other

  • recipes/README.md — marked Java (Spring Data JPA/Cosmos/Security/Session) as ⏳ planned across all recipes
  • sql/README.md — corrected "Local Auth: Disabled" to note local dev may use SQL auth
  • web-api.md / web-app.md / composition.md — added PowerShell equivalents for ENV_NAME generation; clarified "strip database layer" as a bulleted checklist; fixed azd-service-name tag from webapi
  • SKILL.md — bumped version 1.1.1 → 1.1.5

11 template files for App Service development scaffolding:
- selection.md decision tree
- web-api.md and web-app.md base templates
- Composition algorithm (recipes for SQL, Cosmos, Auth, Redis)
- Language-specific source (C#, Python)

Closes #1609
Parent: #1608

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds “reference-only” App Service base templates plus a composable “recipe” system (SQL/Cosmos/Auth/Redis) to guide multi-language AZD project generation and merging.

Changes:

  • Introduces Web API + Web App base template reference docs (architecture, config, deployment, health checks).
  • Adds a template selection decision tree and a documented composition/merge algorithm for base + recipe.
  • Adds integration recipes (SQL, Cosmos DB, Entra ID/Easy Auth, Redis) with IaC/app-settings guidance and language-specific source patterns.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
plugin/skills/azure-prepare/references/services/app-service/templates/web-app.md Adds SSR/full-stack App Service base template guidance and examples.
plugin/skills/azure-prepare/references/services/app-service/templates/web-api.md Adds REST API App Service base template guidance (health checks, plan sizing, config).
plugin/skills/azure-prepare/references/services/app-service/templates/selection.md Adds decision tree for picking the correct base template + recipe(s).
plugin/skills/azure-prepare/references/services/app-service/templates/recipes/sql/source/python.md Adds Python SQLAlchemy + Azure SQL (managed identity) integration example.
plugin/skills/azure-prepare/references/services/app-service/templates/recipes/sql/source/dotnet.md Adds .NET EF Core + Azure SQL integration example and migration hook guidance.
plugin/skills/azure-prepare/references/services/app-service/templates/recipes/sql/README.md Defines SQL recipe composition steps, app settings, RBAC roles, resources.
plugin/skills/azure-prepare/references/services/app-service/templates/recipes/redis/README.md Defines Redis recipe composition steps and multi-language auth/client examples.
plugin/skills/azure-prepare/references/services/app-service/templates/recipes/cosmos/README.md Defines Cosmos recipe composition steps, settings, RBAC, and code examples.
plugin/skills/azure-prepare/references/services/app-service/templates/recipes/composition.md Documents the algorithm for composing base templates with recipes.
plugin/skills/azure-prepare/references/services/app-service/templates/recipes/auth/README.md Defines Entra ID/Easy Auth + MSAL options with IaC and code examples.
plugin/skills/azure-prepare/references/services/app-service/templates/recipes/README.md Adds recipe system overview, principles, and high-level workflow.

@github-actions

github-actions Bot commented Apr 1, 2026

Copy link
Copy Markdown
Contributor
Details# 🔍 Token Analysis Report

@github-copilot-for-azure/scripts@1.0.0 tokens
node --import tsx src/tokens/cli.ts compare --base origin/main --head HEAD --markdown

fatal: path 'plugin/skills/azure-prepare/references/services/app-service/templates/recipes/README.md' exists on disk, but not in 'origin/main'
fatal: path 'plugin/skills/azure-prepare/references/services/app-service/templates/recipes/auth/README.md' exists on disk, but not in 'origin/main'
fatal: path 'plugin/skills/azure-prepare/references/services/app-service/templates/recipes/auth/source/dotnet.md' exists on disk, but not in 'origin/main'
fatal: path 'plugin/skills/azure-prepare/references/services/app-service/templates/recipes/auth/source/nodejs.md' exists on disk, but not in 'origin/main'
fatal: path 'plugin/skills/azure-prepare/references/services/app-service/templates/recipes/auth/source/python.md' exists on disk, but not in 'origin/main'
fatal: path 'plugin/skills/azure-prepare/references/services/app-service/templates/recipes/composition.md' exists on disk, but not in 'origin/main'
fatal: path 'plugin/skills/azure-prepare/references/services/app-service/templates/recipes/cosmos/README.md' exists on disk, but not in 'origin/main'
fatal: path 'plugin/skills/azure-prepare/references/services/app-service/templates/recipes/cosmos/source/dotnet.md' exists on disk, but not in 'origin/main'
fatal: path 'plugin/skills/azure-prepare/references/services/app-service/templates/recipes/cosmos/source/nodejs.md' exists on disk, but not in 'origin/main'
fatal: path 'plugin/skills/azure-prepare/references/services/app-service/templates/recipes/cosmos/source/python.md' exists on disk, but not in 'origin/main'
fatal: path 'plugin/skills/azure-prepare/references/services/app-service/templates/recipes/redis/README.md' exists on disk, but not in 'origin/main'
fatal: path 'plugin/skills/azure-prepare/references/services/app-service/templates/recipes/redis/source/dotnet.md' exists on disk, but not in 'origin/main'
fatal: path 'plugin/skills/azure-prepare/references/services/app-service/templates/recipes/redis/source/nodejs.md' exists on disk, but not in 'origin/main'
fatal: path 'plugin/skills/azure-prepare/references/services/app-service/templates/recipes/redis/source/python.md' exists on disk, but not in 'origin/main'
fatal: path 'plugin/skills/azure-prepare/references/services/app-service/templates/recipes/sql/README.md' exists on disk, but not in 'origin/main'
fatal: path 'plugin/skills/azure-prepare/references/services/app-service/templates/recipes/sql/source/dotnet.md' exists on disk, but not in 'origin/main'
fatal: path 'plugin/skills/azure-prepare/references/services/app-service/templates/recipes/sql/source/nodejs.md' exists on disk, but not in 'origin/main'
fatal: path 'plugin/skills/azure-prepare/references/services/app-service/templates/recipes/sql/source/python.md' exists on disk, but not in 'origin/main'
fatal: path 'plugin/skills/azure-prepare/references/services/app-service/templates/selection.md' exists on disk, but not in 'origin/main'
fatal: path 'plugin/skills/azure-prepare/references/services/app-service/templates/web-api.md' exists on disk, but not in 'origin/main'
fatal: path 'plugin/skills/azure-prepare/references/services/app-service/templates/web-app.md' exists on disk, but not in 'origin/main'

📊 Token Change Report

Comparing origin/mainHEAD

Summary

Metric Value
📈 Total Change +15,302 tokens (+2787%)
Before 549 tokens
After 15,851 tokens
Files Changed 22

Changed Files

File Before After Change
plugin/skills/azure-prepare/references/services/app-service/templates/web-api.md - 1,243 +1243
plugin/skills/azure-prepare/references/services/app-service/templates/web-app.md - 1,233 +1233
plugin/skills/azure-prepare/references/services/app-service/templates/recipes/composition.md - 1,215 +1215
plugin/skills/azure-prepare/references/services/app-service/templates/recipes/sql/source/python.md - 1,122 +1122
plugin/skills/azure-prepare/references/services/app-service/templates/recipes/cosmos/README.md - 921 +921
plugin/skills/azure-prepare/references/services/app-service/templates/recipes/sql/README.md - 888 +888
plugin/skills/azure-prepare/references/services/app-service/templates/recipes/redis/README.md - 830 +830
plugin/skills/azure-prepare/references/services/app-service/templates/recipes/auth/README.md - 786 +786
plugin/skills/azure-prepare/references/services/app-service/templates/recipes/sql/source/nodejs.md - 769 +769
plugin/skills/azure-prepare/references/services/app-service/templates/recipes/sql/source/dotnet.md - 746 +746
plugin/skills/azure-prepare/references/services/app-service/templates/recipes/redis/source/python.md - 737 +737
plugin/skills/azure-prepare/references/services/app-service/templates/recipes/README.md - 699 +699
plugin/skills/azure-prepare/references/services/app-service/templates/selection.md - 654 +654
plugin/skills/azure-prepare/references/services/app-service/templates/recipes/auth/source/nodejs.md - 624 +624
plugin/skills/azure-prepare/references/services/app-service/templates/recipes/redis/source/nodejs.md - 561 +561
plugin/skills/azure-prepare/references/services/app-service/templates/recipes/auth/source/python.md - 552 +552
plugin/skills/azure-prepare/references/services/app-service/templates/recipes/redis/source/dotnet.md - 420 +420
plugin/skills/azure-prepare/references/services/app-service/templates/recipes/auth/source/dotnet.md - 343 +343
plugin/skills/azure-prepare/references/services/app-service/templates/recipes/cosmos/source/dotnet.md - 325 +325
plugin/skills/azure-prepare/references/services/app-service/templates/recipes/cosmos/source/nodejs.md - 313 +313
plugin/skills/azure-prepare/references/services/app-service/templates/recipes/cosmos/source/python.md - 283 +283
plugin/skills/azure-prepare/references/services/app-service/README.md 549 587 +38 (+7%)

@github-copilot-for-azure/scripts@1.0.0 tokens
node --import tsx src/tokens/cli.ts check --markdown

📊 Token Limit Check Report

Checked: 605 files
Exceeded: 90 files

⚠️ Files Exceeding Token Limits

File Tokens Limit Over By
.github/skills/analyze-skill-issues/SKILL.md 2109 500 +1609
.github/skills/analyze-test-run/SKILL.md 2471 500 +1971
.github/skills/file-test-bug/SKILL.md 628 500 +128
.github/skills/sensei/README.md 3531 2000 +1531
.github/skills/sensei/SKILL.md 3026 500 +2526
.github/skills/sensei/references/EXAMPLES.md 3701 2000 +1701
.github/skills/sensei/references/LOOP.md 4181 2000 +2181
.github/skills/sensei/references/SCORING.md 4299 2000 +2299
.github/skills/skill-authoring/SKILL.md 839 500 +339
plugin/skills/airunway-aks-setup/SKILL.md 1025 500 +525
plugin/skills/appinsights-instrumentation/SKILL.md 911 500 +411
plugin/skills/azure-ai/SKILL.md 820 500 +320
plugin/skills/azure-aigateway/SKILL.md 1261 500 +761
plugin/skills/azure-aigateway/references/policies.md 2342 2000 +342
plugin/skills/azure-cloud-migrate/SKILL.md 848 500 +348
plugin/skills/azure-cloud-migrate/references/services/container-apps/cloudrun-deployment-guide.md 2029 2000 +29
plugin/skills/azure-cloud-migrate/references/services/container-apps/deployment-guide.md 2458 2000 +458
plugin/skills/azure-cloud-migrate/references/services/container-apps/fargate-deployment-guide.md 2587 2000 +587
plugin/skills/azure-cloud-migrate/references/services/functions/lambda-to-functions.md 2600 2000 +600
plugin/skills/azure-cloud-migrate/references/services/functions/runtimes/javascript.md 2181 2000 +181
plugin/skills/azure-compliance/SKILL.md 1188 500 +688
plugin/skills/azure-compute/SKILL.md 1090 500 +590
plugin/skills/azure-compute/workflows/vm-recommender/vm-recommender.md 2631 2000 +631
plugin/skills/azure-compute/workflows/vm-troubleshooter/vm-troubleshooter.md 2509 2000 +509
plugin/skills/azure-cost/SKILL.md 1980 500 +1480
plugin/skills/azure-deploy/SKILL.md 1645 500 +1145
plugin/skills/azure-deploy/references/pre-deploy-checklist.md 4692 2000 +2692
plugin/skills/azure-deploy/references/recipes/azd/errors.md 4004 2000 +2004
plugin/skills/azure-deploy/references/troubleshooting.md 2038 2000 +38
plugin/skills/azure-diagnostics/SKILL.md 1423 500 +923
plugin/skills/azure-enterprise-infra-planner/SKILL.md 1002 500 +502
plugin/skills/azure-enterprise-infra-planner/references/constraints/compute-apps.md 2022 2000 +22
plugin/skills/azure-hosted-copilot-sdk/SKILL.md 1263 500 +763
plugin/skills/azure-kubernetes/SKILL.md 2606 500 +2106
plugin/skills/azure-kubernetes/azure-kubernetes-automatic-readiness/SKILL.md 3609 500 +3109
plugin/skills/azure-kusto/SKILL.md 2152 500 +1652
plugin/skills/azure-messaging/SKILL.md 821 500 +321
plugin/skills/azure-prepare/SKILL.md 3359 500 +2859
plugin/skills/azure-prepare/references/aspire.md 4617 2000 +2617
plugin/skills/azure-prepare/references/plan-template.md 2617 2000 +617
plugin/skills/azure-prepare/references/recipes/azd/aspire.md 2275 2000 +275
plugin/skills/azure-prepare/references/recipes/azd/terraform.md 3555 2000 +1555
plugin/skills/azure-prepare/references/research.md 2274 2000 +274
plugin/skills/azure-prepare/references/resources-limits-quotas.md 3322 2000 +1322
plugin/skills/azure-prepare/references/security.md 2147 2000 +147
plugin/skills/azure-prepare/references/services/functions/bicep.md 3127 2000 +1127
plugin/skills/azure-prepare/references/services/functions/templates/recipes/composition.md 2813 2000 +813
plugin/skills/azure-prepare/references/services/functions/terraform.md 3404 2000 +1404
plugin/skills/azure-prepare/references/services/sql-database/bicep.md 2037 2000 +37
plugin/skills/azure-quotas/SKILL.md 2821 500 +2321
plugin/skills/azure-quotas/references/commands.md 2644 2000 +644
plugin/skills/azure-resource-lookup/SKILL.md 1394 500 +894
plugin/skills/azure-resource-visualizer/SKILL.md 2122 500 +1622
plugin/skills/azure-storage/SKILL.md 1228 500 +728
plugin/skills/azure-upgrade/SKILL.md 1249 500 +749
plugin/skills/azure-upgrade/references/languages/java/INSTRUCTION.md 2724 2000 +724
plugin/skills/azure-upgrade/references/languages/java/package-specific/com.microsoft.azure.management.md 2215 2000 +215
plugin/skills/azure-upgrade/references/languages/java/templates/PLAN_TEMPLATE.md 2411 2000 +411
plugin/skills/azure-upgrade/references/languages/java/templates/PROGRESS_TEMPLATE.md 2315 2000 +315
plugin/skills/azure-upgrade/references/languages/java/templates/SUMMARY_TEMPLATE.md 2190 2000 +190
plugin/skills/azure-upgrade/references/services/functions/automation.md 3463 2000 +1463
plugin/skills/azure-upgrade/references/services/functions/consumption-to-flex.md 2773 2000 +773
plugin/skills/azure-validate/SKILL.md 950 500 +450
plugin/skills/entra-agent-id/SKILL.md 4001 500 +3501
plugin/skills/entra-app-registration/SKILL.md 2070 500 +1570
plugin/skills/entra-app-registration/references/api-permissions.md 2545 2000 +545
plugin/skills/entra-app-registration/references/cli-commands.md 2211 2000 +211
plugin/skills/entra-app-registration/references/console-app-example.md 2752 2000 +752
plugin/skills/entra-app-registration/references/oauth-flows.md 2375 2000 +375
plugin/skills/microsoft-foundry/SKILL.md 3840 500 +3340
plugin/skills/microsoft-foundry/foundry-agent/create/create.md 4315 2000 +2315
plugin/skills/microsoft-foundry/foundry-agent/create/references/toolbox.md 2851 2000 +851
plugin/skills/microsoft-foundry/foundry-agent/deploy/deploy.md 6133 2000 +4133
plugin/skills/microsoft-foundry/foundry-agent/eval-datasets/eval-datasets.md 2494 2000 +494
plugin/skills/microsoft-foundry/foundry-agent/eval-datasets/references/generate-seed-dataset.md 2088 2000 +88
plugin/skills/microsoft-foundry/foundry-agent/eval-datasets/references/trace-to-dataset.md 4325 2000 +2325
plugin/skills/microsoft-foundry/foundry-agent/invoke/invoke.md 2084 2000 +84
plugin/skills/microsoft-foundry/foundry-agent/observe/observe.md 2941 2000 +941
plugin/skills/microsoft-foundry/foundry-agent/observe/references/continuous-eval.md 3860 2000 +1860
plugin/skills/microsoft-foundry/foundry-agent/trace/references/kql-templates.md 2701 2000 +701
plugin/skills/microsoft-foundry/models/deploy-model/SKILL.md 1640 500 +1140
plugin/skills/microsoft-foundry/models/deploy-model/capacity/SKILL.md 1739 500 +1239
plugin/skills/microsoft-foundry/models/deploy-model/customize/SKILL.md 2235 500 +1735
plugin/skills/microsoft-foundry/models/deploy-model/customize/references/customize-workflow.md 3335 2000 +1335
plugin/skills/microsoft-foundry/models/deploy-model/preset/SKILL.md 1226 500 +726
plugin/skills/microsoft-foundry/models/deploy-model/preset/references/preset-workflow.md 5534 2000 +3534
plugin/skills/microsoft-foundry/quota/quota.md 2288 2000 +288
plugin/skills/microsoft-foundry/quota/references/capacity-planning.md 2080 2000 +80
plugin/skills/microsoft-foundry/references/agent-metadata-contract.md 2373 2000 +373
plugin/skills/microsoft-foundry/references/sdk/foundry-sdk-py.md 2162 2000 +162

Consider moving content to references/ subdirectories.


Automated token analysis. See skill authoring guidelines for best practices.

@kvenkatrajan kvenkatrajan left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Code Review — PR #1635: Gap-1: App Service Develop (C → A) — Templates + composition + multi-language

✅ What Looks Good

  • Composable recipe architecture is excellent — The "base template + additive recipe" pattern avoids synthesizing IaC from scratch, prevents LLM hallucination of Bicep/Terraform, and is the right abstraction for multi-integration support.
  • RBAC role GUIDs are hardcoded in every recipe — Cosmos, SQL, and Redis recipes specify exact GUIDs (e.g., fbdf93bf-... for Cosmos DB Account Reader). This is critical for preventing the LLM from guessing role IDs.
  • Managed identity by default, zero passwords — Every recipe uses DefaultAzureCredential and explicitly forbids connection strings with passwords. Strong security posture.
  • Decision tree routing in selection.md — Ordered indicators with clear fallthrough logic follows the recipe-based selective loading pattern used by azure-deploy and azure-prepare.
  • Multi-language coverage — C#, Python, Node.js, and Java examples where applicable. Follows the repo convention for broad runtime support.

🟠 High (3 findings)

1. Orphaned file tree — no link chain from SKILL.md or app-service/README.md

File: plugin/skills/azure-prepare/references/services/app-service/README.md (not modified in this PR)

Issue: The existing app-service/README.md has no link to templates/selection.md (the entry point for all 11 new files). Since references are JIT-loaded via explicit markdown links, the agent will never discover these files during a typical azure-prepare flow. The entire templates directory tree is unreachable.

Current link chain: SKILL.md → ... → app-service/README.mdbicep.md, deployment-slots.md, scaling.md ❌ no templates/

Suggested Fix: Add a link in app-service/README.md under References or a new "Templates" section:

## Templates

For App Service templates with composable recipes, see [Template Selection](templates/selection.md).

2. Seven of 11 reference files exceed the 1,000-token soft limit

Files and token estimates:

File Tokens Over limit
auth/README.md ~1,304 1.3×
web-app.md ~1,244 1.2×
cosmos/README.md ~1,128 1.1×
redis/README.md ~1,126 1.1×
web-api.md ~1,124 1.1×
composition.md ~1,069 1.1×
sql/source/python.md ~1,049 1.0×

Issue: Per skill-authoring guidelines, reference files should be <1,000 tokens each. While none are catastrophically over, 7/11 files exceeding the limit is a systematic pattern. The largest offender (auth/README.md at 1,304 tokens) has 3 full language code examples embedded inline.

Suggested Fix:

  • auth/README.md: Split language examples into auth/source/dotnet.md, auth/source/python.md, auth/source/nodejs.md (matching the sql/ pattern)
  • web-api.md / web-app.md: Move Dockerfile examples into a shared dockerfiles.md reference
  • cosmos/README.md / redis/README.md: Split source code into source/{lang}.md sub-files

3. azure-prepare SKILL.md version not bumped

File: plugin/skills/azure-prepare/SKILL.md (not modified in this PR)

Issue: Adding 11 new reference files modifies the azure-prepare skill. Per repo convention: "version must be bumped in the same PR that modifies the skill." Current version is 1.1.4.

Suggested Fix: Bump to 1.1.5 in SKILL.md frontmatter.


🟡 Medium (4 findings)

4. selection.md uses plain-text references instead of markdown links

File: templates/selection.md (lines ~11, ~47)

Issue: References to web-api.md and web-app.md are plain text — (see web-app.md) and (see web-api.md) — not markdown links [web-app.md](web-app.md). JIT reference loading requires explicit markdown link syntax [text](path) to discover and load files.

Suggested Fix:

- └─► YES → web-app base template (see web-app.md)
+ └─► YES → web-app base template (see [web-app.md](web-app.md))

5. DRY violation — "Critical Rules" duplicated across two files

Files: selection.md (lines 57-62) and composition.md (lines 129-135)

Issue: Nearly identical 6-7 rule lists appear in both files. When rules evolve, both need updating — this is the classic DRY maintenance trap.

Suggested Fix: Keep the canonical rules in composition.md (the authoritative process document). In selection.md, replace with a reference: > See [Critical Rules](recipes/composition.md#critical-rules).

6. Inconsistent source code organization across recipes

Files: sql/source/dotnet.md, sql/source/python.md vs auth/README.md, cosmos/README.md, redis/README.md

Issue: The SQL recipe properly splits per-language examples into source/{lang}.md sub-files. Auth, Cosmos, and Redis recipes embed all language examples directly in their README.md. This inconsistency inflates token counts (contributing to finding #2) and makes maintenance harder.

Suggested Fix: Adopt the source/{lang}.md pattern consistently across all recipes.

7. Missing microsoftgraph Bicep extension declaration

File: auth/README.md (line ~56)

Issue: Uses resource appRegistration 'Microsoft.Graph/applications@v1.0' which requires the microsoftgraph Bicep extension declaration. Without it, Bicep compilation fails. Repo convention (documented in entra-app-registration skill) requires:

extension microsoftGraphV1_0

Suggested Fix: Add the extension declaration above the appRegistration resource block, or add a note stating the prerequisite.


🟢 Low (3 findings)

8. Missing Node.js source example for SQL recipe

Files: sql/source/ (only contains dotnet.md and python.md)

Issue: Cosmos and Redis recipes include Node.js examples, but the SQL recipe has no source/nodejs.md. Prisma or mssql driver examples would complete the language coverage.

Suggested Fix: Add sql/source/nodejs.md with a Prisma or tedious/mssql example.

9. Bash-specific ENV_NAME generation without PowerShell equivalent

Files: composition.md (line 33), web-api.md (line 159), web-app.md (line 166)

Issue: ENV_NAME="$(basename "$PWD" | tr '[:upper:]' '[:lower:]' | tr ' _' '-')-dev" is bash-only. Per repo conventions, non-trivial shell commands should have PowerShell equivalents.

Suggested Fix: Add PowerShell:

$ENV_NAME = "$(Split-Path -Leaf (Get-Location) | ForEach-Object { $_.ToLower() -replace '[ _]','-' })-dev"

10. "Strip the database layer" guidance is vague

File: web-api.md (line 16)

Issue: States "strip the database layer" from AZD templates that include Mongo by default, but provides no specifics on which files or sections to remove. An agent following this instruction may delete the wrong files.

Suggested Fix: Either list the specific files/modules to remove, or provide a recipe for "no-database" that clarifies the cleanup steps.


Summary

Priority Count
Critical 0
High 3
Medium 4
Low 3
Total 10

Overall Assessment: Comment

The composable recipe architecture is a strong, well-thought-out addition. The primary concerns are discoverability (finding #1 — orphaned files) and token budget compliance (finding #2 — 7/11 files over limit). Finding #1 is the most impactful since these files are invisible to the agent without a link chain fix. I'd recommend fixing findings #1, #3, and #4 before merge, and tracking #2 and #5-7 as fast-follows.

@jongio Jon Gallant (jongio) left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Three findings not covered by existing reviews. All other issues already caught by copilot-pull-request-reviewer and kvenkatrajan - solid coverage.

…ity, bicep schema tools, auth IaC classification, token refresh, source splits

Agent-Logs-Url: https://github.com/microsoft/GitHub-Copilot-for-Azure/sessions/d8b94e2b-3785-456d-8309-ed9a3a5b446c

Co-authored-by: jongio <2163001+jongio@users.noreply.github.com>

Copilot AI commented Apr 8, 2026

Copy link
Copy Markdown
Contributor

Code Review — PR #1635: Gap-1: App Service Develop (C → A) — Templates + composition + multi-language

✅ What Looks Good...

All findings addressed in cfeb750:

High:

Medium:

Low:

Copilot AI changed the title Gap-1: App Service Develop (C → A) — Templates + composition + multi-language fix(app-service-templates): address review feedback — discoverability, auth IaC, token refresh, source splits Apr 8, 2026

@jongio Jon Gallant (jongio) left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Round 2 addresses all previous findings - the source splits, auth reclassification, and token refresh patterns are solid improvements. Found a few issues in the new code that would cause runtime failures in Azure.

Also: PR has merge conflicts (mergeable_state: dirty) - needs a rebase before merge.

@kvenkatrajan

Copy link
Copy Markdown
Collaborator

Andrew Westgarth (@apwestgarth) - another one please

# Conflicts:
#	plugin/skills/azure-prepare/SKILL.md
#	plugin/skills/azure-prepare/references/services/app-service/README.md
@paulyuk

Copy link
Copy Markdown
Member Author

📌 Follow-up enhancement filed: #2148

After this PR ships, we plan to refactor App Service templates to use a dynamic MCP tool pattern (analogous to Manvir Kaur (@manvkaur)'s Functions work in #1949), which would replace ~1,995 lines of hardcoded templates with runtime fetches from Azure-Samples + 3-tier fallback. This is intentionally not blocking this PR — we want to ship the proven, hand-curated templates now and layer the optimization after.

- sql/source/python.md: replace one-shot token in attrs_before with
  SQLAlchemy do_connect event listener that fetches a fresh MI token
  per physical connection, so the pool stays valid past 1 hour.
  Also handle empty AZURE_CLIENT_ID by omitting client_id.
- redis/source/python.md: replace module-level singleton with
  get_cache() lazy/refreshing accessor; uses RLock to avoid deadlock
  with _get_token() and closes the prior client on rotation.
- auth/source/nodejs.md: pin jwt.verify() to algorithms: ['RS256']
  to match the Python version and prevent algorithm confusion.
- sql/source/nodejs.md: validate req.body for the POST /api/todos
  endpoint — require non-empty trimmed title (string) and validate
  isComplete is boolean if provided.
- composition.md: add per-language env-var table before the .NET
  ADO.NET connection-string example so Python/Node.js get the
  correct config (AZURE_SQL_SERVER+AZURE_SQL_DATABASE for Python,
  DATABASE_URL with sqlserver:// for Node/Prisma).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@paulyuk

Copy link
Copy Markdown
Member Author

Review Feedback Addressed

Latest commit (4bc9cd7) addresses all remaining Jon Gallant (@jongio) runtime-failure findings + merges main. Verified each unresolved thread against current code:

Fixes in this commit (5 files):

  • sql/source/python.md — Replaced one-shot token in attrs_before with SQLAlchemy do_connect event listener that fetches a fresh MI token per physical connection. Pool stays valid past 1 hour. Also handles empty AZURE_CLIENT_ID (was a footgun).
  • redis/source/python.md — Replaced module-level singleton cache = create_redis_client() with get_cache() lazy/refreshing accessor. Uses RLock (was Lock — would deadlock when _get_token() is called inside get_cache() lock). Closes prior client on rotation to avoid pool leaks.
  • auth/source/nodejs.md — Added algorithms: ['RS256'] to jwt.verify() to match the Python version and prevent algorithm confusion attacks.
  • sql/source/nodejs.md — Validate req.body for POST /api/todos: require non-empty trimmed title (string), validate isComplete is boolean if provided.
  • composition.md — Added per-language env-var table before the .NET ADO.NET connection-string example so Python (AZURE_SQL_SERVER + AZURE_SQL_DATABASE) and Node.js (DATABASE_URL with sqlserver:// for Prisma) get correct config.

Already addressed in earlier commits (verified, marking as resolved):

  • sql/source/python.md:38, 134 — Connection string format consistent: AZURE_SQL_CONNECTION_STRING is SQLAlchemy URL for local dev (matches .env example); Azure path uses managed identity with separate env vars
  • web-api.md:152azd-service-name = 'api' with explicit warning explaining the tag must match services.<name> in azure.yaml
  • web-api.md:133, auth/README.md:26, 62mcp_bicep_get_az_resource_type_schema tool guidance added at all flagged locations
  • sql/source/dotnet.md:56app.MapHealthChecks("/health") added with comment explaining

Merge conflict resolved

Conflicts in SKILL.md (version) and app-service/README.md (Templates section vs Common Data Backends section) resolved — kept upstream version placeholder, preserved both sections in the README.

Independent code review

Ran the changes through an independent rubber-duck review which caught the RLock deadlock and AZURE_CLIENT_ID="" footgun before push.

Jon Gallant (@jongio) kvenkatrajan Andrew Westgarth (@apwestgarth) — ready for re-review. CC @microsoft/ghcp4a.

@paulyuk

Copy link
Copy Markdown
Member Author

Review thread audit complete ✅

Just finished a full audit of every review thread on this PR. All 21/21 threads are now resolved.

  • 9 active threads → replied with commit reference + permalink to fix, then marked resolved
  • 12 outdated threads (line moved due to subsequent edits) → marked resolved

Thread-by-thread reply trail is in the conversation above; each reply links to the exact line in the current branch where the fix lives.

Jon Gallant (@jongio) Andrew Westgarth (@apwestgarth) — your earlier CHANGES_REQUESTED review on this PR is the only thing blocking merge now. CI ✅ green, merge ✅ clean, threads ✅ all resolved. Could you re-review and either approve or dismiss the stale CHANGES_REQUESTED?

@jongio Jon Gallant (jongio) left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Previous comments addressed. Nothing new to flag.

@JasonYeMSFT
JasonYeMSFT (JasonYeMSFT) merged commit 075a9ee into main May 4, 2026
13 checks passed
@JasonYeMSFT
JasonYeMSFT (JasonYeMSFT) deleted the pass-equity-gap-1 branch May 4, 2026 16:17
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.

8 participants