fix(vscode): Guard against bundle download corruption #9294
Conversation
The extension bundle and other CDN-hosted dependencies were streamed to disk without verifying what arrived. Truncated or corrupted downloads silently extracted, mainly affecting Microsoft.Azure.Functions.ExtensionBundle.Workflows. * Add downloadFileWithVerification: streams the file, counts bytes, computes MD5 inline, and asserts both against the response's Content-Length and Content-MD5 headers. Azure Blob Storage (which backs cdn.functions.azure.com) sets these on upload, so this catches CDN-edge corruption end-to-end with no publishing-pipeline changes. * Wrap downloads in a retry loop (default 3 attempts, exponential backoff). Retries network errors, 5xx responses, and DownloadIntegrityError; surfaces 4xx as fatal. * Fix latent bug in downloadAndExtractDependency: the axios.get(...).then(...) chain was never awaited, so callers' awaits resolved before the download started and write errors were not propagated. Now downloads complete before extraction, and errors bubble up to callers. * Telemetry: <dep>DownloadAttempts, ExpectedSize, ActualSize, Md5Match (true/skipped), DownloadDurationMs per attempt. * Treat missing Content-Length / Content-MD5 as advisory so non-Blob mirrors keep working. Applies to all callers of downloadAndExtractDependency (extension bundle, Func Core Tools, Node.js, .NET install script). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…rification, CDN E2E probe Phase 2-4 of the bundle integrity work. * Adds 3 azureLogicAppsStandard settings: useExperimentalExtensionBundle, experimentalExtensionBundleSourceUri, experimentalExtensionBundleVersion. When the toggle is on, downloadExtensionBundle never calls the public CDN for `latest'' so a local/preview bundle isn't silently overridden. * Extracts a vscode-free integrity helper (app/utils/integrity.ts) so the same verifier is used by binaries.ts and the new E2E probe. * On-disk hash verification: each download writes a sidecar .bundle-source-md5; on next startup we HEAD the public bundle zip and redownload if the sidecar is missing or stale. * New E2E phase (bundleCdnHealth.test.ts, E2E_MODE=bundleintegrityonly): pure-Mocha probe that fails loudly if the CDN ever stops emitting Content-Length / Content-MD5. Wired into the independentonly shard. * writeTestSettings() in run-e2e.js gains experimental-bundle options. * SKILL.md and docs/ai-setup/packages/vs-code-designer.md updated. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- bundleFeed: use membership test (localVersions.some(v === envVarVer)) instead of equality with latestLocalBundleVersion so the env-var pin is honored when on disk alongside other versions. - bundleFeed: add tryDownloadBundleAndWriteSidecar / tryFetchSourceIndex helpers that swallow 'package not present' errors (HTTP 4xx, network failures from isMissingPackageError) and surface them as fallback signals rather than fatal exceptions. - bundleFeed: when toggle is on, the experimental sourceUri is now attempted first (with index probe to detect pinNotInIndex), then falls back to the public CDN for the same pin / latest. Both source and public failing throws so the dev sees the failure. - bundleFeed: experimentalSourceFallback telemetry property records pinNotInIndex | zip404 | index404 | networkError reasons. - bundleFeed: 'fall through to public' path now downloads from PUBLIC_BUNDLE_BASE_URL, not the broken experimental baseUrl. - package.json: reword the three experimental settings to call out the master-toggle gating and the public-CDN safety net. - integrity: export isMissingPackageError shared helper. - bundleFeed.test: 8 new tests covering env-var membership + fallback matrix (zip404 / pinNotInIndex / index404 / networkError / both CDNs failing / toggle off ignores experimental settings). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…+ toasts When the extension activates and decides to (re)download the Logic Apps extension bundle, the user now sees a notification explaining what's happening rather than waiting silently while activation hangs. - bundleFeed: new downloadBundleWithProgress / tryDownloadBundleWithProgress helpers wrap every download call in vscode.window.withProgress with a context-specific title that names the version and the source CDN (public Azure CDN vs the configured private/experimental URL). - bundleFeed: when verifyLocalBundleHash returns sidecarMissing / sidecarMismatch we now showWarningMessage *before* redownloading so the user understands why the bundle is being replaced even though they didn't change anything. - bundleFeed: success toast (showInformationMessage) on completion. - bundleFeed: all download call sites (env-var pin, experimental pin, experimental cold-start, public-CDN fallback, public newer-version, corrupt-local redownload) now go through the new helpers. - bundleFeed.test: extend vscode mock with window.withProgress (calls task immediately), showWarningMessage, showInformationMessage, and ProgressLocation. Two new tests assert the corruption warning + the newer-version progress notification render with the expected copy. 64 → 66 bundleFeed tests, 1063 → 1065 extension-unit tests passing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Future sessions opening a PR must read .github/pull_request_template.md (lowercase filename) before writing the body. Promote this from the generic 'opening a PR body' row to its own top-of-table row, and add it as Hard Rule #1 so it cannot be skipped. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…at applies Add explicit rule to release-scribe pattern in review-patterns.md: when authoring a PR body, copy the entire template structure (every section, every checkbox, every HTML comment hint) and only flip applicable boxes to [x]. Never delete unticked rows. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🤖 AI PR Validation ReportPR Review ResultsThank you for your submission! Here's detailed feedback on your PR title and body compliance:✅ PR Title
✅ Commit Type
|
| Section | Status | Recommendation |
|---|---|---|
| Title | ✅ | Optional cleanup: remove trailing whitespace |
| Commit Type | ✅ | None |
| Risk Level | Change to High; label/body should match | |
| What & Why | ✅ | None |
| Impact of Change | ✅ | None |
| Test Plan | ✅ | None |
| Contributors | Add contributors if applicable | |
| Screenshots/Videos | ✅ | None |
Overall: the PR body mostly passes, but the advised risk level is higher than the current selection. Please update the risk selection/label to High before merging.
Last updated: Mon, 22 Jun 2026 18:29:46 GMT
There was a problem hiding this comment.
Pull request overview
This PR hardens the VS Code designer extension’s activation-time download of Microsoft.Azure.Functions.ExtensionBundle.Workflows by adding integrity verification and improving the developer/testing story around experimental bundle sources. It also adds a new Mocha-only E2E phase to continuously validate the public CDN’s integrity headers and exercise the verifier logic without spinning up VS Code.
Changes:
- Added CDN download integrity verification (size + MD5) plus a local MD5 sidecar to detect and self-heal corrupt cached bundles on subsequent activations.
- Introduced opt-in experimental bundle settings with a “private source → public CDN” fallback that triggers only for missing-package style failures.
- Added a Mocha-only E2E probe (
bundleintegrityonly/ Phase 4.11) and documented the new phase in the VS Code E2E skill docs.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| docs/ai-setup/packages/vs-code-designer.md | Documents new E2E phase 4.11 and E2E_MODE=bundleintegrityonly. |
| apps/vs-code-designer/src/test/ui/SKILL.md | Adds the new CDN integrity probe test to the VS Code E2E “skill” inventory and mode table. |
| apps/vs-code-designer/src/test/ui/run-e2e.js | Adds a Mocha-only phase runner plus a fast-path mode for bundleintegrityonly, and wires the probe into independentonly. |
| apps/vs-code-designer/src/test/ui/bundleCdnHealth.test.ts | New live CDN probe validating Content-Length/Content-MD5 on the bundle zip and a small verified download. |
| apps/vs-code-designer/src/package.json | Adds three new VS Code settings for experimental bundle selection and source URI/version. |
| apps/vs-code-designer/src/constants.ts | Adds setting keys and the MD5 sidecar filename constant. |
| apps/vs-code-designer/src/app/utils/integrity.ts | New vscode-free download verifier + helper utilities (fetchExpectedMd5, retry logic, missing-package classification). |
| apps/vs-code-designer/src/app/utils/bundleFeed.ts | Integrates verification, sidecar checks, experimental source resolution + fallback chain, and user-visible progress/toasts. |
| apps/vs-code-designer/src/app/utils/binaries.ts | Routes all dependency downloads through the verifier and propagates integrity results/telemetry. |
| apps/vs-code-designer/src/app/utils/test/bundleFeed.test.ts | Updates/adds unit tests for sidecar verification, progress/warning UX, and experimental fallback behavior. |
| apps/vs-code-designer/src/app/utils/test/binaries.test.ts | Adds unit tests for downloadFileWithVerification behavior (MD5/size verification, retry rules, telemetry). |
| .squad/knowledge/review-patterns.md | Tightens PR-body guidance: preserve template sections/checkboxes verbatim. |
| .squad/knowledge/INDEX.md | Updates knowledge index triggers and hard rules around PR body editing. |
…esponses Reported by user: every dotnet SDK install fails 3x with Download integrity check failed for https://dot.net/v1/dotnet-install.ps1: size mismatch (expected 24942, got 76680). Root cause: dot.net/v1/dotnet-install.ps1 is served gzipped by the CDN. axios (Node) sends Accept-Encoding: gzip, ... by default and auto-decompresses the stream. Our Content-Length check then compared the gzipped header value (24942) against the decoded bytes piped to disk (76680) and threw DownloadIntegrityError on every attempt. This is a real regression introduced by Phase 5: dotnet install + any text dependency the CDN gzips at the edge has been broken since that ship. Bundle zips (binary, not gzipped) were not affected, which is why E2E missed it. Fix: - integrity.ts: force Accept-Encoding: identity + decompress: false on the axios GET so Content-Length reflects the actual transferred bytes. - integrity.ts: defensive — if the server returns Content-Encoding anyway, skip the size check (Content-Length is meaningless next to decoded bytes). MD5 is still verified when present. - integrity.ts: same Accept-Encoding: identity on the fetchExpectedMd5 HEAD. Tests: - binaries.test.ts: 3 new cases — (a) gzip response with mismatched Content-Length succeeds, (b) un-encoded mismatched Content-Length still throws DownloadIntegrityError, (c) Accept-Encoding: identity header is sent on every request. - bundleCdnHealth.test.ts: new live E2E case that round-trips dot.net/v1/dotnet-install.ps1 end-to-end via downloadFileWithVerification and sanity-checks the script body. Catches future CDN/axios drift on the actual URL we install from. 109 binaries+bundleFeed unit tests passing. 5/5 bundleintegrityonly live E2E tests passing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
verifyLocalBundleHash only compared the stored sidecar string to the CDN's HEAD
Content-MD5, so any post-download mutation of the extracted bundle on disk (manual
edits, disk bit-rot, AV restore, partial overwrite, interrupted install) silently
passed verification. The user can end up running a corrupt 400 MB bundle indefinitely.
Upgrades the sidecar to JSON { version, sourceMd5, contentHash } and adds
computeBundleContentHash — a deterministic streaming sha256 over the extracted tree
(POSIX-normalized relative paths, sidecar self-excluded, <relPath>\\0<size>\\0<bytes>\\0
framing). verifyLocalBundle now recomputes that hash on every activation before it
falls through to the existing publisher-MD5 HEAD check.
New result 'contentMismatch' joins the existing Phase 6 corruption-notification path:
warning toast + progress notification + redownload. Legacy bare-MD5 sidecars (and JSON
sidecars missing contentHash) collapse into 'sidecarMissing' so the one-time migration
stays silent — those users haven't actually hit a corruption event.
Rejected alternatives (kept here for future readers):
- range-GET the zip central directory from the CDN: regresses offline activation
- keep source.zip on disk: ~400 MB per cached version, 1+ GB redundancy with 2-3 cached
Unit coverage: 7 new tests in bundleContentHash.test.ts (determinism, byte/add/remove
sensitivity, sidecar exclusion, path sensitivity) + 3 new full-pipeline cases in
bundleFeed.test.ts (legacy migration silent, JSON contentHash mismatch fires toast +
redownload, matching JSON sidecar stays 'passed'). 1078 unit tests pass, 5/5
bundleintegrityonly E2E pass.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…dle download main.ts fires downloadExtensionBundle as a background task during activation so the UI stays snappy. When the bundle is corrupt or missing, the re-extract can take 10+ seconds — and if the user opens a workflow during that window, startDesignTimeApi spawns func.exe against the half-extracted bundle folder. On Windows that locks the folder, kills the design-time host, and leaves the bundle in a half-extracted state until the next activation. Observed in the wild: 5:48:24 PM: Re-downloading Logic Apps extension bundle 1.165.52... 5:48:28 PM: Starting Design Time Api... ← user opened workflow 5:48:29 PM: Stopping Design Time Api... ← crashed Successfully downloaded ... ← download finally finished Fix: add a module-level in-flight tracker in bundleFeed.ts. downloadExtensionBundle dedupes concurrent callers and exposes: - waitForExtensionBundleReady(): blocks on the in-flight work (noop otherwise) - isExtensionBundleDownloadInFlight(): sync probe for log-gating startDesignTimeApi awaits waitForExtensionBundleReady() immediately before spawning func.exe, with a one-line output-channel message so the user sees what's happening. main.ts also gets a .catch() so background download failures surface in the log instead of becoming unhandled rejections. New unit test: concurrent downloadExtensionBundle calls dedupe (only one downloadAndExtractDependency call), waitForExtensionBundleReady blocks until that call completes, and the in-flight flag clears afterward. 1079/1079 unit tests pass. 5/5 bundleintegrityonly E2E pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
After downloadFileWithVerification confirms the zip itself, AdmZip.extractAllTo could leave a partial tree on disk if a file lock, antivirus quarantine, or disk pressure interrupted extraction mid-stream. We then wrote a content-hash sidecar over the partial tree, blessing the broken state as 'good'. Subsequent activations passed the sidecar check while func.exe failed to load missing assemblies. Phase 11 closes the gap: - New verifyExtractedZip walks the zip's central directory after extraction and asserts every non-directory entry exists on disk at the expected size. Throws BundleExtractionError with a discriminator (missing | sizeMismatch | empty). - extractDependency wraps cleanDirectory + extractAllTo + verifyExtractedZip in a 2-attempt retry loop that absorbs transient EBUSY/EPERM/EACCES locks and verification failures with a 750ms backoff. - downloadAndExtractDependency now tears down the partial targetFolder if extraction throws, so the next activation re-downloads from scratch instead of inheriting a corrupt tree. - downloadBundleAndWriteSidecar refuses to write a sidecar when the content hash is undefined (bundleDir vanished post-extract). Tests: 5 new unit cases in binaries.test.ts covering happy path, missing file, truncated file, empty extract dir, and empty zip. 1084/1084 vscode-designer unit tests pass; bundleintegrityonly E2E (5/5) green. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…terminate orphan func.exe
When a corrupt extension bundle is detected, the existing re-extract
pipeline failed in two ways on Windows:
1. AdmZip's overwrite mode only replaces files that exist in the new
zip. Stale files from the prior version remained on disk, so the
tree was a hybrid of new + old content even when extract appeared
to succeed.
2. When an orphan func.exe from a previous VS Code session held bundle
DLLs open, cleanDirectory + extractAllTo hit EPERM, the prior catch
block's rm-rf was silently swallowed, and activation continued
against the still-corrupt directory. Users saw 'No job functions
found' and unhealthy storage forever.
Fix:
- extractDependency now does fs.rmSync(targetFolder, recursive:true,
force:true) BEFORE extraction, so we always extract into a truly
empty directory. Stale files cannot survive the replace.
- If the delete throws EPERM/EBUSY/EACCES (i.e. the dir is locked),
downloadAndExtractDependency's catch invokes a new helper,
offerToTerminateOrphanFuncProcesses, that:
a) enumerates running func.exe PIDs via tasklist (Windows only)
b) filters out ones tracked by ext.designTimeInstances
c) prompts the user with a 'Terminate N process(es)' button
d) calls process.kill on accepted orphans, waits 1.5s
- After successful termination, extractDependency is retried once.
- Drop the prior destructive cleanup in the failure catch — leaving
the user with the prior (corrupt-but-locked) bundle is strictly
better than leaving them with no bundle.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…eady
After the orphan-func + delete-first fix, users hit a new symptom: the
bundle download visibly completed and the bundle was on disk, but the
design-time host was stuck forever on 'Waiting for Logic Apps extension
bundle download to complete'.
Root cause: the in-flight promise gate self-deadlocks.
downloadExtensionBundle()
inFlightBundleWork = new Promise(...) // resolves only in finally
downloadExtensionBundleCore()
downloadAndExtractDependency()
extractDependency() // ✓ succeeds
await startAllDesignTimeApis() // ← starts host
startDesignTimeApi()
await waitForExtensionBundleReady() // ← awaits the very
// promise above
finally: resolveInFlight() // ← never reached
The post-extract restart awaits the same in-flight promise its own
parent will only resolve once the restart finishes.
Fix: use Node AsyncLocalStorage to scope a 're-entrant' flag to the
async call-tree rooted at downloadExtensionBundle. waitForExtensionBundleReady
checks the store first — if we are inside the download's own scope,
return Promise.resolve() (the bundle is by definition already on disk).
Other concurrent design-time starts (different call-stacks) still
correctly await the in-flight promise.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…le install failed
Even after the delete-first + orphan-kill fix, when extract still fails
(e.g. user declines the terminate-orphan prompt), activation logged
'Azure Logic Apps Standard Runtime Dependencies validation and
installation completed successfully' and then func.exe spawned against
the absent/locked bundle. Result: 'No job functions found' + perpetual
unhealthy storage with no actionable error.
Root cause: the extension-bundle download is fire-and-forget from
main.ts, and neither validateAndInstallBinaries nor startDesignTimeApi
checked its outcome. waitForExtensionBundleReady resolved cleanly even
when the install threw.
Fix:
- bundleFeed.ts: track lastBundleInstallResult ('unknown'|'ok'|'failed')
+ lastBundleInstallError across the lifetime of downloadExtensionBundle.
Export a new helper, ensureExtensionBundleHealthy(), that awaits the
in-flight work and throws if the last attempt failed (with a clear,
actionable message naming orphan func.exe as the likely cause).
- startDesignTimeApi.ts: after the existing wait gate, call
ensureExtensionBundleHealthy(). Without a healthy bundle, refuse to
spawn func.exe — the existing error path surfaces the failure to the
user and avoids the silent 'No job functions found' rabbit hole.
- validateAndInstallBinaries.ts: as the last step of the validation
flow, await ensureExtensionBundleHealthy(). The bundle is part of
'runtime dependencies' from the user's perspective; if it failed to
install, validation should fail loudly rather than logging success.
- Updated the validateAndInstallBinaries.test.ts mock to include the
new export.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…te actually trips downloadExtensionBundleCore's outer try/catch swallowed every install error by returning false, defeating the lastBundleInstallResult bookkeeping added in the prior commit: the outer downloadExtensionBundle wrapper saw a successful resolved value, marked the install 'ok', and ensureExtensionBundleHealthy() then passed through. Result: 'Failed to install' was logged, validation immediately logged 'completed successfully', and func.exe spawned against the missing/corrupt bundle. Re-throw from the catch so the wrapper records 'failed' and downstream callers (validateAndInstallBinaries, startDesignTimeApi) refuse to proceed. Updated the one test that asserted the swallow-returns-false behavior to expect a rejection + 'failed' install result. Imports getLastBundleInstallResult for the assertion. All 1084 vs-code-designer unit tests pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When the extension bundle is corrupted, we delete the existing install and re-extract in place. On Windows this races with pending-deletion and with our own draining func.exe — rmSync silently leaves the dir behind, then mkdirSync at the same path throws EPERM and the install fails permanently in <1s. Fix by adding lock-wait wrappers around the rmSync/mkdirSync pair in extractDependency: - removeWithLockWait / mkdirWithLockWait poll for up to 30s on EPERM/EBUSY/EACCES, logging progress every ~5s. - After ~5s of persistent failure, prompt the user once to kill orphan func.exe processes (existing helper, now reused here). - stopAllDesignTimeApisAndWait now actually awaits process exit before the cleanup begins, instead of fire-and-forget SIGTERM. Adds 10 unit tests (1094 total now pass). No on-disk layout change — still extract in place. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
After the 30s lock-wait fix made re-extraction succeed, the post-install restart was still firing from inside `downloadAndExtractDependency` while `bundleDownloadScope` was active. That caused `startDesignTimeApi` to short-circuit the new health gate via the AsyncLocalStorage scope check, log a misleading `Waiting for bundle download to complete…` message, and then immediately spawn func.exe before `lastBundleInstallResult` settled to `'ok'` and before the sidecar was written. - Remove the extensionBundleId branch from binaries.ts `downloadAndExtractDependency` so it no longer triggers a restart inside the active download scope. - In `downloadExtensionBundle`, fire `startAllDesignTimeApis()` from the `finally` block via a dynamic import (avoids the circular dep with `startDesignTimeApi.ts`) only when the install succeeded and changed disk. Restart runs AFTER `inFlightBundleWork` is cleared and `lastBundleInstallResult` is settled. - Export `isInsideBundleDownloadScope()` from bundleFeed.ts and tighten the gate in startDesignTimeApi.ts so the `Waiting…` log is suppressed when the call originates from inside the bundle download scope (defensive — the new flow shouldn't reach it). Tests: 1096 passing (added 2 deferred-restart cases in bundleFeed.test.ts). No new TypeScript errors. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…e validating dependencies Drops the implicit trust in .bundle-source-md5 as a session-cached source of truth. ensureExtensionBundleHealthy() now recomputes the on-disk content hash via the new assertExtensionBundleOnDiskHealthy() helper on every activation, and synchronously kicks off a repair download when on-disk state has drifted (e.g. a user manually deleted a subfolder inside the installed bundle dir). If the repair doesn't restore integrity, the gate throws so validateAndInstallBinaries reports failure instead of silently spawning func.exe against a corrupt bundle. Three short-circuit paths in downloadExtensionBundleCore (env-var pinned local match, experimental pinned local match, experimental no-pin local latest) now run verifyLocalBundle first and fall through to a *Repair download on contentMismatch / sidecarMissing instead of returning false. Tests: +10 cases in bundleFeed.test.ts covering the new helper, the repair gate, and the three short-circuit verification paths. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The p41a prelaunch cleanup was deleting a valid restored NodeJs dependency because CI's extracted POSIX layout has bin/node directly under NodeJs. Probe that layout before falling back to nested node-* folders so strict setup does not force an unnecessary reinstall. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
❌ PR Validation ErrorAn error occurred while validating your PR. Please try again later or contact the maintainers. Error: API request failed with status 500 |
Strict p41a currently waits for the Workflows bundle sidecar after activation, but activation starts the bundle install in the background and only logs failures. Await the bundle install when LA_E2E_STRICT_DEPENDENCY_VALIDATION is enabled so fixture setup either starts with a healthy sidecar or fails on the real install error before downstream shards can run. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
❌ PR Validation ErrorAn error occurred while validating your PR. Please try again later or contact the maintainers. Error: API request failed with status 500 |
The Workflows bundle path could complete download/extract without writing .bundle-source-md5 when the download result had no source MD5, and sidecar write failures were logged but swallowed. Treat both cases as install failures so strict p41a surfaces the real setup error instead of timing out on a missing sidecar. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Avoid running the extraction progress message through the shell. The Linux shell treats the unquoted attempt parentheses as syntax, which prevented the Workflows extension bundle from extracting during strict p41a validation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Include file size when recomputing the Workflows bundle content hash in the E2E repair assertion so it matches the product sidecar contract. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
❌ PR Validation ErrorAn error occurred while validating your PR. Please try again later or contact the maintainers. Error: API request failed with status 500 |
Restore the verified Logic Apps extension bundle for p41b while keeping it independent from workspace fixtures. The create-workspace behavior shard only exercises wizard UI, so skip runtime/design-time validation there to avoid blocking the webview on first-run dependency checks. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Refactor VS Code E2E scenario artifact flags, route bundle repair through the scenario table, and add a bundle hash contract guard without weakening strict setup validation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
❌ PR Validation ErrorAn error occurred while validating your PR. Please try again later or contact the maintainers. Error: API request failed with status 500 |
Use the same raw QuickInput typing path for fallback command searches so p41a fixture setup does not fail when ExTester InputBox is temporarily non-interactable. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
❌ PR Validation ErrorAn error occurred while validating your PR. Please try again later or contact the maintainers. Error: API request failed with status 504 |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
❌ PR Validation ErrorAn error occurred while validating your PR. Please try again later or contact the maintainers. Error: API request failed with status 504 |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Require the Workflows bundle manifest to prove runtime files exist before backfilling missing sidecar metadata, and disable backfill for strict bundle health repair paths so tampered bundles redownload instead of being blessed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
❌ PR Validation ErrorAn error occurred while validating your PR. Please try again later or contact the maintainers. Error: API request failed with status 500 |
Use the shared robust QuickInput typing helper for create-workspace command selection so CI does not fail when VS Code keeps a hidden pooled quick-input widget during fallback searches. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
❌ PR Validation ErrorAn error occurred while validating your PR. Please try again later or contact the maintainers. Error: API request failed with status 500 |
Restore the create-workspace command palette typing path that passed before the helper swap, and reopen a fresh command palette before the fallback query so stale no-pick widgets are not reused in p41a setup fixtures. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…-dependency-downloads Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Commit Type
Risk Level
What & Why
Microsoft.Azure.Functions.ExtensionBundle.Workflowsis downloaded from a CDN at extension activation. When the CDN occasionally returns a truncated zip, the extension cached the partial file and failed later in opaque ways. There was also no way to test against an unreleased bundle locally, no fallback when a private/experimental CDN was misconfigured, and no user-visible signal during activation downloads.This PR adds end-to-end integrity verification (size + MD5), opt-in experimental bundle settings with a public-CDN safety net, and
withProgressnotifications so the user sees what is happening (and why a redownload is occurring).Impact of Change
Content-LengthandContent-MD5on download, and against an MD5 sidecar on every activation. Corrupt local copies are detected and replaced automatically. Users see a progress notification during downloads and a warning toast immediately before a corruption-triggered redownload, so silent activation hangs are gone. Three new VS Code settings (useExperimentalExtensionBundle,experimentalExtensionBundleSourceUri,experimentalExtensionBundleVersion) let users point at unreleased bundle builds without losing the public-CDN safety net. Bundles are now verified and repaired automatically for users.downloadFileWithVerification,verifyLocalBundleHash,fetchExpectedMd5, andisMissingPackageErrorhelpers inintegrity.ts.bundleFeed.tsgains aDownloadReason-drivenwithProgresswrapper used at every download call site, plus a private-to-public CDN fallback chain that only triggers on "package missing" errors (4xx / DNS), never on integrity failures. New E2E phasebundleintegrityonlyexercised viarun-e2e.js.Test Plan
bundleintegrityonlylive E2E phase 4/4 passing.Contributors
Screenshots/Videos