Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates the CustomizedCodeUpdateTool workflow to correctly report failed operations via the standard CommandResponse status/error fields, improving downstream consumers’ ability to detect failure conditions.
Changes:
- Populate
ResponseErrorforCustomizedCodeUpdateResponsefailure cases soOperationStatus/ExitCodereflect failures correctly. - Adjust build execution within the retry loop to avoid unnecessary builds in some iterations.
- Update response formatting/documentation around
BuildResult(including printing build output in formatted output when present).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| tools/azsdk-cli/Azure.Sdk.Tools.Cli/Tools/TypeSpec/CustomizedCodeUpdateTool.cs | Sets ResponseError on failure responses and tweaks build/regen flow in the retry loop and patch validation paths. |
| tools/azsdk-cli/Azure.Sdk.Tools.Cli/Models/Responses/Package/CustomizedCodeUpdateResponse.cs | Updates BuildResult docstring and includes BuildResult in formatted output. |
Comments suppressed due to low confidence (2)
tools/azsdk-cli/Azure.Sdk.Tools.Cli/Tools/TypeSpec/CustomizedCodeUpdateTool.cs:155
- The PR’s main behavior change is setting
ResponseErrorwhenSuccess = falsesoOperationStatusis reported correctly. The existing unit tests for failure cases assertSuccess/ErrorCode/BuildResult, but none assert thatResponseErroris set (and therefore thatOperationStatus/ExitCodeflips to failed). Adding assertions forResponseErrorin a couple representative failure tests would prevent regressions in the status-reporting behavior this PR is fixing.
return new CustomizedCodeUpdateResponse
{
Success = false,
ResponseError = $"Package path does not exist: {packagePath}",
Message = $"Package path does not exist: {packagePath}",
ErrorCode = CustomizedCodeUpdateResponse.KnownErrorCodes.InvalidInput,
BuildResult = $"Package path does not exist: {packagePath}"
};
tools/azsdk-cli/Azure.Sdk.Tools.Cli/Models/Responses/Package/CustomizedCodeUpdateResponse.cs:36
- The updated
BuildResultXML comment says it’s “Raw build output” and is set on both success and failure, but the tool is populating it withLanguageService.BuildAsync’sErrorMessage, which is explicitlynullon success. Either update the documentation to reflect that this is build failure output/error context, or change the implementation to actually capture and populate successful build output.
/// <summary>
/// Raw build output. Set on both success and failure to provide context in MCP responses.
/// </summary>
[JsonPropertyName("buildResult")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? BuildResult { get; set; }
You can also share your feedback on Copilot code review. Take the survey.
tools/azsdk-cli/Azure.Sdk.Tools.Cli/Tools/TypeSpec/CustomizedCodeUpdateTool.cs
Outdated
Show resolved
Hide resolved
tools/azsdk-cli/Azure.Sdk.Tools.Cli/Tools/TypeSpec/CustomizedCodeUpdateTool.cs
Outdated
Show resolved
Hide resolved
tools/azsdk-cli/Azure.Sdk.Tools.Cli/Models/Responses/Package/CustomizedCodeUpdateResponse.cs
Show resolved
Hide resolved
m-redding
reviewed
Mar 12, 2026
tools/azsdk-cli/Azure.Sdk.Tools.Cli/Tools/TypeSpec/CustomizedCodeUpdateTool.cs
Outdated
Show resolved
Hide resolved
m-redding
approved these changes
Mar 13, 2026
tools/azsdk-cli/Azure.Sdk.Tools.Cli/Tools/TypeSpec/CustomizedCodeUpdateTool.cs
Show resolved
Hide resolved
tools/azsdk-cli/Azure.Sdk.Tools.Cli/Tools/TypeSpec/CustomizedCodeUpdateTool.cs
Outdated
Show resolved
Hide resolved
tools/azsdk-cli/Azure.Sdk.Tools.Cli/Tools/TypeSpec/CustomizedCodeUpdateTool.cs
Outdated
Show resolved
Hide resolved
…fixes and builds, pass 2 re-evaluates with error context
m-redding
approved these changes
Mar 18, 2026
Member
m-redding
left a comment
There was a problem hiding this comment.
Looks good! I think the new flow makes so much more sense!! Just had a few optional nits
tools/azsdk-cli/Azure.Sdk.Tools.Cli.Tests/Tools/TypeSpec/CustomizedCodeUpdateToolTests.cs
Outdated
Show resolved
Hide resolved
tools/azsdk-cli/Azure.Sdk.Tools.Cli/Tools/TypeSpec/CustomizedCodeUpdateTool.cs
Outdated
Show resolved
Hide resolved
tools/azsdk-cli/Azure.Sdk.Tools.Cli/Tools/TypeSpec/CustomizedCodeUpdateTool.cs
Outdated
Show resolved
Hide resolved
tools/azsdk-cli/Azure.Sdk.Tools.Cli/Tools/TypeSpec/CustomizedCodeUpdateTool.cs
Outdated
Show resolved
Hide resolved
tools/azsdk-cli/Azure.Sdk.Tools.Cli/Tools/TypeSpec/CustomizedCodeUpdateTool.cs
Show resolved
Hide resolved
tools/azsdk-cli/Azure.Sdk.Tools.Cli/Tools/TypeSpec/CustomizedCodeUpdateTool.cs
Show resolved
Hide resolved
…cleanup # Conflicts: # tools/azsdk-cli/Azure.Sdk.Tools.Cli/Tools/TypeSpec/CustomizedCodeUpdateTool.cs
m-redding
approved these changes
Mar 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
flowchart TD Start([HandleCommand / UpdateAsync]) --> Validate{Validate Inputs} Validate -->|Invalid| ErrInput[Return InvalidInput Error] Validate -->|Valid| GetLang[Get LanguageService] GetLang --> GetFeedback[GetFeedbackItems] GetFeedback -->|No items| ErrNoFeedback[Return InvalidInput Error] GetFeedback -->|Has items| Pass1["Pass 1: ClassifyItemsAsync"] Pass1 -->|No classifications| ErrClassify[Return Classification Error] Pass1 -->|Has classifications| Loop1["Loop: Process Each Classification"] subgraph ClassifyFeedback["Pass 1: Classify Feedbacks"] direction TB Pass1 ErrClassify Loop1 Loop1 -->|TSP_APPLICABLE| ApplyTSP["ApplyCustomizationAsync\n(TypeSpec changes)"] Loop1 -->|CODE_CUSTOMIZATION| TrackCode[Mark for code patching] Loop1 -->|REQUIRES_MANUAL| TrackManual[Add to manualInterventions] Loop1 -->|SUCCESS| TrackNoChange["Remove – no change\nneeded"] ApplyTSP -->|Success| TrackTSPOk[Track changesMade] ApplyTSP -->|Failure| TrackTSPFail[Track failure reason] end TrackTSPOk --> EarlyExit TrackTSPFail --> EarlyExit TrackCode --> EarlyExit TrackManual --> EarlyExit TrackNoChange --> EarlyExit EarlyExit{Early exit checks} EarlyExit -->|"All manual..."| RetManual[Return:\nManualInterventionRequired] EarlyExit -->|"All success"| RetNoChange[Return: No changes needed] EarlyExit -->|"TSP fixes applied"| RegenGate{tspFixSucceeded > 0?} subgraph RegenBuild["Regen + Build after TSP"] direction TB RegenGate RegenGate -->|Yes| Regen["UpdateGenerationAsync"] Regen -->|Success| Build1["BuildAsync"] Regen -->|Failed| EnrichRegen[Enrich items with regen error] Build1 -->|"Pass & no code\ncustomizations"| RetBuildOk1["Return: Success – TSP only"] Build1 -->|Fail| EnrichBuild[Enrich items with build error] end RegenGate -->|No| Pass2Gate EnrichRegen --> Pass2Gate EnrichBuild --> Pass2Gate subgraph Pass2["Pass 2: Re-classify"] direction TB Pass2Gate{Remaining items?} Pass2Gate -->|Yes| Reclass["ClassifyItemsAsync – 2nd\npass"] Reclass -->|CODE_CUSTOMIZATION| MoreCode[codeCustomizations++] Reclass -->|REQUIRES_MANUAL| MoreManual[manualInterventions++] Reclass -->|SUCCESS| MoreSuccess[Remove item] end Pass2Gate -->|No| NeedBuild MoreCode --> NeedBuild MoreManual --> NeedBuild MoreSuccess --> NeedBuild NeedBuild{"Build not yet run\nor failed?"} NeedBuild -->|"No build yet"| Build2["BuildAsync\n(for error context)"] Build2 --> CheckBuild2 NeedBuild -->|"Already built"| CheckBuild2 CheckBuild2{"Build passed &\nno code customizations?"} CheckBuild2 -->|Yes| RetBuildOk2[Return Success +\nTypeSpec changes] CheckBuild2 -->|No| SupportCheck{IsCustomizedCodeUpdate\nSupported?} SupportCheck -->|No| RetNoLang[Return NoLanguageService Error] SupportCheck -->|Yes| HasCustom{HasCustomizations?} HasCustom -->|No files| RetNoCust[Return BuildNoCustomizationsFailed] HasCustom -->|Has files| Patch["ApplyPatchesAsync\n(code customization patches)"] Patch -->|No patches| RetNoPatch[Return PatchesFailed Error] Patch -->|Has patches| JavaCheck{Language == Java?} JavaCheck -->|Yes| RegenJava["UpdateGenerationAsync\n(Java post-patch regen)"] RegenJava -->|Failed| RetRegenFail[Return RegenerateAfterPatchesFailed] RegenJava -->|Success| FinalBuild JavaCheck -->|No| FinalBuild["Final BuildAsync"] FinalBuild -->|Pass| RetFinalOk[Return Success +\npatches + changes] FinalBuild -->|Fail| RetFinalFail[Return BuildAfterPatchesFailed] style Start fill:#4a90d9,color:#fff style RetBuildOk1 fill:#27ae60,color:#fff style RetBuildOk2 fill:#27ae60,color:#fff style RetFinalOk fill:#27ae60,color:#fff style RetNoChange fill:#27ae60,color:#fff style RetManual fill:#f39c12,color:#fff style ErrInput fill:#e74c3c,color:#fff style ErrNoFeedback fill:#e74c3c,color:#fff style ErrClassify fill:#e74c3c,color:#fff style RetNoLang fill:#e74c3c,color:#fff style RetNoCust fill:#e74c3c,color:#fff style RetNoPatch fill:#e74c3c,color:#fff style RetRegenFail fill:#e74c3c,color:#fff style RetFinalFail fill:#e74c3c,color:#fff style ClassifyFeedback fill:#fef9e7,stroke:#f0e68c style RegenBuild fill:#fef9e7,stroke:#f0e68c style Pass2 fill:#fef9e7,stroke:#f0e68c