diff --git a/.github/instructions/ado-work-items-markdown.instructions.md b/.github/instructions/ado-work-items-markdown.instructions.md new file mode 100644 index 0000000000..419faeff0b --- /dev/null +++ b/.github/instructions/ado-work-items-markdown.instructions.md @@ -0,0 +1,129 @@ +--- +applyTo: "**" +--- +# Azure DevOps Work Items: Markdown Description Rules + +Use this guide whenever creating or updating Azure DevOps work items that include rich text in `System.Description`. + +## Goals + +- Ensure descriptions render as Markdown (not HTML/plain text) +- Preserve newline characters and list structure +- Verify work items after every batch update + +## Required Behavior + +1. Always use `az rest` for description content-type changes. +2. Use `application/json-patch+json` for PATCH requests. +3. Set `multilineFieldsFormat.System.Description` to `markdown`. +4. Preserve exact newlines in the Markdown body. +5. Verify both format and newline integrity after updates. + +## Authentication and Resource + +Use Azure DevOps resource audience when calling `az rest`: + +- Resource: `499b84ac-1321-427f-aa17-267ca6975798` + +Example auth check: + +```bash +az rest \ + --method GET \ + --resource 499b84ac-1321-427f-aa17-267ca6975798 \ + --url "https://dev.azure.com//_apis/projects?api-version=7.1-preview.4" +``` + +## Safe Update Pattern (Prevents Type/Value Errors) + +Some work items reject a direct type switch unless a valid value is provided. Use this two-step process: + +### Step 1: Capture current description + +```bash +desc=$(az boards work-item show --id | jq -r '.fields["System.Description"] // ""') +``` + +### Step 2: Force markdown type with temporary empty value + +```bash +jq -n '[ + {"op":"replace","path":"/fields/System.Description","value":""}, + {"op":"replace","path":"/multilineFieldsFormat/System.Description","value":"markdown"} +]' >/tmp/patch-step1.json + +az rest \ + --method PATCH \ + --resource 499b84ac-1321-427f-aa17-267ca6975798 \ + --url "https://dev.azure.com///_apis/wit/workitems/?api-version=7.1-preview.3" \ + --headers "Content-Type=application/json-patch+json" \ + --body @/tmp/patch-step1.json +``` + +### Step 3: Restore exact Markdown text + +```bash +jq -n --arg d "$desc" '[ + {"op":"replace","path":"/fields/System.Description","value":$d} +]' >/tmp/patch-step2.json + +az rest \ + --method PATCH \ + --resource 499b84ac-1321-427f-aa17-267ca6975798 \ + --url "https://dev.azure.com///_apis/wit/workitems/?api-version=7.1-preview.3" \ + --headers "Content-Type=application/json-patch+json" \ + --body @/tmp/patch-step2.json +``` + +## Newline Integrity Checks + +After updates, confirm newline characters are still present and structure was not flattened. + +### Check format and description sample + +```bash +az boards work-item show --id | jq '.multilineFieldsFormat, .fields["System.Description"][0:200]' +``` + +Expected: + +- `multilineFieldsFormat.System.Description == "markdown"` +- Description text contains `\n` where line breaks are expected + +### Check line count did not collapse + +```bash +az boards work-item show --id \ +| jq -r '.fields["System.Description"]' \ +| awk 'END { print NR }' +``` + +If a multi-line description unexpectedly returns `1`, newline content was likely lost. + +## Batch Verification Script + +Use this after bulk updates: + +```bash +python3 - <<'PY' +import json, subprocess +ids = [44787, 44794] # replace with your target IDs +bad = [] +for i in ids: + out = subprocess.check_output(["az", "boards", "work-item", "show", "--id", str(i)], text=True) + j = json.loads(out) + fmt = (j.get("multilineFieldsFormat") or {}).get("System.Description") + desc = j.get("fields", {}).get("System.Description") or "" + if fmt != "markdown" or "\n" not in desc: + bad.append((i, fmt, "has_newlines" if "\n" in desc else "missing_newlines")) +print("noncompliant:", len(bad)) +for row in bad: + print(row) +PY +``` + +## Common Failure Modes + +- `401` or `TF400813`: wrong token audience or insufficient auth context +- `Content-Type ... not supported`: must use `application/json-patch+json` +- `type changed without a value`: use two-step pattern (empty + markdown type, then restore text) diff --git a/AGENTS.md b/AGENTS.md index 690e9c9c8d..409523b444 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -5,6 +5,7 @@ This document provides guidance for AI coding agents working with the Microsoft. ## Quick Start ### Essential Context Files + Before making changes, agents should be aware of: | File | Purpose | @@ -15,6 +16,7 @@ Before making changes, agents should be aware of: | [.github/copilot-instructions.md](.github/copilot-instructions.md) | Copilot-specific instructions | ### Detailed Technical Instructions + The `.github/instructions/` directory contains comprehensive guides: | Guide | Coverage | @@ -29,6 +31,7 @@ The `.github/instructions/` directory contains comprehensive guides: | [features.instructions.md](.github/instructions/features.instructions.md) | Feature reference, keywords | | [documentation.instructions.md](.github/instructions/documentation.instructions.md) | Documentation and samples | | [external-resources.instructions.md](.github/instructions/external-resources.instructions.md) | Docs links, version matrix, external references | +| [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 | ## Workflow Prompts @@ -66,6 +69,7 @@ Do **not** create branches directly under `main`, `dev/`, or any other top-level ## Common Tasks ### Bug Fix Workflow + 1. Understand the issue from the bug report 2. Locate relevant code in `src/Microsoft.Data.SqlClient/src/` (do NOT modify legacy `netcore/src/` or `netfx/src/`) 3. Write a failing test that reproduces the issue @@ -74,6 +78,7 @@ Do **not** create branches directly under `main`, `dev/`, or any other top-level 6. Update documentation if behavior changes ### Feature Implementation + 1. Review the feature specification 2. Plan the implementation (see `implement-feature` prompt) 3. Update reference assemblies if adding public APIs @@ -82,6 +87,7 @@ Do **not** create branches directly under `main`, `dev/`, or any other top-level 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. ### Adding Connection String Keywords + 1. Add to `SqlConnectionStringBuilder` 2. Update connection string parser 3. Default to backward-compatible value @@ -89,6 +95,7 @@ Do **not** create branches directly under `main`, `dev/`, or any other top-level 5. Document in feature reference ### Protocol Changes + 1. Reference MS-TDS specification 2. Update `TdsEnums.cs` for new constants 3. Implement in `TdsParser.cs` and related files @@ -96,6 +103,7 @@ Do **not** create branches directly under `main`, `dev/`, or any other top-level 5. Consider backward compatibility ### Performance Optimization + 1. Profile the issue using benchmarks or traces 2. Identify allocation hotspots (see `perf-optimization` prompt) 3. Apply patterns: `ArrayPool`, `Span`, static/cached instances, source generation @@ -105,6 +113,7 @@ Do **not** create branches directly under `main`, `dev/`, or any other top-level ### Key Documentation Links + - [Microsoft.Data.SqlClient on Microsoft Learn](https://learn.microsoft.com/sql/connect/ado-net/introduction-microsoft-data-sqlclient-namespace) - [MS-TDS Protocol Specification](https://learn.microsoft.com/openspecs/windows_protocols/ms-tds) - [SQL Server Documentation](https://learn.microsoft.com/sql/sql-server/) @@ -112,6 +121,7 @@ Do **not** create branches directly under `main`, `dev/`, or any other top-level ## Repository Policies See the `policy/` directory for: + - [coding-best-practices.md](policy/coding-best-practices.md) - Programming standards - [coding-style.md](policy/coding-style.md) - Code formatting guidelines - [review-process.md](policy/review-process.md) - PR review requirements