Guides the process of downloading and analyzing failing GitHub Actions logs to identify root causes of CI errors.
Install
mkdir -p .claude/skills/ci-test-failures && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/3299" && unzip -o skill.zip -d .claude/skills/ci-test-failures && rm skill.zipInstalls to .claude/skills/ci-test-failures
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Guide for diagnosing GitHub Actions test failures, extracting failed tests from runs, and creating or updating failing-test issues. Use this when asked to investigate GitHub Actions test failures, download failure logs, create failing-test issues, or debug CI issues.Key capabilities
- →Fetch failed CI job logs
- →Download test artifacts
- →Create failing-test issues
- →Analyze .trx test results
- →Extract error patterns from logs
How it works
Uses automated tools to download logs and artifacts, then parses results to identify failures and file issues.
Inputs & outputs
When to use ci-test-failures
- →Debug failed CI/CD pipelines
- →Download logs from GitHub Actions
- →Identify root causes of build failures
About this skill
CI Test Failure Diagnosis and Issue Filing
Recipe: Create an Issue for a Test Failure
When the user asks to create an issue for a failing test, follow these steps. Always redirect full output to a log file (not tail) so you can inspect it if the command fails.
Step 1: List failed tests (if user didn't specify one)
Omit --test to discover all failures. Redirect output to a log file:
dotnet run --project tools/CreateFailingTestIssue -- \
--url "<the-url-the-user-gave>" \
--output /tmp/cfti-result.json \
> /tmp/cfti-list.log 2>&1
dotnet run --project tools/CreateFailingTestIssue -- `
--url "<the-url-the-user-gave>" `
--output $env:TEMP/cfti-result.json `
> $env:TEMP/cfti-list.log 2>&1
Then read the result with jq:
jq '{ success, availableFailedTests: .diagnostics.availableFailedTests, errorMessage: .errorMessage }' /tmp/cfti-result.json
Get-Content $env:TEMP/cfti-result.json | ConvertFrom-Json | Select-Object success, errorMessage, @{N='availableFailedTests';E={$_.diagnostics.availableFailedTests}}
If success is false, inspect the full log: cat /tmp/cfti-list.log (bash) or Get-Content $env:TEMP/cfti-list.log (PowerShell).
Ask the user which test to file for, then proceed to Step 2.
Step 2: Create the issue
dotnet run --project tools/CreateFailingTestIssue -- \
--url "<the-url-the-user-gave>" \
--test "<test-name>" \
--create \
--output /tmp/cfti-result.json \
> /tmp/cfti-create.log 2>&1
dotnet run --project tools/CreateFailingTestIssue -- `
--url "<the-url-the-user-gave>" `
--test "<test-name>" `
--create `
--output $env:TEMP/cfti-result.json `
> $env:TEMP/cfti-create.log 2>&1
Then read the result:
jq '{ success, issue: .issue.createdIssue, errorMessage: .errorMessage }' /tmp/cfti-result.json
Get-Content $env:TEMP/cfti-result.json | ConvertFrom-Json | Select-Object success, errorMessage, @{N='issue';E={$_.issue.createdIssue}}
If success is false, inspect the full log: cat /tmp/cfti-create.log (bash) or Get-Content $env:TEMP/cfti-create.log (PowerShell).
That's it — do not add analysis comments, do not use --dry-run unless the user explicitly asks for a preview.
Rules:
- Always use
--output <file>to keep JSON clean. Do NOT try to parse JSON from stdout — it is interleaved with dotnet build progress output. - Use
jqto extract fields from the output file. Key paths:.success— whether the operation succeeded.issue.createdIssue.numberand.issue.createdIssue.url— the created/updated issue.diagnostics.availableFailedTests[]— test names when--testis omitted.errorMessage— error details when.successis false
- Do NOT create issues manually with
gh issue create. The tool handles everything: resolving the run, finding the test, generating a template-compliant body, and creating the issue. - Do NOT invent your own issue markdown. The tool generates content that matches
.github/ISSUE_TEMPLATE/50_failing_test.yml. - If the tool fails, report the error from
diagnostics.logand the JSON output. Do not fall back to manual issue creation.
Recipe: Investigate a Failing Run (No Issue Creation)
To download and inspect failure artifacts without creating an issue:
cd tools/scripts
dotnet run DownloadFailingJobLogs.cs -- <run-id>
Set-Location tools/scripts
dotnet run DownloadFailingJobLogs.cs -- <run-id>
Then search the downloaded logs and .trx files for errors.
Reference Documentation
Everything below is reference material for edge cases and deeper investigation.
Overview
Use this skill in two phases:
- Investigate the run with
DownloadFailingJobLogs.csto fetch failed job logs and artifacts. - Create or update a failing-test issue with
tools/CreateFailingTestIssue --create.
Tools covered
| Tool | Purpose | Location |
|---|---|---|
DownloadFailingJobLogs.cs | Download failed job logs and test artifacts from a GitHub Actions run | tools/scripts/DownloadFailingJobLogs.cs |
CreateFailingTestIssue | Resolve a failing test from PR/run/job URLs and create/update issues | tools/CreateFailingTestIssue |
/create-issue workflow | Create, reopen, or comment on failing-test issues from issue/PR comments | .github/workflows/create-failing-test-issue.yml |
Quick Start
Step 1: Find the Run ID
Get the run ID from the GitHub Actions URL or use the gh CLI:
# From URL: https://github.com/microsoft/aspire/actions/runs/19846215629
# ^^^^^^^^^^
# run ID
# Or find the latest run on a branch
gh run list --repo microsoft/aspire --branch <branch-name> --limit 1 --json databaseId --jq '.[0].databaseId'
# Or for a PR
gh pr checks <pr-number> --repo microsoft/aspire
# From URL: https://github.com/microsoft/aspire/actions/runs/19846215629
# ^^^^^^^^^^
# run ID
# Or find the latest run on a branch
gh run list --repo microsoft/aspire --branch <branch-name> --limit 1 --json databaseId --jq '.[0].databaseId'
# Or for a PR
gh pr checks <pr-number> --repo microsoft/aspire
Step 2: Run the Tool
cd tools/scripts
dotnet run DownloadFailingJobLogs.cs -- <run-id>
Set-Location tools/scripts
dotnet run DownloadFailingJobLogs.cs -- <run-id>
Example:
dotnet run DownloadFailingJobLogs.cs -- 19846215629
Step 3: Analyze Output
The tool creates files in your current directory:
| File Pattern | Contents |
|---|---|
failed_job_<n>_<job-name>.log | Raw job logs from GitHub Actions |
artifact_<n>_<testname>_<os>.zip | Downloaded artifact zip files |
artifact_<n>_<testname>_<os>/ | Extracted directory with .trx files, logs, binlogs |
What the Tool Does
- Finds all failed jobs in a GitHub Actions workflow run
- Downloads job logs for each failed job
- Extracts test failures and errors from logs using regex patterns
- Determines artifact names from job names (pattern:
logs-{testShortName}-{os}) - Downloads test artifacts containing .trx files and test logs
- Extracts artifacts to local directories for inspection
Creating or Updating Failing-Test Issues
After you know which test failed, use the branch automation to create a failing-test issue in the known-issues format.
Preferred path: /create-issue from a PR or issue comment
Comment on the PR or issue with:
/create-issue --test "<test-name>" [--url <pr|run|job-url>] [--workflow <selector>] [--force-new]
Examples:
/create-issue --test "Tests.Namespace.Type.Method(input: 1)"
/create-issue --test "Tests.Namespace.Type.Method(input: 1)" --url https://github.com/microsoft/aspire/actions/runs/123
/create-issue "Tests.Namespace.Type.Method(input: 1)" https://github.com/microsoft/aspire/actions/runs/123/job/456
/create-issue --test "Tests.Namespace.Type.Method(input: 1)" --url https://github.com/microsoft/aspire/actions/runs/123/attempts/2/job/456?pr=321 --force-new
Notes:
- When the command is posted on a PR and no
--urlis supplied, the workflow defaults to that PR URL. --workflowdefaults toci.--force-newbypasses issue reuse and always requests a fresh issue.- The workflow requires write or admin access to the repository before it will create or update issues.
Supported source URLs
The resolver accepts:
- Pull request URLs:
https://github.com/<owner>/<repo>/pull/<number> - Workflow run URLs:
https://github.com/<owner>/<repo>/actions/runs/<run-id> - Attempt URLs:
https://github.com/<owner>/<repo>/actions/runs/<run-id>/attempts/<attempt> - Job URLs:
https://github.com/<owner>/<repo>/actions/runs/<run-id>/job/<job-id> - Attempt job URLs with query strings
Local path: run the resolver directly
Always use --output to write results to a file so JSON is not interleaved with build output:
To generate the JSON result locally without creating an issue (dry run):
dotnet run --project tools/CreateFailingTestIssue -- \
--url "https://github.com/microsoft/aspire/actions/runs/123" \
--test "<test-name>" \
--repo "microsoft/aspire" \
--output /tmp/cfti-result.json
dotnet run --project tools/CreateFailingTestIssue -- `
--url "https://github.com/microsoft/aspire/actions/runs/123" `
--test "<test-name>" `
--repo "microsoft/aspire" `
--output $env:TEMP/cfti-result.json
To resolve the failure and create the issue on GitHub in one step:
dotnet run --project tools/CreateFailingTestIssue -- \
--url "https://github.com/microsoft/aspire/actions/runs/123" \
--test "<test-name>" \
--repo "microsoft/aspire" \
--create \
--output /tmp/cfti-result.json
dotnet run --project tools/CreateFailingTestIssue -- `
--url "https://github.com/microsoft/aspire/actions/runs/123" `
--test "<test-name>" `
--repo "microsoft/aspire" `
--create `
--output $env:TEMP/cfti-result.json
Read the result with jq:
jq '{ success, issue: .issue, availableFailedTests: .diagnostics.availableFailedTests }' /tmp/cfti-result.json
Get-Content $env:TEMP/cfti-result.json | ConvertFrom-Json | Select-Object success, @{N='issue';E={$_.issue}}, @{N='availableFailedTests';E={$_.diagnostics.availableFailedTests}}
If --test is omitted, the tool emits structured JSON for all failing tests it found in the run (useful for picking which test to file).
The command writes a diagnostics.log file in the current directory. The JSON output (written to the --output file or stdout) contains:
- the resolved run and job URLs
- either the matched ca
Content truncated.
When not to use it
- →When manual issue creation is required
- →Without GitHub CLI authentication
Prerequisites
Limitations
- →Requires GitHub CLI access
- →Limited to supported repository workflows
How it compares
It automates the entire diagnostic and issue-filing workflow, replacing manual log searching and issue creation.
Compared to similar skills
ci-test-failures side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| ci-test-failures (this skill) | 1 | 2mo | Review | Intermediate |
| gha | 1 | 6mo | No flags | Intermediate |
| github-actions-failure-debugging | 1 | 7mo | No flags | Intermediate |
| fix-ci | 0 | 3mo | Review | Advanced |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by dotnet
View all by dotnet →You might also like
gha
ykdojo
Analyze GitHub Actions failures and identify root causes
github-actions-failure-debugging
Rabithua
Guide for debugging failing GitHub Actions workflows. Use this when asked to debug failing GitHub Actions workflows.
fix-ci
nickolashkraus
>
github-actions-lookup
matthieumarshall
Look up GitHub Actions run results for login-page CI/CD pipeline and collect failure details including logs, job outcomes, and diagnostics. Use when: investigating CI failures on main or add_security_standards branches, debugging workflow issues, checking latest PR build status, or collecting build
dependency-auditor
alirezarezvani
Check dependencies for known vulnerabilities using npm audit, pip-audit, etc. Use when package.json or requirements.txt changes, or before deployments. Alerts on vulnerable dependencies. Triggers on dependency file changes, deployment prep, security mentions.
github-actions-templates
wshobson
Create production-ready GitHub Actions workflows for automated testing, building, and deploying applications. Use when setting up CI/CD with GitHub Actions, automating development workflows, or creating reusable workflow templates.