Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions marketplaces/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,32 @@
"preview",
"hosting"
]
},
{
"name": "debug-github-ci",
"source": "./debug-github-ci",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion - Path Ambiguity: You claim pluginRoot: "./skills" resolves these paths, but that configuration isn't visible in this diff.

Either:

  1. Show the full marketplace context where pluginRoot is set
  2. Use explicit paths: "./skills/debug-github-ci"

Relying on invisible context makes this PR impossible to review accurately.

"description": "Debug GitHub Actions CI failures by fetching logs, identifying root causes, and suggesting fixes.",
"category": "debugging",
"keywords": [
"github",
"ci",
"actions",
"debugging",
"workflow"
]
},
{
"name": "debug-jenkins-ci",
"source": "./debug-jenkins-ci",
"description": "Debug Jenkins CI/CD pipeline failures by fetching logs, identifying root causes, and suggesting fixes.",
"category": "debugging",
"keywords": [
"jenkins",
"ci",
"pipeline",
"debugging",
"build"
]
}
]
}
151 changes: 151 additions & 0 deletions plugins/debug-github-ci/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# Debug GitHub CI Plugin

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion - Plugin vs Skill Clarity: This README says "Plugin" but you registered it as a skill in the marketplace.

From the repo's AGENTS.md:

  • Skills = progressive disclosure guidance (SKILL.md)
  • Plugins = executable code with lifecycle hooks

You have both. Which is the primary artifact? The marketplace registration suggests "skill" but this README and the action.yml suggest "plugin".

Pick one identity or clearly document the dual-mode usage.


Automated debugging of GitHub Actions CI failures using OpenHands agents. This plugin provides GitHub workflows that automatically diagnose and suggest fixes when CI fails.

## Quick Start

Copy the workflow file to your repository:

```bash
mkdir -p .github/workflows
curl -o .github/workflows/debug-ci-failure.yml \
https://raw.githubusercontent.com/OpenHands/extensions/main/plugins/debug-github-ci/workflows/debug-ci-failure.yml
```

Then configure the required secrets (see [Installation](#installation) below).

## Features

- **Automatic CI Failure Analysis**: Triggered when workflow runs fail
- **Log Analysis**: Fetches and analyzes failed job logs to identify root causes
- **Actionable Suggestions**: Posts comments with specific fixes and commands
- **Error Pattern Recognition**: Identifies common CI failure patterns
- **Context-Aware**: Considers recent commits and PR changes

## Plugin Contents

```
plugins/debug-github-ci/
├── README.md # This file
├── action.yml # Composite GitHub Action
├── skills/ # Symbolic links to debug skills
│ └── debug-github-ci -> ../../../skills/debug-github-ci
├── workflows/ # Example GitHub workflow files
│ └── debug-ci-failure.yml
└── scripts/ # Python scripts for debug execution
├── agent_script.py # Main CI debug agent script
└── prompt.py # Prompt template for debugging
```

## Installation

### 1. Copy the Workflow File

Copy the workflow file to your repository's `.github/workflows/` directory:

```bash
mkdir -p .github/workflows
curl -o .github/workflows/debug-ci-failure.yml \
https://raw.githubusercontent.com/OpenHands/extensions/main/plugins/debug-github-ci/workflows/debug-ci-failure.yml
```

### 2. Configure Secrets

Add the following secrets in your repository settings (**Settings → Secrets and variables → Actions**):

| Secret | Required | Description |
|--------|----------|-------------|
| `LLM_API_KEY` | Yes | API key for your LLM provider |
| `GITHUB_TOKEN` | Auto | Provided automatically by GitHub Actions |

### 3. Customize the Workflow (Optional)

Edit the workflow file to customize:

```yaml
- name: Debug CI Failure
uses: OpenHands/extensions/plugins/debug-github-ci@main
with:
# LLM model to use
llm-model: anthropic/claude-sonnet-4-5-20250929

# Secrets
llm-api-key: ${{ secrets.LLM_API_KEY }}
github-token: ${{ secrets.GITHUB_TOKEN }}
```

## Usage

### Automatic Triggers

CI debugging is automatically triggered when:

1. A workflow run fails on the repository
2. The `debug-ci` label is added to a PR with failed checks

### Manual Trigger

You can manually trigger debugging:

1. Go to **Actions** tab
2. Select **Debug CI Failure** workflow
3. Click **Run workflow**
4. Enter the failed run ID

## Action Inputs

| Input | Required | Default | Description |
|-------|----------|---------|-------------|
| `llm-model` | No | `anthropic/claude-sonnet-4-5-20250929` | LLM model to use |
| `llm-base-url` | No | `''` | Custom LLM endpoint URL |
| `run-id` | No | Auto | Specific workflow run ID to debug |
| `extensions-repo` | No | `OpenHands/extensions` | Extensions repository |
| `extensions-version` | No | `main` | Git ref (tag, branch, or SHA) |
| `llm-api-key` | Yes | - | LLM API key |
| `github-token` | Yes | - | GitHub token for API access |

## What Gets Analyzed

The agent analyzes:

1. **Failed job logs**: Console output from failed steps
2. **Error messages**: Specific error patterns and stack traces
3. **Recent commits**: Changes that may have caused the failure
4. **Workflow configuration**: Issues in the workflow YAML
5. **Dependencies**: Version conflicts or missing packages

## Output

The agent posts a comment with:

- **Root Cause Analysis**: What caused the failure
- **Suggested Fixes**: Specific commands or code changes
- **Prevention Tips**: How to avoid similar failures

## Troubleshooting

### Debug Not Triggered

1. Ensure the workflow file is in `.github/workflows/`
2. Verify secrets are configured correctly
3. Check that the workflow has `workflow_run` trigger permissions

### Analysis Incomplete

1. Check if logs are available (some expire after 90 days)
2. Verify the `GITHUB_TOKEN` has read access to workflow logs
3. Increase timeout if analysis takes too long

## Security

- Uses `workflow_run` event for secure access to secrets
- Only analyzes public workflow logs
- Does not execute any code from the failed run

## Contributing

See the main [extensions repository](https://github.com/OpenHands/extensions) for contribution guidelines.

## License

This plugin is part of the OpenHands extensions repository. See [LICENSE](../../LICENSE) for details.
122 changes: 122 additions & 0 deletions plugins/debug-github-ci/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
---
name: OpenHands Debug GitHub CI
description: Automated CI failure debugging using OpenHands agent
author: OpenHands

branding:
icon: alert-circle
color: red

inputs:
llm-model:
description: LLM model to use for debugging
required: false
default: anthropic/claude-sonnet-4-5-20250929
llm-base-url:
description: LLM base URL (optional, for custom LLM endpoints)
required: false
default: ''
run-id:
description: Specific workflow run ID to debug (auto-detected if not provided)
required: false
default: ''
extensions-repo:
description: GitHub repository for extensions (owner/repo)
required: false
default: OpenHands/extensions
extensions-version:
description: Git ref to use for extensions (tag, branch, or commit SHA)
required: false
default: main
llm-api-key:
description: LLM API key (required)
required: true
github-token:
description: GitHub token for API access (required)
required: true

runs:
using: composite
steps:
- name: Checkout extensions repository
uses: actions/checkout@v4
with:
repository: ${{ inputs.extensions-repo }}
ref: ${{ inputs.extensions-version }}
path: extensions

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Install uv
uses: astral-sh/setup-uv@v6
with:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion - Cache in Debug Tool: Previous review flagged this. You defended it with "reproducibility", but for a debug tool analyzing CI failures, you want fresh state.

The cache could hide the very problem you're debugging (e.g., "works on my cached env but fails on fresh install").

Consider making this opt-in: use cache only if debug-use-cache: true is explicitly set.

enable-cache: true

- name: Install GitHub CLI
shell: bash
run: |
sudo apt-get update
sudo apt-get install -y gh

- name: Determine run ID
id: get-run-id
shell: bash
env:
GITHUB_TOKEN: ${{ inputs.github-token }}
INPUT_RUN_ID: ${{ inputs.run-id }}
run: |
if [ -n "$INPUT_RUN_ID" ]; then
echo "run_id=$INPUT_RUN_ID" >> $GITHUB_OUTPUT
elif [ -n "${{ github.event.workflow_run.id }}" ]; then
echo "run_id=${{ github.event.workflow_run.id }}" >> $GITHUB_OUTPUT
else
# Get the most recent failed run
RUN_ID=$(gh run list --status failure --limit 1 --json databaseId --jq '.[0].databaseId')
echo "run_id=$RUN_ID" >> $GITHUB_OUTPUT
fi

- name: Check required configuration
shell: bash
env:
LLM_API_KEY: ${{ inputs.llm-api-key }}
GITHUB_TOKEN: ${{ inputs.github-token }}
run: |
if [ -z "$LLM_API_KEY" ]; then
echo "Error: llm-api-key is required."
exit 1
fi

if [ -z "$GITHUB_TOKEN" ]; then
echo "Error: github-token is required."
exit 1
fi

echo "Run ID to debug: ${{ steps.get-run-id.outputs.run_id }}"
echo "Repository: ${{ github.repository }}"
echo "LLM model: ${{ inputs.llm-model }}"

- name: Run CI debug analysis
shell: bash
env:
LLM_MODEL: ${{ inputs.llm-model }}
LLM_BASE_URL: ${{ inputs.llm-base-url }}
LLM_API_KEY: ${{ inputs.llm-api-key }}
GITHUB_TOKEN: ${{ inputs.github-token }}
RUN_ID: ${{ steps.get-run-id.outputs.run_id }}
REPO_NAME: ${{ github.repository }}
run: |
uv run --with openhands-sdk --with openhands-tools \
python extensions/plugins/debug-github-ci/scripts/agent_script.py

- name: Upload logs as artifact
uses: actions/upload-artifact@v4
if: always()
with:
name: openhands-ci-debug-logs
path: |
*.log
output/
retention-days: 7
Loading
Loading