Add publish output verification#18876
Conversation
53a8131 to
5416177
Compare
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8963f49d-361e-4026-8676-d5caf3c24b51
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8963f49d-361e-4026-8676-d5caf3c24b51
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8963f49d-361e-4026-8676-d5caf3c24b51
5416177 to
1f63db2
Compare
PR Testing ReportPR Information
Artifact Version Verification
The PR head moved from Changes AnalyzedMain Surfaces
Change Categories
Test Scenarios ExecutedScenario 1: Current-head restore and local-hive buildObjective: Build the CLI, Hosting packages, templates, and Linux-x64 portable archive from the exact current PR head. Coverage Type: Build/artifact validation Status: ✅ Passed Results:
Evidence:
Scenario 2: Focused CLI verification testsObjective: Exercise the changed command, verification session, reconciliation, Git, path safety, compatibility, cleanup, and extension argument-forwarding logic. Coverage Type: Unit/boundary validation Status: ✅ Passed Results: 51 passed, 0 failed, 0 skipped. The run includes the current-head direct-manifest-file fail-closed coverage and confirms a directory primary output remains authorized. Evidence: Scenario 3: Focused Hosting output-contract testsObjective: Exercise the stacked output-plan registration and AppHost backchannel behavior used by publish verification. Coverage Type: Unit/integration boundary validation Status: ✅ Passed Results: 36 passed, 0 failed, 0 skipped. Evidence: Scenario 4: Submitted publish-verification E2EObjective: Run the new E2E exactly as submitted after installing the current-head CLI and Hosting packages. Coverage Type: E2E regression validation Status: ❌ Failed The generated AppHost adds a step named Evidence:
Scenario 5: Corrected clean/drift/no-mutation E2EObjective: Isolate the submitted fixture defect and validate the intended user-facing workflow against the unchanged current-head CLI and packages. Coverage Type: Happy path and unhappy path Status: ✅ Passed The temporary fixture correction gave the output-producing step a unique name and wired it into the built-in publish aggregation step: Name = "write-verification-output",
RequiredBySteps = [WellKnownPipelineSteps.Publish],Verified behavior:
Expected Unhappy-Path Outcome: Clear drift diagnostics, exit code 23, and no target mutation. Evidence:
Environment Notes
Summary
Overall Result❌ ISSUES FOUND The publish-verification product behavior is verified at the current PR head, including its fail-closed and no-mutation guarantees. However, the PR's newly added E2E test is broken as submitted and cannot reach RecommendationUpdate the E2E fixture to use a uniquely named output-producing step and set |
Description
Checked-in publish artifacts can drift from their AppHost model when a developer forgets to regenerate them. This adds
aspire publish --verify, which publishes into an isolated staging directory, compares the generated files with the Git-included logical destinations, and exits with an actionable stale/missing/orphaned report without modifying the checked-in output.This PR is intentionally stacked on #18875, which adds the publisher output-path contract and
pipeline-outputs.v1authorization handshake required to relocate primary and named publisher outputs safely.User-facing usage
Command help includes:
Drift is grouped by destination:
Verification fails closed for incompatible Hosting versions or capabilities, unsupported steps, unsafe or overlapping destinations, unavailable Git, nested repositories/submodules, and symbolic-link or junction escapes. Direct legacy manifest-file output is rejected because sibling Dockerfile/Bicep artifacts cannot be completely inventoried; manifest-directory output remains verifiable. Git reconciliation includes tracked files even when newly ignored, untracked non-ignored files, and absent generated candidates that are not ignored. UTF-8 text comparison normalizes staged/logical path forms; binary and non-UTF-8 content remains byte-exact.
Screenshots / Recordings
TODO: Capture the
PublishVerificationTestsLinux E2E recording in CI. Local Docker Desktop was unavailable.Security considerations
Verification guarantees that logical targets are read-only during the operation. It uses a securely created temporary directory, validates all output destinations against the AppHost Git root before authorization, rejects nested repositories and link/reparse-point traversal, invokes Git through argument lists and NUL-delimited input, and redacts likely secrets from the regenerate command. Security review is requested for these path-boundary, cleanup, and non-mutation guarantees.
Validation
Aspire.Cli.Testssuite during development: 4,648 passed, 38 platform-specific skipped.Fixes #18833
Checklist
<remarks />and<code />elements on your triple slash comments?