Add "watch" sub-mode for execution context#18863
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 18863Or
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 18863" |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Pull request overview
Adds an experimental run sub-mode model so integrations can distinguish normal and watch execution.
Changes:
- Adds
RunSubModeto hosting execution context APIs. - Reads the watch sub-mode from AppHost configuration.
- Adds tests and updates polyglot snapshots and the Project v2 plan.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
src/Aspire.Hosting/RunSubMode.cs |
Defines normal and watch sub-modes. |
src/Aspire.Hosting/DistributedApplicationExecutionContextOptions.cs |
Adds sub-mode configuration. |
src/Aspire.Hosting/DistributedApplicationExecutionContext.cs |
Exposes the selected sub-mode. |
src/Aspire.Hosting/DistributedApplicationBuilder.cs |
Parses sub-mode configuration. |
tests/Aspire.Hosting.Tests/OperationModesTests.cs |
Tests configuration and operation behavior. |
tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.ts |
Updates TypeScript output. |
tests/Aspire.Hosting.CodeGeneration.Rust.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.rs |
Updates Rust output. |
tests/Aspire.Hosting.CodeGeneration.Python.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.py |
Updates Python output. |
tests/Aspire.Hosting.CodeGeneration.Java.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.java |
Updates Java output. |
tests/Aspire.Hosting.CodeGeneration.Go.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.go |
Updates Go output. |
docs/plans/project-v2-csharpprogram-watch.md |
Records Session 3 completion. |
karolz-ms
left a comment
There was a problem hiding this comment.
Found 3 issues: 1 failing generated snapshot and 2 correctness issues.
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
- Harden RunSubMode parsing: match the declared enum names case-insensitively
instead of Enum.TryParse, which also accepted numeric ("42") and
comma-separated ("Normal,Watch") inputs and bypassed the documented Normal
fallback.
- Normalize RunSubMode to Normal for non-run operations in the
DistributedApplicationExecutionContext options-constructor so a Publish
context can never report Watch.
- Regenerate the TypeScript TwoPassScanning codegen snapshot so it matches the
generated output (fixes the failing codegen test); the previously hand-edited
wording was not reproducible.
- Fix unbalanced inline-code backticks in the Session 3 plan notes and correct
the now-stale Enum.TryParse description.
- Add regression tests: numeric and compound config values fall back to Normal,
and direct Publish construction reports Normal.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt. |
|
/azp run |
Tests selector (audit mode)The full test matrix and all jobs still run in audit mode. The tests and jobs below are what selective CI would run under enforcement. 48 / 100 test projects · 4 jobs, from 10 changed files. Selected test projects (48 / 100)
Selected jobs (4)
How these were chosen — grouped by what changed
🔧 show 38
🧪 📦 affected project 🧪 🧪 🧪 🧪 🧪 Job reasons
Selection computed for commit |
PR Testing ReportPR Information
Artifact Version Verification
Changes AnalyzedFiles Changed
Change Categories
Test Scenarios ExecutedScenario 1: Execution-context source testsObjective: Verify normal/watch parsing, case insensitivity, invalid-value fallback, and publish isolation in the hosting implementation. Coverage Type: Unit, happy path, unhappy path, boundary Status: ✅ Passed Command: dotnet test --project tests/Aspire.Hosting.Tests/Aspire.Hosting.Tests.csproj \
--no-launch-profile -- \
--filter-class '*.OperationModesTests' \
--filter-not-trait 'quarantined=true' \
--filter-not-trait 'outerloop=true'Result: 13 passed, 0 failed, 0 skipped. Evidence: Scenario 2: Polyglot API generationObjective: Verify the additive Coverage Type: Snapshot/code generation Status: ✅ Passed Method: Results:
Evidence: Scenario 3: Dogfood artifact and templateObjective: Verify the downloadable PR artifact matches the PR head and can create a fresh C# AppHost from the PR package hive. Coverage Type: Artifact/template smoke Status: ✅ Passed Steps:
Evidence: Scenario 4: Default run modeObjective: Verify an unconfigured AppHost reports the backward-compatible normal sub-mode. Coverage Type: Happy path Status: ✅ Passed Observed: The detached AppHost started successfully, its dashboard login endpoint returned HTTP 302, and Evidence: Scenario 5: Watch run modeObjective: Verify the inherited Coverage Type: Happy path and casing boundary Status: ✅ Passed Observed: The detached AppHost started successfully, its dashboard login endpoint returned HTTP 302, and Evidence: Scenario 6: Invalid numeric sub-modeObjective: Verify an undeclared numeric value cannot leak through Coverage Type: Unhappy path Status: ✅ Passed Input: Expected Outcome: The AppHost starts normally and reports Observed: The detached AppHost started successfully, its dashboard login endpoint returned HTTP 302, and Evidence: Scenario 7: Publish-mode isolationObjective: Verify a watch configuration cannot put a publish invocation into watch sub-mode. Coverage Type: Boundary Status: ✅ Passed Input: Expected Outcome: The publish invocation reports Observed: The publish pipeline completed all 4 steps successfully. Evidence: Summary
Overall Result✅ PR VERIFIED The tested hosting-core behavior, public experimental API consumption, generated-language snapshots, downloadable artifact, and runtime configuration paths all behaved as intended. This PR intentionally adds only the core run sub-mode state; |
|
AI code review done earlier #18863 (review) all issues addressed |
|
Why is this top level on the execution context? Just a formal API for exposing how the apphost itself was launched? I would expect we keep watching of the apphost and watching of the individual resource types separate. |
|
@davidfowl in my mind the "watch mode" is primarily about how individual resources are launched (enabling quick iteration during service development). It affects decisions about how resources are configured and launched that are made pretty deeply inside Aspire hosting package(s). That is why I have chosen (via this PR) to put that information in the application execution context. The app host watch mode/hot reload is interesting and useful, but I expect it to be used less frequently (as in, close-loop iteration over app host code). Technically app host watch mode could be separated from resource watch mode, but I am not clear what a compelling scenario for doing this would be... ? |
|
A few plan related thoughts. I'd love to see an extra section in the markdown discussing at least possible future patterns for another language or two (i.e. what would supporting this for to optionally enable watch for JS or Go projects look like?). Especially that some services already default to running with the equivalent of watch (Vite projects, for example). I worry that we'll end up with an inconsistent experience where |
|
@karolz-ms See https://aspire.dev/app-host/hot-reload-and-watch/ I don't think we should expose an API for watch mode on the execution context. Watch for an individual resource can be configured on that resource in whatever way makes sense. If we want to build something for any resource then it needs to be outside of this project resource v2 scope. |
Description
Adds a run sub-mode concept (and a
watchsub-mode) so we can differentiate between the two and change how resources are launched.Part of "Project v2" work stream, #15710 specifically.
Checklist
<remarks />and<code />elements on your triple slash comments?