Skip to content

fix: detect workspace roots for azure.yaml service deps#290

Open
jongio wants to merge 4 commits into
mainfrom
fix/workspace-deps-detection
Open

fix: detect workspace roots for azure.yaml service deps#290
jongio wants to merge 4 commits into
mainfrom
fix/workspace-deps-detection

Conversation

@jongio
Copy link
Copy Markdown
Owner

@jongio jongio commented May 24, 2026

Problem

When all services in azure.yaml are part of a pnpm/npm/yarn workspace but the workspace root itself is not listed as a service, azd app deps (and azd app run) tried to install dependencies individually in each of the N workspace child directories. This caused 10 redundant pnpm install calls instead of 1, failures in non-verbose mode due to progress bar writer conflicts, and azd app run being completely broken on fresh clones or after node_modules cleanup.

Root Cause

detectProjectsFromAzureYaml correctly detected IsWorkspaceRoot on projects, but never set WorkspaceRoot on child projects. The existing FilterNodeProjects workspace handler treated all children as independent projects (since WorkspaceRoot was empty), bypassing the deduplication logic entirely.

Fix

Added linkWorkspaceChildren() that runs after project detection:

  1. For each non-root Node.js project, walks up from its directory to find a workspace root (bounded by the project root)
  2. Sets WorkspaceRoot on child projects so FilterNodeProjects correctly skips them
  3. If the workspace root is not already in the projects list (common, since it's usually not a service in azure.yaml), adds it implicitly

Result

Before: 10 individual pnpm install calls (all failing in non-verbose mode)
After: 1 pnpm install --prefer-offline --recursive at workspace root (~20s, succeeds)
Subsequent runs: instant skip (0.0s) via isDependenciesUpToDate cache

Testing

Verified on a pnpm workspace with 10 packages:

  • azd app deps from clean state (no node_modules): passes
  • azd app deps --no-cache: passes
  • azd app deps repeat (cached): instant skip
  • azd app run from clean state: deps pass, services start
  • azd app deps --dry-run: shows workspace root + children correctly

When services in azure.yaml are all part of a pnpm/npm/yarn workspace
but the workspace root itself is not listed as a service, the workspace
handler could not filter out children because WorkspaceRoot was never set.

This caused all N workspace packages to be installed individually instead
of a single install at the workspace root, leading to failures on Windows
where concurrent pnpm installs conflict.

The fix:
1. After detecting Node.js projects from azure.yaml services, walk up
   from each project directory to find its workspace root.
2. Set WorkspaceRoot on child projects so FilterNodeProjects can skip them.
3. If the workspace root is not already in the projects list, add it
   implicitly so it becomes the single install target.

Result: pnpm workspaces with 10+ packages now install once at the root
(~20s) instead of failing 10 individual installs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
github-actions Bot added a commit that referenced this pull request May 24, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 24, 2026

🚀 Website Preview

Your PR preview is ready!

📎 Preview URL: https://jongio.github.io/azd-app/pr/290/

This preview will be automatically cleaned up when the PR is closed.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 24, 2026

Codecov Report

❌ Patch coverage is 86.95652% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 57.10%. Comparing base (572585c) to head (cc4d3bc).

Files with missing lines Patch % Lines
cli/src/cmd/app/commands/core_deps.go 86.95% 3 Missing and 3 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #290      +/-   ##
==========================================
+ Coverage   57.06%   57.10%   +0.04%     
==========================================
  Files         177      177              
  Lines       22837    22883      +46     
==========================================
+ Hits        13031    13068      +37     
- Misses       9000     9006       +6     
- Partials      806      809       +3     
Flag Coverage Δ
unittests 57.10% <86.95%> (+0.04%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
cli/src/cmd/app/commands/core_deps.go 61.86% <86.95%> (+4.02%) ⬆️

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Fix path mismatch: when a workspace root is already in the project list
(with a relative Dir), children now get WorkspaceRoot set to the root's
original Dir value instead of an absolute path. This ensures
FilterNodeProjects can match them correctly.

Add 10 unit tests covering empty input, no workspace root above children,
discovery of missing roots, existing root using original Dir for path
consistency, all-roots input unchanged, pnpm-workspace.yaml detection,
package.json workspaces field detection, boundary enforcement (stops at
project root), no workspace found returns empty, and start dir being itself
the workspace root.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
github-actions Bot added a commit that referenced this pull request May 24, 2026
Fixes govulncheck CI failure caused by vulnerability in x/net/idna
(Punycode label validation bypass). Bumps x/net v0.54.0 -> v0.55.0
and x/sys v0.44.0 -> v0.45.0.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
github-actions Bot added a commit that referenced this pull request May 24, 2026
The 'local-only services do not use Azure logs' test was failing ~80%
of runs due to a race between React state updates and Connect-RPC's
async transport setup. The issue manifested in two ways:

1. The in-page fetch intercept was not decoding request bodies correctly.
   Connect-ES serializes bodies as Uint8Array even in JSON mode, but the
   interceptor was checking for string-typed bodies only. This meant the
   service name could never be extracted, causing __azureLogsCalledFor to
   always contain empty strings instead of 'api'.

2. The test assertion relied on this tracking array to verify which
   services triggered Azure log fetches.

Fix: decode Uint8Array/ArrayBuffer request bodies with TextDecoder
before parsing the JSON. Also apply the same fix to the GetLogs (local
mode) interceptor for consistency.

Additionally:
- Add session-token fetch intercept in addInitScript to eliminate an
  async microtask gap in the Connect interceptor chain
- Add never-closing stream intercepts for StreamBroadcast,
  StreamStateTransitions, StreamLocalLogs, and StreamAzureLogs to
  prevent reconnection floods
- Remove temporary debug instrumentation from useLogsStream.ts and
  useHealthStream.ts

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
github-actions Bot added a commit that referenced this pull request May 25, 2026
@github-actions
Copy link
Copy Markdown
Contributor

🚀 Test This PR

A preview build (0.14.0-pr290) is ready for testing!

🌐 Website Preview

Live Preview: https://jongio.github.io/azd-app/pr/290/

One-Line Install (Recommended)

PowerShell (Windows):

iex "& { $(irm https://raw.githubusercontent.com/jongio/azd-app/main/cli/scripts/install-pr.ps1) } -PrNumber 290 -Version 0.14.0-pr290"

Bash (macOS/Linux):

curl -fsSL https://raw.githubusercontent.com/jongio/azd-app/main/cli/scripts/install-pr.sh | bash -s 290 0.14.0-pr290

Uninstall

When you're done testing:

PowerShell (Windows):

iex "& { $(irm https://raw.githubusercontent.com/jongio/azd-app/main/cli/scripts/uninstall-pr.ps1) } -PrNumber 290"

Bash (macOS/Linux):

curl -fsSL https://raw.githubusercontent.com/jongio/azd-app/main/cli/scripts/uninstall-pr.sh | bash -s 290

Build Info:

What to Test:
Please review the PR description and test the changes described there.

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.

1 participant