Skip to content

Commit 323aba9

Browse files
authored
Agents | Add Azure DevOps work item markdown formatting guide & PR feedback prompt (#4253)
1 parent 29a9b2a commit 323aba9

3 files changed

Lines changed: 272 additions & 0 deletions

File tree

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
---
2+
applyTo: "**"
3+
---
4+
# Azure DevOps Work Items: Markdown Description Rules
5+
6+
Use this guide whenever creating or updating Azure DevOps work items that include rich text in `System.Description`.
7+
8+
## Goals
9+
10+
- Ensure descriptions render as Markdown (not HTML/plain text)
11+
- Preserve newline characters and list structure
12+
- Verify work items after every batch update
13+
14+
## Required Behavior
15+
16+
1. Always use `az rest` for description content-type changes.
17+
2. Use `application/json-patch+json` for PATCH requests.
18+
3. Set `multilineFieldsFormat.System.Description` to `markdown`.
19+
4. Preserve exact newlines in the Markdown body.
20+
5. Verify both format and newline integrity after updates.
21+
22+
## Authentication and Resource
23+
24+
Use Azure DevOps resource audience when calling `az rest`:
25+
26+
- Resource: `499b84ac-1321-427f-aa17-267ca6975798`
27+
28+
Example auth check:
29+
30+
```bash
31+
az rest \
32+
--method GET \
33+
--resource 499b84ac-1321-427f-aa17-267ca6975798 \
34+
--url "https://dev.azure.com/<org>/_apis/projects?api-version=7.1-preview.4"
35+
```
36+
37+
Note: API versions can differ by endpoint. The examples below use `7.1-preview.3` for work item PATCH calls, while this auth check uses `7.1-preview.4`.
38+
39+
## Safe Update Pattern (Prevents Type/Value Errors)
40+
41+
Some work items reject a direct type switch unless a valid value is provided. Use this two-step process:
42+
43+
### Step 1: Capture current description
44+
45+
```bash
46+
az boards work-item show --id <id> | jq -j '.fields["System.Description"] // ""' > ./desc-backup.txt
47+
```
48+
49+
> **NOTE**: Writing to a file preserves all characters including trailing newlines.
50+
> Command substitution (`$(...)`) silently strips trailing newlines, which would
51+
> corrupt multi-line Markdown content.
52+
53+
### Step 2: Force markdown type with temporary empty value
54+
55+
```bash
56+
PATCH_STEP1_FILE="${PATCH_STEP1_FILE:-./patch-step1.json}"
57+
58+
jq -n '[
59+
{"op":"replace","path":"/fields/System.Description","value":""},
60+
{"op":"replace","path":"/multilineFieldsFormat/System.Description","value":"markdown"}
61+
]' >"$PATCH_STEP1_FILE"
62+
63+
az rest \
64+
--method PATCH \
65+
--resource 499b84ac-1321-427f-aa17-267ca6975798 \
66+
--url "https://dev.azure.com/<org>/<project>/_apis/wit/workitems/<id>?api-version=7.1-preview.3" \
67+
--headers "Content-Type=application/json-patch+json" \
68+
--body @"$PATCH_STEP1_FILE"
69+
```
70+
71+
### Step 3: Restore exact Markdown text
72+
73+
```bash
74+
PATCH_STEP2_FILE="${PATCH_STEP2_FILE:-./patch-step2.json}"
75+
76+
jq -n --rawfile d ./desc-backup.txt '[
77+
{"op":"replace","path":"/fields/System.Description","value":$d}
78+
]' >"$PATCH_STEP2_FILE"
79+
80+
az rest \
81+
--method PATCH \
82+
--resource 499b84ac-1321-427f-aa17-267ca6975798 \
83+
--url "https://dev.azure.com/<org>/<project>/_apis/wit/workitems/<id>?api-version=7.1-preview.3" \
84+
--headers "Content-Type=application/json-patch+json" \
85+
--body @"$PATCH_STEP2_FILE"
86+
```
87+
88+
## Newline Integrity Checks
89+
90+
After updates, confirm newline characters are still present and structure was not flattened.
91+
92+
### Check format and description sample
93+
94+
```bash
95+
az boards work-item show --id <id> | jq '.multilineFieldsFormat, .fields["System.Description"][0:200]'
96+
```
97+
98+
Expected:
99+
100+
- `multilineFieldsFormat.System.Description == "markdown"`
101+
- Description text contains `\n` where line breaks are expected
102+
103+
### Check line count did not collapse
104+
105+
```bash
106+
az boards work-item show --id <id> \
107+
| jq -r '.fields["System.Description"]' \
108+
| awk 'END { print NR }'
109+
```
110+
111+
If a multi-line description unexpectedly returns `1`, newline content was likely lost.
112+
113+
## Batch Verification Script
114+
115+
Use this after bulk updates:
116+
117+
```bash
118+
python3 - <<'PY'
119+
import json, subprocess
120+
ids = [12345, 12346] # replace with your target IDs
121+
bad = []
122+
for i in ids:
123+
out = subprocess.check_output(["az", "boards", "work-item", "show", "--id", str(i)], text=True)
124+
j = json.loads(out)
125+
fmt = (j.get("multilineFieldsFormat") or {}).get("System.Description")
126+
desc = j.get("fields", {}).get("System.Description") or ""
127+
if fmt != "markdown" or "\n" not in desc:
128+
bad.append((i, fmt, "has_newlines" if "\n" in desc else "missing_newlines"))
129+
print("noncompliant:", len(bad))
130+
for row in bad:
131+
print(row)
132+
PY
133+
```
134+
135+
## Common Failure Modes
136+
137+
- `401` or `TF400813`: wrong token audience or insufficient auth context
138+
- `Content-Type ... not supported`: must use `application/json-patch+json`
139+
- `type changed without a value`: use two-step pattern (empty + markdown type, then restore text)
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
---
2+
name: review-pr-feedback
3+
description: Uses gh CLI to collect unresolved PR review feedback, optionally includes discussion comments, applies fixes, and reports status.
4+
argument-hint: pr=<number-or-url> repo=<owner/repo-optional> includeDiscussionComments=<true|false> authorFilter=<optional regex or csv> testScope=<optional test hint>
5+
tools: ['edit/editFiles', 'edit/createFile', 'read/readFile', 'read/problems', 'search/codebase', 'search/textSearch', 'search/fileSearch', 'execute/runInTerminal', 'execute/getTerminalOutput']
6+
---
7+
You are an expert software maintenance agent focused on resolving pull request feedback quickly, safely, and with clear traceability.
8+
9+
## Context
10+
- Workspace root: ${workspaceFolder}
11+
- Target PR: ${input:pr}
12+
- Optional repository override: ${input:repo}
13+
- Include non-review discussion comments: ${input:includeDiscussionComments}
14+
- Optional author filter: ${input:authorFilter}
15+
- Optional focused testing hint: ${input:testScope}
16+
- Optional selected context: ${selection}
17+
18+
## Skills
19+
#skill:generate-mstest-filter
20+
21+
Use this skill when building a dotnet test filter:
22+
- [generate-mstest-filter](.github/skills/generate-mstest-filter/SKILL.md)
23+
24+
Follow the referenced skill instructions before producing any custom filter.
25+
26+
## Task
27+
1. Validate prerequisites
28+
- Confirm gh CLI is installed and authenticated.
29+
- Resolve repository from ${input:repo}, or infer from git remote.
30+
- Resolve PR number from ${input:pr} (accept number or URL).
31+
- Discover the correct git remote name from the current repository and store it for later commands.
32+
- Use that discovered remote name for push and any other git operations that require a remote; do not assume `origin`.
33+
34+
2. Gather actionable review feedback
35+
- Query PR review threads with gh api GraphQL.
36+
- Keep only unresolved threads where isResolved is false.
37+
- Extract thread id, file path, line/startLine, comment url, author login, and body.
38+
- If ${input:authorFilter} is provided, apply it case-insensitively.
39+
40+
3. Optionally gather non-review discussion comments
41+
- If ${input:includeDiscussionComments} is true, fetch PR issue comments.
42+
- Mark these as Informational because they do not have open/resolved state.
43+
- Apply ${input:authorFilter} if provided.
44+
45+
4. Build an implementation plan
46+
- Group unresolved review feedback by file and risk.
47+
- Determine minimal safe edits needed.
48+
- Identify comments that are non-actionable or ambiguous.
49+
- Ask the user to confirm the plan before proceeding, showing a concise summary of proposed changes and rationale.
50+
51+
5. Implement and verify
52+
- Apply required code or test updates with smallest safe change set.
53+
- Run targeted checks first.
54+
- If ${input:testScope} is provided, generate and use a focused MSTest filter via the skill.
55+
- Collect diagnostics when tests cannot run.
56+
57+
6. Classify each item
58+
- Fixed: change implemented and validated.
59+
- Needs Clarification: ambiguous, conflicting, or insufficiently specified.
60+
- Blocked: external dependency, permission, or missing context.
61+
- Informational: non-review discussion comment captured only.
62+
63+
7. Produce a final report
64+
- Keep review-thread outcomes and discussion outcomes in separate sections.
65+
- Include evidence for each item: file location, change summary, validation result.
66+
- Draft a distinct reply for each comment item that addresses that exact comment's request, context, and outcome.
67+
68+
8. Commit changes
69+
- If any changes were made, create a commit with a clear message referencing the PR and summarizing the resolution.
70+
- Prompt the user to review and confirm the commit message before finalizing.
71+
- When suggesting or performing a push, use the discovered git remote name.
72+
- Prompt the user to push the commit if they have permissions, or provide instructions if they do not.
73+
- Prompt the user to reply to each original PR comment with a comment-specific response and link to the relevant commit or code location, if appropriate.
74+
- Prompt the user to mark review threads as resolved in GitHub if they have permissions, or provide instructions if they do not.
75+
76+
## Output Format
77+
1. PR Scope
78+
- Repo
79+
- PR number
80+
- Unresolved review threads found
81+
- Discussion comments found (if enabled)
82+
83+
2. Unresolved Review Feedback (Actionable)
84+
- Item: <comment url>
85+
- Location: <file>:<line>
86+
- Author: <login>
87+
- Request summary: <concise>
88+
- Action taken: <change or rationale>
89+
- Status: Fixed | Needs Clarification | Blocked
90+
- Evidence: <tests/diagnostics>
91+
- Suggested reply: <specific response for this exact comment>
92+
93+
3. Discussion Comments (Informational, optional)
94+
- Item: <comment url>
95+
- Author: <login>
96+
- Summary: <concise>
97+
- Notes: <if converted to actionable task, explain>
98+
- Suggested reply: <specific response for this exact comment>
99+
100+
4. Validation
101+
- Commands run
102+
- Filters used
103+
- Pass/fail summary
104+
- Remaining warnings/errors
105+
106+
5. Final Summary
107+
- Files changed
108+
- Number fixed
109+
- Number needing clarification
110+
- Number blocked
111+
- Number informational
112+
- Recommended next step
113+
114+
## Rules
115+
- Do not invent comments; only act on data fetched from gh.
116+
- Review-thread resolution tracking is authoritative for unresolved state.
117+
- Keep behavior-compatible edits unless feedback explicitly requires change.
118+
- If no unresolved review threads exist, report that explicitly.
119+
- If auth or permission fails, report exact failure and minimum required user action.
120+
- Do not use `set -e` in bash commands or scripts.
121+
- After each terminal step, verify the bash session is still alive; if it died, report it immediately, start a new session, and continue from the last confirmed checkpoint.
122+
- Use the discovered git remote name consistently anywhere a remote is required.
123+
- Do not post generic batch replies; each reply must be tailored to the specific comment content and its exact resolution status.

AGENTS.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ This document provides guidance for AI coding agents working with the Microsoft.
55
## Quick Start
66

77
### Essential Context Files
8+
89
Before making changes, agents should be aware of:
910

1011
| File | Purpose |
@@ -15,6 +16,7 @@ Before making changes, agents should be aware of:
1516
| [.github/copilot-instructions.md](.github/copilot-instructions.md) | Copilot-specific instructions |
1617

1718
### Detailed Technical Instructions
19+
1820
The `.github/instructions/` directory contains comprehensive guides:
1921

2022
| Guide | Coverage |
@@ -29,6 +31,7 @@ The `.github/instructions/` directory contains comprehensive guides:
2931
| [features.instructions.md](.github/instructions/features.instructions.md) | Feature reference, keywords |
3032
| [documentation.instructions.md](.github/instructions/documentation.instructions.md) | Documentation and samples |
3133
| [external-resources.instructions.md](.github/instructions/external-resources.instructions.md) | Docs links, version matrix, external references |
34+
| [ado-work-items-markdown.instructions.md](.github/instructions/ado-work-items-markdown.instructions.md) | Ensure Azure DevOps work item descriptions are Markdown and preserve newlines |
3235

3336
## Workflow Prompts
3437

@@ -77,6 +80,7 @@ Do **not** create branches directly under `main`, `dev/`, or any other top-level
7780
## Common Tasks
7881

7982
### Bug Fix Workflow
83+
8084
1. Understand the issue from the bug report
8185
2. Locate relevant code in `src/Microsoft.Data.SqlClient/src/` (do NOT modify legacy `netcore/src/` or `netfx/src/`)
8286
3. Check `.github/instructions/features.instructions.md` for existing AppContext switches (including failover compatibility switches) before introducing behavior changes
@@ -86,6 +90,7 @@ Do **not** create branches directly under `main`, `dev/`, or any other top-level
8690
7. Update documentation if behavior changes
8791

8892
### Feature Implementation
93+
8994
1. Review the feature specification
9095
2. Plan the implementation (see `implement-feature` prompt)
9196
3. Update reference assemblies if adding public APIs
@@ -94,20 +99,23 @@ Do **not** create branches directly under `main`, `dev/`, or any other top-level
9499
6. Do not edit `CHANGELOG.md` directly; instead, add a suggested release-note entry (per `.github/copilot-instructions.md`) in the PR description or via the release-notes workflow/prompt.
95100

96101
### Adding Connection String Keywords
102+
97103
1. Add to `SqlConnectionStringBuilder`
98104
2. Update connection string parser
99105
3. Default to backward-compatible value
100106
4. Add tests for new keyword
101107
5. Document in feature reference
102108

103109
### Protocol Changes
110+
104111
1. Reference MS-TDS specification
105112
2. Update `TdsEnums.cs` for new constants
106113
3. Implement in `TdsParser.cs` and related files
107114
4. Test against multiple SQL Server versions
108115
5. Consider backward compatibility
109116

110117
### Performance Optimization
118+
111119
1. Profile the issue using benchmarks or traces
112120
2. Identify allocation hotspots (see `perf-optimization` prompt)
113121
3. Apply patterns: `ArrayPool<T>`, `Span<T>`, static/cached instances, source generation
@@ -117,13 +125,15 @@ Do **not** create branches directly under `main`, `dev/`, or any other top-level
117125

118126

119127
### Key Documentation Links
128+
120129
- [Microsoft.Data.SqlClient on Microsoft Learn](https://learn.microsoft.com/sql/connect/ado-net/introduction-microsoft-data-sqlclient-namespace)
121130
- [MS-TDS Protocol Specification](https://learn.microsoft.com/openspecs/windows_protocols/ms-tds)
122131
- [SQL Server Documentation](https://learn.microsoft.com/sql/sql-server/)
123132

124133
## Repository Policies
125134

126135
See the `policy/` directory for:
136+
127137
- [coding-best-practices.md](policy/coding-best-practices.md) - Programming standards
128138
- [coding-style.md](policy/coding-style.md) - Code formatting guidelines
129139
- [review-process.md](policy/review-process.md) - PR review requirements

0 commit comments

Comments
 (0)