Skip to main content

binlog-failure-analysis

Analyze a failed Azure DevOps PR build by reusing the binlog that build already produced — instead of rebuilding locally. Use when an `azure-pipelines` check on a GitHub PR transitions to `failure` and you need a structured root-cause analysis posted back as a PR review. Downloads `PostBuildLogs_*` / `Logs_Build_*` from the AzDO build artifacts, invokes the `binlog` MCP server (Microsoft.AITools.BinlogMcp) for build overview / errors / warnings (with deeper diagnostic capabilities — root-cause reports, property-value tracing — when the basics aren't enough), groups symptoms by root cause, and emits a single summary comment. Optionally attaches inline `suggestion` blocks when an error maps to a one-line fix on a diffed line. Cuts per-PR analysis cost from ~5–8 min (rebuild + analyze) to ~2–3 min (download + analyze). DO NOT USE FOR: pipelines that don't publish a binlog artifact, GitHub-Actions-only repos (no AzDO build to reuse), or general CI health dashboards (use `ci-analysis`).

معلومات المصدر

المستودع
dotnet/arcade-skills
آخر نشاط في المصدر
١٠ سبتمبر ٢٠٢٦ في ٢١:٤٥
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
١٤
التفرعات
٢١

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

مستكشف الملفات
2 ملفات

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
binlog-failure-analysis
description
Analyze a failed Azure DevOps PR build by reusing the binlog that build already produced — instead of rebuilding locally. Use when an `azure-pipelines` check on a GitHub PR transitions to `failure` and you need a structured root-cause analysis posted back as a PR review. Downloads `PostBuildLogs_*` / `Logs_Build_*` from the AzDO build artifacts, invokes the `binlog` MCP server (Microsoft.AITools.BinlogMcp) for build overview / errors / warnings (with deeper diagnostic capabilities — root-cause reports, property-value tracing — when the basics aren't enough), groups symptoms by root cause, and emits a single summary comment. Optionally attaches inline `suggestion` blocks when an error maps to a one-line fix on a diffed line. Cuts per-PR analysis cost from ~5–8 min (rebuild + analyze) to ~2–3 min (download + analyze). DO NOT USE FOR: pipelines that don't publish a binlog artifact, GitHub-Actions-only repos (no AzDO build to reuse), or general CI health dashboards (use `ci-analysis`).
# Binlog Failure Analysis (reuse AzDO binlog, don't rebuild) Analyze a failed AzDO PR build by reading the **binlog that build already produced**, not by re-running the local build (`./build.sh -bl` or equivalent) on a GitHub Actions runner. This is the AI-build-failure-analyst pattern: it makes the analyst run cheap enough to be turned on for every failing PR sync. > 🛑 **NEVER** use `gh pr review --approve` or `--request-changes`. Only `--comment` is allowed. Approval and blocking are human-only actions. **Workflow**: gate on `check_run: completed` → resolve PR + build id → download AzDO artifact → ask the `binlog` MCP server for the build overview, errors, and warnings (drilling into root-cause diagnostics or property-value tracing when the basics aren't enough) → group symptoms by root cause → post a single summary comment → optionally attach ≤10 inline `suggestion` blocks. The agent drives the analysis; tools provide the data. ## When to use - A GitHub PR check from app slug `azure-pipelines` (or the repo's AzDO check slug) transitions to `failure`. - The pipeline publishes a binlog artifact (arcade-onboarded repos do this via `eng/common/core-templates/steps/publish-logs.yml`; arbitrary AzDO pipelines may not). - You want a structured per-PR comment with grouped root causes and concrete `suggestion` blocks — not just a link to the raw log. ## When NOT to use - The PR has no AzDO check (GH-Actions-only repos) — use a rebuild-based skill instead, or wait for an AzDO migration. - The pipeline doesn't publish a binlog artifact — there's nothing to reuse. - You want pipeline-wide health analysis across many builds — use `ci-analysis` or `pipeline-investigation`. - You want to investigate a non-build leg failure (test failures, Helix work item failures) — see `helix-investigation`. ## Prerequisites - **`binlog` MCP server** — `Microsoft.AITools.BinlogMcp` is wired in `plugins/dotnet-binlog/plugin.json` under the namespace `binlog`. The same server is also published by `dotnet/skills/dotnet-msbuild` under the same `binlog` name, so installing both plugins resolves to a single MCP instance. This skill invokes the server's capabilities semantically (build overview, error list, warning list, root-cause diagnose, property-value trace, structured search, task details, tasks-in-target) — discover the exact tool names for your server version via `tools/list`. With `Microsoft.AITools.BinlogMcp`, typical names start with `binlog_` (e.g., `binlog_overview`, `binlog_errors`); the server exposes ~29 tools total. - **`curl`** for the AzDO REST artifact download. - **`jq`** for parsing the AzDO artifacts JSON and the GitHub check-runs payload (Step 2 + `references/azdo-artifact-fetch.md`). - **`unzip`** for extracting the artifact. - **Azure DevOps access:** - Anonymous read for `dev.azure.com/dnceng-public/public` — no token needed. - For `devdiv/DevDiv` or `dnceng/internal`: a federated identity (`azure/login@v2`) or `azureauth ado token`. See `references/azdo-artifact-fetch.md`. - **`gh` CLI** for posting the summary comment + inline review comments. ## Inputs The caller must provide these as environment variables (or equivalent): | Variable | Meaning | | ----------------------- | ------- | | `AZDO_ORG` | AzDO organisation (e.g., `dnceng-public`, `devdiv`). | | `AZDO_PROJECT` | AzDO project (e.g., `public`, `DevDiv`). | | `AZDO_BUILD_ID` | Numeric build ID to fetch the binlog from. | | `PR_NUMBER` | GitHub PR number where the analysis comment will be posted. | | `PR_HEAD_SHA` | Head SHA of the PR (used for permalinks in the comment). | | `GITHUB_WORKSPACE` | Repo checkout root; used to convert absolute paths in the binlog to repo-relative paths. | If only a PR number is known, see `references/azdo-artifact-fetch.md` for finding the build ID via the GitHub check-runs API. ## Workflow The skill executes seven sequential steps. Each step gates the next — stop early if a step's preconditions aren't met. 1. **Sanity check** — verify the trigger is a real failure with a known build id. 2. **Download the binlog** from AzDO build artifacts. 3. **Dump the binlog as JSON** via the `binlog` MCP server (build overview, errors, warnings; drill-down capabilities on demand). 4. **Group errors by root cause** using common .NET / MSBuild failure patterns. 5. **Post the summary comment** on the PR with grouped clusters and proposed fixes. 6. **Post inline `suggestion` review comments** (≤10, **optional / best-effort**) only when an error has a clear one-line fix on a line touched by the PR diff. Skip if no error fits cleanly. 7. **Stop** — never approve or request changes; this skill is comment-only. ### Step 1 — Sanity check If `AZDO_BUILD_ID` is empty or the check-run that triggered this skill has `conclusion != 'failure'`, stop. There's nothing to analyse. ### Step 2 — Download the binlog from AzDO ```bash # 1. List artifacts on the build, find the binlog artifact. ARTIFACTS=$(curl -fsSL \ ${AZDO_TOKEN:+ -H "Authorization: Bearer $AZDO_TOKEN"} \ "https://dev.azure.com/$AZDO_ORG/$AZDO_PROJECT/_apis/build/builds/$AZDO_BUILD_ID/artifacts?api-version=7.1") # Arcade-onboarded repos publish binlogs under artifact name # `PostBuildLogs_<StageLabel>_<JobLabel>_Attempt<N>`. dnceng-public legs # typically use `Logs_Build_Attempt<N>_<leg>`. Prefer PostBuildLogs* first. ARTIFACT_NAME=$(echo "$ARTIFACTS" | jq -r '.value[] | select(.name | test("^PostBuildLogs_|^Logs_Build_")) | .name' | head -1) if [ -z "$ARTIFACT_NAME" ]; then echo "No PostBuildLogs_* or Logs_Build_* artifact on build $AZDO_BUILD_ID — pipeline likely doesn't publish a binlog. Post a one-line PR comment noting this and stop." exit 0 fi DOWNLOAD_URL=$(echo "$ARTIFACTS" | jq -r --arg n "$ARTIFACT_NAME" '.value[] | select(.name == $n) | .resource.downloadUrl') if [ -z "$DOWNLOAD_URL" ] || [ "$DOWNLOAD_URL" = "null" ]; then echo "Artifact '$ARTIFACT_NAME' has no downloadUrl — unexpected AzDO response shape. Stop." exit 0 fi # 2. Download and unzip. mkdir -p /tmp/azdo-binlog curl -fsSL ${AZDO_TOKEN:+ -H "Authorization: Bearer $AZDO_TOKEN"} -o /tmp/azdo-artifact.zip "$DOWNLOAD_URL" unzip -q -o /tmp/azdo-artifact.zip -d /tmp/azdo-binlog # 3. Pick the most-recently-modified *.binlog (the failing leg's binlog # is typically the newest in the artifact). BINLOG=$(find /tmp/azdo-binlog -name '*.binlog' -type f -printf '%T@ %p\n' \ | sort -nr | head -1 | cut -d' ' -f2-) if [ -z "$BINLOG" ]; then echo "Artifact '$ARTIFACT_NAME' extracted but contains no *.binlog — pipeline isn't binlog-producing. Post a one-line PR comment noting this and stop." exit 0 fi ``` Full REST recipe (incl. dnceng/internal auth, fallback when no `PostBuildLogs_*` artifact exists): see `references/azdo-artifact-fetch.md`. ### Step 3 — Dump the binlog as JSON Use the `binlog` MCP server (`Microsoft.AITools.BinlogMcp`). Every tool takes a `binlog_file` argument (no separate load step needed). > **Discover the tool surface first.** Tool names below are the typical ones exposed by `Microsoft.AITools.BinlogMcp` and are listed as hints — if names differ on your server version, call `tools/list` on the `binlog` MCP namespace and use the equivalent capability. The capability you need is what matters; the exact name is incidental. **Always gather the basics first** — they're cheap and feed Step 4's clustering: | Information you need | Typical tool | Output file | | -------------------- | ------------ | ----------- | | Build status + project totals + which target failed | `binlog_overview` | `/tmp/binlog-data/binlog-overview.json` | | Per-error structured rows | `binlog_errors` | `/tmp/binlog-data/binlog-errors.json` | | Top-N warnings (pass `top: 10`) | `binlog_warnings` | `/tmp/binlog-data/binlog-warnings.json` | Each error row contains: `severity`, `code`, `message`, `file`, `line`, `column`, `projectFile`, `targetName`, `taskName`. **Drill down on-demand when the basics aren't enough** — e.g., overview says FAILED but the errors list is empty, or two clusters look like they share a hidden cause: | Information you need | When to gather it | Typical tool | Output file | | -------------------- | ----------------- | ------------ | ----------- | | Automated root-cause report (task failures, OnError targets, process exits) | Overview says FAILED but the errors list is empty or uninformative | `binlog_diagnose` | `/tmp/binlog-data/binlog-diagnose.json` | | Where a property value came from (which import/file set `$(TargetFramework)`, `$(OutputPath)`, etc.) | An error blames a property value | `binlog_explain_property` | `/tmp/binlog-data/binlog-explain-<name>.json` | | Every occurrence of a string/path/regex across the build (StructuredLog-Viewer query syntax) | You need to locate every mention of a token | `binlog_search` | `/tmp/binlog-data/binlog-search-<slug>.json` | | One task's inputs, outputs, and timing | A specific task is responsible for the failure | `binlog_task_details` | `/tmp/binlog-data/binlog-task-<name>.json` | | Which task inside a target actually failed | A failing target has many tasks; you need to find the culprit | `binlog_tasks_in_target` | `/tmp/binlog-data/binlog-tasks-in-<target>.json` | If the overview says the build FAILED but every error/diagnose tool returns empty, the failure was non-MSBuild (process crash, signing, network). Fall back to grepping the raw artifact for `error` / `failed` lines. ### Step 4 — Group errors by root cause Common .NET / MSBuild root-cause patterns: | Pattern | Telltale codes | Typical root cause | |-------------------------------|-----------------------------|--------------------| | Missing API / using directive | `CS0103`, `CS0246`, `CS0234`| Removed namespace, missing project reference, missing TFM-conditional code. | | Nullable / type mismatch | `CS8600`–`CS8618`, `CS0029` | Recent nullability change cascading across call sites. | | Public API mismatch | `RS0016`, `RS0017`, `RS0026`| Public API not declared in `PublicAPI.Unshipped.txt`. | | StyleCop violation | `SA####` | Trailing whitespace, missing newline, tuple casing. | | Analyzer rule violation | `CA####` | Code-quality rule promoted via `WarnAsError`. | | MSBuild task / target failure | `MSB####` | Missing file, malformed XML, broken import. | | NuGet resolution failure | `NU####`, `NETSDK####` | Version conflict, banned dependency, missing TFM. | | Localization regression | `xlf` parsing error | `.resx` modified without `dotnet msbuild /t:UpdateXlf`. | | TFM-specific failure | error only fires for one TFM| Missing `#if NET` guard or conditional reference. | Group every error in the binlog under exactly one root-cause cluster. If two clusters share a probable common cause, merge them. ### Step 5 — Post the summary comment Post exactly one comment via `gh pr comment` (or the safe-output equivalent in the calling workflow). Mark it with `<!-- binlog-failure-analysis -->` so later runs can supersede the previous one. Template (keep under 400 lines total): ```markdown <!-- binlog-failure-analysis --> ## 🔍 Build Failure Analysis **Summary** — <one sentence stating what failed, with a link to the AzDO build URL> ### Root cause 1: <short title> <2–3 sentences explaining the underlying issue and which symptoms it produces.> **Affected files / errors** - [`path/to/file.cs:42`](<permalink>) — `CS0103: ...` **Proposed fix** ```diff - old line + new line ``` ### Root cause 2: <short title> … (repeat) … --- <details><summary><b>Build overview</b></summary> <paste the build-overview output: configuration, TFM, target that failed.> </details> <details><summary><b>All MSBuild errors (N)</b></summary> | Code | Project | File:Line | Message | | ---- | ------- | --------- | ------- | | `CS0103` | `Foo` | `Bar.cs:42` | The name 'foo' does not exist… | </details> <sub>🤖 Generated by the `binlog-failure-analysis` skill · binlog from AzDO build <code>$AZDO_BUILD_ID</code></sub> ``` Build permalinks as `${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/blob/${PR_HEAD_SHA}/<relative-path>#L<line>`. ### Step 6 — Post inline suggestions (optional, best-effort) > ℹ️ **This step is best-effort.** Skip it entirely if no error fits cleanly — a high-quality summary comment alone is more valuable than speculative inline edits. The skill is considered successful even when Step 6 produces zero comments. When (and **only** when) an error has all of the following: - a `file:line` that lies **inside the PR diff** (verify with `gh pr diff`), - a fix that is exactly one or a few contiguous lines, and - a fix you can render as valid code (no pseudo-code, no TODOs), post one inline review comment via `gh api /repos/{owner}/{repo}/pulls/{n}/comments` with a `suggestion` code block: ````markdown 🔧 **`<error-code>`** — <one-sentence explanation> ```suggestion <replacement line(s); preserve indentation> ``` ```` Hard caps: - ≤10 inline suggestions per run.
عرض على GitHub
ملف SKILL.md هذا كبير جدا، لذلك يعرض SkillsMP القسم الاول فقط هنا. عرض على GitHub