Writing Skills
writing-skills
效率与协作技能,来自 obra/superpowers,查看原文获取完整用途和操作说明。
flaky-smoke-tests诊断来自 Azure DevOps Flaky Smoke Tests 管道(definition 700)的间歇性 VS Code Electron 烟雾测试失败。涵盖查找失败迭代、使用 Azure CLI 下载任务日志和平台工件、关联累计 runner 日志、追踪引入故障的提交,以及排队有针对性的验证运行。
AI 翻译
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Use this skill for failures from the Azure DevOps Flaky Smoke Tests pipeline:
https://dev.azure.com/monacotoolsMonaco700build/azure-pipelines/product-smoke-flaky.ymlmainThe pipeline builds VS Code from source and runs the complete Electron smoke suite once per entry in the iterations parameter. Each platform runs its iterations sequentially in one job.
Smoke test iteration <N>/<total> (Electron).continueOnError: true, so a failed iteration normally has result succeededWithIssues and later iterations still run..build/logs directory. The artifact is job-scoped, not iteration-scoped: smoke-test-runner.log can contain multiple iterations, and suite directories are not separated by iteration.Platform definitions and artifacts:
| Platform | Job | Logs artifact | Crash artifact |
|---|---|---|---|
| macOS arm64 | macOSSmokeFlaky | logs-macos-arm64-smoke-<attempt> | crash-dump-macos-arm64-smoke-<attempt> |
| Windows x64 | WindowsSmokeFlaky | logs-windows-x64-smoke-<attempt> | crash-dump-windows-x64-smoke-<attempt> |
| Linux x64 | LinuxSmokeFlaky | logs-linux-x64-smoke-<attempt> | crash-dump-linux-x64-smoke-<attempt> |
Use Azure CLI rather than the browser:
az --version
az extension show --name azure-devops
az devops configure --defaults \
organization=https://dev.azure.com/monacotools \
project=Monaco
If authentication fails, run az login.
az pipelines build show \
--id <BUILD_ID> \
--org https://dev.azure.com/monacotools \
--project Monaco \
--query "{id:id,status:status,result:result,sourceBranch:sourceBranch,sourceVersion:sourceVersion,templateParameters:templateParameters}" \
--output json
Record sourceVersion. Investigate the exact code built by the pipeline, not the current working tree.
Download the build timeline:
az devops invoke \
--org https://dev.azure.com/monacotools \
--area build \
--resource timeline \
--route-parameters project=Monaco buildId=<BUILD_ID> \
--output json
Filter task records whose names contain Smoke test iteration. Treat succeededWithIssues, failed, and tasks with error issues as failed iterations. Record:
ididnamestartTime and finishTimelog.idissuesIf the user supplied an Azure log URL, its j= value is the job ID and its t= value is the task ID. Query those records directly:
az devops invoke \
--org https://dev.azure.com/monacotools \
--area build \
--resource timeline \
--route-parameters project=Monaco buildId=<BUILD_ID> \
--query "records[?id=='<JOB_OR_TASK_ID>'].{id:id,parentId:parentId,name:name,type:type,state:state,result:result,logId:log.id,startTime:startTime,finishTime:finishTime,issues:issues}" \
--output json
Use timeline record log.id. The correct REST resource is logs, not buildLog:
az devops invoke \
--org https://dev.azure.com/monacotools \
--area build \
--resource logs \
--route-parameters project=Monaco buildId=<BUILD_ID> logId=<LOG_ID> \
--out-file task-log.json
The downloaded response is JSON with a value array containing one string per log line. Convert it to plain text.
PowerShell:
(Get-Content -Raw task-log.json | ConvertFrom-Json).value |
Set-Content task-log.txt
Bash:
jq -r '.value[]' task-log.json > task-log.txt
The task log provides the concise Mocha failure, stack, and the iteration's exact time range even before platform artifacts are published. Diagnostics written through the smoke runner's Logger (including dumpFailureDiagnostics) may exist only in smoke-test-runner.log, so do not assume they will be present in the Azure task log.
List artifacts first; names include the job attempt:
az pipelines runs artifact list \
--run-id <BUILD_ID> \
--org https://dev.azure.com/monacotools \
--project Monaco \
--output table
Download the relevant platform:
az pipelines runs artifact download \
--run-id <BUILD_ID> \
--artifact-name <LOGS_ARTIFACT> \
--path <DESTINATION> \
--org https://dev.azure.com/monacotools \
--project Monaco
Artifacts are available after the platform job publishes its outputs. An absent platform artifact after a canceled run is expected; it is not evidence that the artifact name was wrong.
Start with <DESTINATION>/smoke-tests-electron/smoke-test-runner.log. Use the failed task's timestamps and test title to isolate the matching Test start / Test end interval. Do not use the first occurrence of a test title because the runner log can contain several iterations.
Within that interval, establish this chain:
For mock-LLM suites, search for:
request body:model turn 1/2 and model turn 2/2The request log distinguishes:
Then inspect the suite directory:
smoke-tests-electron/<N>_suite_<Suite_Name>/
Useful files include:
window*/exthost/<extension>/<extension>.logmain.log, renderer.log, and agenthost.logcopilot-runtime-logs/process-*.log — the Copilot runtime (@github/copilot CLI) process logs, captured by dumpFailureDiagnostics when a Copilot-runtime session fails. Check these first for a hang or "Timed out waiting for response": they are the SDK/CLI's own record (startup, auth, model request, turn lifecycle, panics, out-of-order or protocol errors) and explain a timeout the test error alone does not. A tail is also mirrored into smoke-test-runner.log. Agent Host sessions (Agents Window / local AgentHost) write a full log run at trace; Chat Sessions editor (Copilot CLI / Claude) and Local sessions write only a minimal startup log here (whether the runtime came up), with their detailed diagnostics in GitHub Copilot Chat.log. (Claude / Codex sessions use a different runtime and are not captured here.)playwright-screenshot-*.pngFor native exits or renderer crashes, also download the platform crash artifact.
Session-list text and active-view text answer different questions:
installAllHandlers use distinct randomized user-data directories. Do not attribute a setting from the preceding suite to the failing suite without comparing the actual vscode-userdata: or --user-data-dir paths in their logs. Iterations share broader job state, but sibling suites normally do not share the same profile.Prefer assertions that establish identity:
Do not "fix" these races by only increasing a timeout. Wait for the actual state transition or remove duplicate/in-flight work.
Use the build's sourceVersion and identify the source file from the stack:
git show <SOURCE_VERSION>:test/smoke/src/areas/<area>/<test>.test.ts
git log --oneline <KNOWN_GOOD>..<SOURCE_VERSION> -- <relevant paths>
git blame -L <start>,<end> <file>
git show <SUSPECT_COMMIT> -- <relevant paths>
Trace the whole causal sequence, not only the failing assertion. For example, inspect setup hooks, warm-ups, session selection, response waits, and teardown.
Distinguish:
State the introducing commit only when the diff contains the causal behavior and the pipeline evidence matches it.
The branch and commit must already be pushed to microsoft/vscode. Check for and cancel obsolete definition-700 runs on the same branch before queueing.
Use az pipelines run directly because iterations is an object parameter:
az pipelines run \
--id 700 \
--branch <BRANCH> \
--commit-id <COMMIT_SHA> \
--parameters "iterations=[1,2,3,4,5,6]" \
VSCODE_BUILD_MACOS=true \
VSCODE_BUILD_LINUX=false \
VSCODE_BUILD_WIN32=true \
--org https://dev.azure.com/monacotools \
--project Monaco \
--output json
Enable only platforms relevant to the failure. Confirm the queued run's sourceVersion and templateParameters with az pipelines build show.
Six iterations are a useful quick validation sample. Use the default 20 when the failure is rare or when validating before declaring a recurring flake resolved.
For smoke-test TypeScript changes:
npm run compile --prefix test/smoke
node --experimental-strip-types build/hygiene.ts <changed-file>
If local dependencies are missing or stale, report that explicitly and rely on the focused definition-700 run for full compiled validation; do not silently skip validation or install unrelated tooling.
Summarize: