Repository navigation
refactor: Use composite GitHub Action for PR review workflow #1927
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4864ff2
9318dde
24ba17a
7393a5a
fcec737
5614298
983b44f
d510dbd
256a944
7c29c92
a0ac453
55d19b2
35f5d0a
8097053
62db20a
da2095e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,129 @@ | ||||||||
| --- | ||||||||
| name: OpenHands PR Review | ||||||||
| description: Automated PR review using OpenHands agent | ||||||||
| author: OpenHands | ||||||||
|
|
||||||||
| branding: | ||||||||
| icon: code | ||||||||
| color: blue | ||||||||
|
|
||||||||
| inputs: | ||||||||
| llm-model: | ||||||||
| description: LLM model to use for the review | ||||||||
| required: false | ||||||||
| default: anthropic/claude-sonnet-4-5-20250929 | ||||||||
| llm-base-url: | ||||||||
| description: LLM base URL (optional, for custom LLM endpoints) | ||||||||
| required: false | ||||||||
| default: '' | ||||||||
| review-style: | ||||||||
| description: "Review style: 'standard' (balanced review covering style, readability, and security) or 'roasted' (Linus Torvalds-style brutally honest | ||||||||
| feedback focusing on data structures, simplicity, and pragmatism)" | ||||||||
| required: false | ||||||||
| default: roasted | ||||||||
| sdk-repo: | ||||||||
| description: GitHub repository for the SDK (owner/repo) | ||||||||
| required: false | ||||||||
| default: OpenHands/software-agent-sdk | ||||||||
| sdk-version: | ||||||||
| description: Git ref to use for the SDK (tag, branch, or commit SHA, e.g., v1.0.0, main, or abc1234) | ||||||||
| required: false | ||||||||
| default: main | ||||||||
|
enyst marked this conversation as resolved.
|
||||||||
| 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 software-agent-sdk repository | ||||||||
| uses: actions/checkout@v4 | ||||||||
| with: | ||||||||
| repository: ${{ inputs.sdk-repo }} | ||||||||
| ref: ${{ inputs.sdk-version }} | ||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Suggestion: Consider documenting the security implications of the |
||||||||
| path: software-agent-sdk | ||||||||
|
|
||||||||
| - name: Checkout PR repository | ||||||||
| uses: actions/checkout@v4 | ||||||||
| with: | ||||||||
| repository: ${{ github.event.pull_request.head.repo.full_name }} | ||||||||
| ref: ${{ github.event.pull_request.head.ref }} | ||||||||
| fetch-depth: 0 | ||||||||
| persist-credentials: false | ||||||||
| path: pr-repo | ||||||||
|
|
||||||||
| - name: Set up Python | ||||||||
| uses: actions/setup-python@v5 | ||||||||
| with: | ||||||||
| python-version: '3.12' | ||||||||
|
|
||||||||
| - name: Install uv | ||||||||
| uses: astral-sh/setup-uv@v6 | ||||||||
| with: | ||||||||
| enable-cache: true | ||||||||
|
|
||||||||
| - name: Install GitHub CLI | ||||||||
| shell: bash | ||||||||
| run: | | ||||||||
| sudo apt-get update | ||||||||
| sudo apt-get install -y gh | ||||||||
|
|
||||||||
| - name: Install OpenHands dependencies | ||||||||
| shell: bash | ||||||||
| run: | | ||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟢 Nit: Using
Suggested change
|
||||||||
| uv pip install --system ./software-agent-sdk/openhands-sdk ./software-agent-sdk/openhands-tools | ||||||||
|
|
||||||||
| - 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 "PR Number: ${{ github.event.pull_request.number }}" | ||||||||
| echo "PR Title: ${{ github.event.pull_request.title }}" | ||||||||
| echo "Repository: ${{ github.repository }}" | ||||||||
| echo "SDK Version: ${{ inputs.sdk-version }}" | ||||||||
| echo "LLM model: ${{ inputs.llm-model }}" | ||||||||
| if [ -n "${{ inputs.llm-base-url }}" ]; then | ||||||||
| echo "LLM base URL: ${{ inputs.llm-base-url }}" | ||||||||
| fi | ||||||||
|
|
||||||||
| - name: Run PR review | ||||||||
| shell: bash | ||||||||
| env: | ||||||||
| LLM_MODEL: ${{ inputs.llm-model }} | ||||||||
| LLM_BASE_URL: ${{ inputs.llm-base-url }} | ||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟢 Nit: Empty string for |
||||||||
| REVIEW_STYLE: ${{ inputs.review-style }} | ||||||||
| LLM_API_KEY: ${{ inputs.llm-api-key }} | ||||||||
| GITHUB_TOKEN: ${{ inputs.github-token }} | ||||||||
| PR_NUMBER: ${{ github.event.pull_request.number }} | ||||||||
| PR_TITLE: ${{ github.event.pull_request.title }} | ||||||||
| PR_BODY: ${{ github.event.pull_request.body }} | ||||||||
| PR_BASE_BRANCH: ${{ github.event.pull_request.base.ref }} | ||||||||
| PR_HEAD_BRANCH: ${{ github.event.pull_request.head.ref }} | ||||||||
| REPO_NAME: ${{ github.repository }} | ||||||||
| run: | | ||||||||
| cd pr-repo | ||||||||
| uv run python ../software-agent-sdk/examples/03_github_workflows/02_pr_review/agent_script.py | ||||||||
|
|
||||||||
| - name: Upload logs as artifact | ||||||||
| uses: actions/upload-artifact@v4 | ||||||||
| if: always() | ||||||||
| with: | ||||||||
| name: openhands-pr-review-logs | ||||||||
| path: | | ||||||||
| *.log | ||||||||
| output/ | ||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 Critical: The artifact paths are incorrect. The script runs with Fix:
Suggested change
|
||||||||
| retention-days: 7 | ||||||||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -37,91 +37,15 @@ jobs: | |||||||
| group: pr-review-${{ github.event.pull_request.number }} | ||||||||
| cancel-in-progress: true | ||||||||
| runs-on: ubuntu-24.04 | ||||||||
| env: | ||||||||
| LLM_MODEL: litellm_proxy/claude-sonnet-4-5-20250929 | ||||||||
| LLM_BASE_URL: https://llm-proxy.app.all-hands.dev | ||||||||
| # PR context will be automatically provided by the agent script | ||||||||
| PR_NUMBER: ${{ github.event.pull_request.number }} | ||||||||
| PR_TITLE: ${{ github.event.pull_request.title }} | ||||||||
| PR_BODY: ${{ github.event.pull_request.body }} | ||||||||
| PR_BASE_BRANCH: ${{ github.event.pull_request.base.ref }} | ||||||||
| PR_HEAD_BRANCH: ${{ github.event.pull_request.head.ref }} | ||||||||
| REPO_NAME: ${{ github.repository }} | ||||||||
| steps: | ||||||||
| - name: Checkout software-agent-sdk repository | ||||||||
| uses: actions/checkout@v5 | ||||||||
| - name: Run PR Review | ||||||||
| uses: OpenHands/software-agent-sdk/.github/actions/pr-review@main | ||||||||
| with: | ||||||||
| repository: OpenHands/software-agent-sdk | ||||||||
| path: software-agent-sdk | ||||||||
|
|
||||||||
| - name: Checkout PR repository | ||||||||
| uses: actions/checkout@v5 | ||||||||
| with: | ||||||||
| # When using pull_request_target, explicitly checkout the PR branch | ||||||||
| # This ensures we review the actual PR code (including fork PRs) | ||||||||
| repository: ${{ github.event.pull_request.head.repo.full_name }} | ||||||||
| ref: ${{ github.event.pull_request.head.ref }} | ||||||||
| fetch-depth: 0 | ||||||||
| # Security: Don't persist credentials to prevent untrusted PR code from using them | ||||||||
| persist-credentials: false | ||||||||
| path: pr-repo | ||||||||
|
|
||||||||
| - name: Set up Python | ||||||||
| uses: actions/setup-python@v6 | ||||||||
| with: | ||||||||
| python-version: '3.13' | ||||||||
|
|
||||||||
| - name: Install uv | ||||||||
| uses: astral-sh/setup-uv@v7 | ||||||||
| with: | ||||||||
| enable-cache: true | ||||||||
|
|
||||||||
| - name: Install GitHub CLI | ||||||||
| run: | | ||||||||
| # Install GitHub CLI for posting review comments | ||||||||
| sudo apt-get update | ||||||||
| sudo apt-get install -y gh | ||||||||
|
|
||||||||
| - name: Install OpenHands dependencies | ||||||||
| run: | | ||||||||
| # Install OpenHands SDK and tools from local checkout | ||||||||
| uv pip install --system ./software-agent-sdk/openhands-sdk ./software-agent-sdk/openhands-tools | ||||||||
|
|
||||||||
| - name: Check required configuration | ||||||||
| env: | ||||||||
| LLM_API_KEY: ${{ secrets.LLM_API_KEY }} | ||||||||
| run: | | ||||||||
| if [ -z "$LLM_API_KEY" ]; then | ||||||||
| echo "Error: LLM_API_KEY secret is not set." | ||||||||
| exit 1 | ||||||||
| fi | ||||||||
|
|
||||||||
| echo "PR Number: $PR_NUMBER" | ||||||||
| echo "PR Title: $PR_TITLE" | ||||||||
| echo "Repository: $REPO_NAME" | ||||||||
| echo "LLM model: $LLM_MODEL" | ||||||||
| if [ -n "$LLM_BASE_URL" ]; then | ||||||||
| echo "LLM base URL: $LLM_BASE_URL" | ||||||||
| fi | ||||||||
|
|
||||||||
| - name: Run PR review | ||||||||
| env: | ||||||||
| LLM_API_KEY: ${{ secrets.LLM_API_KEY }} | ||||||||
| GITHUB_TOKEN: ${{ secrets.ALLHANDS_BOT_GITHUB_PAT }} | ||||||||
| LMNR_PROJECT_API_KEY: ${{ secrets.LMNR_SKILLS_API_KEY }} | ||||||||
| run: | | ||||||||
| # Change to the PR repository directory so agent can analyze the code | ||||||||
| cd pr-repo | ||||||||
|
|
||||||||
| # Run the PR review script from the software-agent-sdk checkout | ||||||||
| uv run python ../software-agent-sdk/examples/03_github_workflows/02_pr_review/agent_script.py | ||||||||
|
|
||||||||
| - name: Upload logs as artifact | ||||||||
| uses: actions/upload-artifact@v5 | ||||||||
| if: always() | ||||||||
| with: | ||||||||
| name: openhands-pr-review-logs | ||||||||
| path: | | ||||||||
| *.log | ||||||||
| output/ | ||||||||
| retention-days: 7 | ||||||||
| llm-model: anthropic/claude-sonnet-4-5-20250929 | ||||||||
| llm-base-url: '' | ||||||||
| # Review style: roasted (other option: standard) | ||||||||
| review-style: roasted | ||||||||
| # Use the PR's head commit SHA to test SDK changes on the SDK repo itself | ||||||||
| sdk-version: ${{ github.event.pull_request.head.sha }} | ||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟢 Nit: This is clever for testing SDK changes on the SDK repo itself, but consider adding a comment explaining why this differs from the example workflow. It helps future maintainers understand the self-referential testing pattern.
Suggested change
|
||||||||
| llm-api-key: ${{ secrets.LLM_API_KEY }} | ||||||||
| github-token: ${{ secrets.ALLHANDS_BOT_GITHUB_PAT }} | ||||||||
|
xingyaoww marked this conversation as resolved.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,7 +4,8 @@ This example demonstrates how to set up a GitHub Actions workflow for automated | |
|
|
||
| ## Files | ||
|
|
||
| - **`workflow.yml`**: GitHub Actions workflow file that triggers on PR labels | ||
| - **`action.yml`**: Symlink to the composite GitHub Action (`.github/actions/pr-review/action.yml`) | ||
| - **`workflow.yml`**: Example GitHub Actions workflow file that uses the composite action | ||
| - **`agent_script.py`**: Python script that runs the OpenHands agent for PR review | ||
| - **`prompt.py`**: The prompt asking the agent to write the PR review | ||
| - **`README.md`**: This documentation file | ||
|
|
@@ -32,6 +33,7 @@ This example demonstrates how to set up a GitHub Actions workflow for automated | |
| - Potential issues and security concerns | ||
| - Specific improvement suggestions | ||
| - **GitHub API Integration**: Uses the GitHub API to post inline review comments directly on specific lines of code | ||
| - **Version Control**: Use `sdk-version` to pin to a specific version tag or branch | ||
|
|
||
| ## Setup | ||
|
|
||
|
|
@@ -54,18 +56,24 @@ Set the following secrets in your GitHub repository settings: | |
|
|
||
| ### 3. Customize the workflow (optional) | ||
|
|
||
| Edit `.github/workflows/pr-review-by-openhands.yml` to customize the configuration in the `env` section: | ||
| Edit `.github/workflows/pr-review-by-openhands.yml` to customize the inputs: | ||
|
|
||
| ```yaml | ||
| env: | ||
| # Optional: Use a different LLM model | ||
| LLM_MODEL: openhands/claude-sonnet-4-5-20250929 | ||
| # Optional: Use a custom LLM base URL | ||
| # LLM_BASE_URL: 'https://custom-api.example.com' | ||
| # Optional: Choose review style ('standard' or 'roasted') | ||
| # - 'standard': Pragmatic, constructive feedback (default) | ||
| # - 'roasted': Linus Torvalds style brutally honest review | ||
| REVIEW_STYLE: standard | ||
| - name: Run PR Review | ||
| uses: ./.github/actions/pr-review | ||
| with: | ||
| # LLM configuration | ||
| llm-model: anthropic/claude-sonnet-4-5-20250929 | ||
| llm-base-url: '' | ||
| # Review style: roasted (other option: standard) | ||
| review-style: roasted | ||
| # SDK git ref to use (tag, branch, or commit SHA, e.g., 'v1.0.0', 'main', or 'abc1234') | ||
| sdk-version: main | ||
| # Optional: override the SDK repo (owner/repo) if you forked it | ||
| sdk-repo: OpenHands/software-agent-sdk | ||
| # Secrets | ||
| llm-api-key: ${{ secrets.LLM_API_KEY }} | ||
| github-token: ${{ secrets.GITHUB_TOKEN }} | ||
| ``` | ||
|
|
||
| ### 4. Create the review label | ||
|
|
@@ -101,3 +109,78 @@ There are two ways to trigger an automated review of a pull request: | |
| 5. Review comments will be posted to the PR when complete | ||
|
|
||
| **Note**: Both methods require write access to the repository, ensuring only authorized users can trigger the AI review. | ||
|
|
||
| ## Customizing the Code Review | ||
|
|
||
| Instead of forking the `agent_script.py`, you can customize the code review behavior by adding a `.openhands/skills/code-review.md` file to your repository. This is the **recommended approach** for customization. | ||
|
|
||
| ### How It Works | ||
|
|
||
| The PR review agent uses skills from the [OpenHands/skills](https://github.com/OpenHands/skills) repository by default. When you add a `.openhands/skills/code-review.md` file to your repository, it **overrides** the default skill with your custom guidelines. | ||
|
|
||
| ### Example: Custom Code Review Skill | ||
|
|
||
| Create `.openhands/skills/code-review.md` in your repository: | ||
|
|
||
| ```markdown | ||
| --- | ||
| name: code-review | ||
| description: Custom code review guidelines for my project | ||
| triggers: | ||
| - /codereview | ||
| --- | ||
|
|
||
| # My Project Code Review Guidelines | ||
|
|
||
| You are a code reviewer for this project. Follow these guidelines: | ||
|
|
||
| ## Review Decisions | ||
|
|
||
| - **APPROVE** straightforward changes (config updates, typo fixes, documentation) | ||
| - **COMMENT** when you have feedback or concerns | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Out of curiosity, why not
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because then itll be slightlytricky for all-hands-bot to re-review and unblock again. in general, i dont want to see reviewer bot is blocking our PR with some trivialsuggestion 😓
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TBH in my experience so far, my concern is more the other way around: if it has That's why the idea I brought in slack about a workflow forcing it to address all comments, no matter how trivial, to make it think about them before dismissing them -that feels like a thing my yolo repos need 😅 I feel maybe it's good to keep it simpler... I'm not sure it'd be tricky the other way around, but maybe it would need to re-run in the same session, not from github actions with fresh context every time maybe (my little agents were run from CLI runs on my machine, and re-reviewed from the same session)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good point, maybe we can leave it as customizable for each repo. which probably outof the conext of this PR; but yeah agree on the blocker workflow |
||
|
|
||
| ## What to Check | ||
|
|
||
| - Code follows our project conventions | ||
| - Tests are included for new functionality | ||
| - No security vulnerabilities introduced | ||
| - Documentation is updated if needed | ||
|
|
||
| ## Communication Style | ||
|
|
||
| - Be direct and constructive | ||
| - Use GitHub suggestion syntax for code fixes | ||
| - Approve quickly when code is good | ||
| ``` | ||
|
|
||
| ### Benefits of Custom Skills | ||
|
|
||
| 1. **No forking required**: Keep using the official SDK while customizing behavior | ||
| 2. **Version controlled**: Your review guidelines live in your repository | ||
| 3. **Easy updates**: SDK updates don't overwrite your customizations | ||
| 4. **Team alignment**: Everyone uses the same review standards | ||
|
|
||
| ### Reference Example | ||
|
|
||
| See the [software-agent-sdk's own code-review skill](https://github.com/OpenHands/software-agent-sdk/blob/main/.openhands/skills/code-review.md) for a complete example of a custom code review skill. | ||
|
|
||
| ## Composite Action | ||
|
|
||
| This workflow uses a reusable composite action located at `.github/actions/pr-review/action.yml` in the software-agent-sdk repository. The composite action handles: | ||
|
enyst marked this conversation as resolved.
|
||
|
|
||
| - Checking out the SDK at the specified version | ||
| - Setting up Python and dependencies | ||
| - Running the PR review agent | ||
| - Uploading logs as artifacts | ||
|
|
||
| ### Action Inputs | ||
|
|
||
| | Input | Description | Required | Default | | ||
| |-------|-------------|----------|---------| | ||
| | `llm-model` | LLM model to use | No | `anthropic/claude-sonnet-4-5-20250929` | | ||
| | `llm-base-url` | LLM base URL (optional) | No | `''` | | ||
| | `review-style` | Review style: 'standard' or 'roasted' | No | `roasted` | | ||
| | `sdk-version` | Git ref for SDK (tag, branch, or commit SHA) | No | `main` | | ||
| | `sdk-repo` | SDK repository (owner/repo) | No | `OpenHands/software-agent-sdk` | | ||
| | `llm-api-key` | LLM API key | Yes | - | | ||
| | `github-token` | GitHub token for API access | Yes | - | | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| ../../../.github/actions/pr-review/action.yml |
Uh oh!
There was an error while loading. Please reload this page.