refactor: Use composite GitHub Action for PR review workflow#1927
refactor: Use composite GitHub Action for PR review workflow#1927
Conversation
This adds a new 'cloud' mode to the PR review workflow that launches reviews in OpenHands Cloud instead of running locally in GitHub Actions. Changes: - Add REVIEW_MODE environment variable (sdk/cloud) to agent_script.py - Add run_cloud_mode() function that: - Creates an OpenHandsCloudWorkspace with keep_alive=True - Starts a conversation and calls .run() - Posts a comment on the PR with the cloud conversation URL - Exits without monitoring (review continues asynchronously) - Add post_github_comment() helper function - Update workflow.yml example to support cloud mode - Update pr-review-by-openhands.yml to use cloud mode by default - Update README.md with cloud mode documentation - Add tests for the new functionality Cloud mode benefits: - Faster CI completion (exits after starting the review) - Track review progress in OpenHands Cloud UI - Interact with the review conversation Closes #1925 Co-authored-by: openhands <openhands@all-hands.dev>
…ud's model - Rename REVIEW_MODE environment variable to MODE - Keep LLM_MODEL and LLM_BASE_URL for SDK mode - In cloud mode, ignore LLM_MODEL and LLM_BASE_URL - the reviewer bot will use the model configured in the OpenHands Cloud account - Cloud mode no longer requires LLM_API_KEY, only OPENHANDS_CLOUD_API_KEY - Update workflow files and documentation to reflect these changes - Add _start_cloud_conversation() helper to call cloud API directly
- Create composite action at .github/actions/pr-review/action.yml - Add sdk-version input to allow checkout by version tag or branch name - Simplify pr-review-by-openhands.yml to use the composite action - Update example workflow.yml to use the composite action - Keep LLM_MODEL and LLM_BASE_URL inputs (used in sdk mode, ignored in cloud mode) - Update README.md with composite action documentation Co-authored-by: openhands <openhands@all-hands.dev>
When reviewing PRs on the SDK repo itself, this option allows the workflow to use the PR's head branch instead of the sdk-version input. This enables testing PR review changes with the code from the PR. Changes: - Add 'use-pr-branch-for-sdk' input to action.yml (default: false) - Add step to determine SDK ref based on the new option - Update pr-review-by-openhands.yml to use PR branch for both: - Initial action checkout - SDK checkout via use-pr-branch-for-sdk: true Co-authored-by: openhands <openhands@all-hands.dev>
Update the github-token input description and validation logic to note that it is not required for cloud mode when the OpenHands Cloud account has access to the repository. Co-authored-by: openhands <openhands@all-hands.dev>
Simplify the workflow by directly referencing the action from the repository path instead of checking out and using a local path. This standardizes the usage pattern that external repos will use. Co-authored-by: openhands <openhands@all-hands.dev>
|
@OpenHands merge from main, resolve the conflict, then review the diff from main. Please remove ALL the additional code that adds the cloud mode. Let's focus on making the composite github action in this PR. Please update PR description & title when you are done |
|
I'm on it! xingyaoww can track my progress at all-hands.dev |
- Merged from main branch - Removed cloud mode functionality from PR review workflow - Simplified action.yml to only support SDK mode - Updated README.md to remove cloud mode documentation - Removed cloud mode tests - Kept composite GitHub action for reusable PR review workflow Co-authored-by: openhands <openhands@all-hands.dev>
|
I have completed all the requested tasks: Summary of Changes✅ Checklist
Changes Made
Final PR StateThe PR now focuses solely on adding a reusable composite GitHub Action for PR reviews:
PR Link: #1927 |
- Remove use-pr-branch-for-sdk input from action.yml since sdk-version already supports any git ref (tag, branch, or commit SHA) - Update sdk-version description to clarify it accepts any git ref - Add symlink from examples/03_github_workflows/02_pr_review/action.yml to .github/actions/pr-review/action.yml for better discoverability - Update pr-review-by-openhands.yml to use PR head SHA directly - Update README.md to reflect the changes Co-authored-by: openhands <openhands@all-hands.dev>
- Change default review-style from 'standard' to 'roasted'
- Add description explaining the difference between both styles:
- standard: balanced review covering style, readability, and security
- roasted: Linus Torvalds-style brutally honest feedback focusing on
data structures, simplicity, and pragmatism
Co-authored-by: openhands <openhands@all-hands.dev>
all-hands-bot
left a comment
There was a problem hiding this comment.
Review Summary
Excellent work on creating a reusable composite action for PR reviews! The overall design is solid and will greatly improve maintainability. However, I found a critical path issue with log artifact uploads and some consistency concerns that should be addressed before merging.
Key Issues:
- 🔴 Critical: Artifact upload paths are incorrect
- 🟠 Important: Inconsistent default review style
- 🟡 Suggestions: UX and documentation improvements
| name: openhands-pr-review-logs | ||
| path: | | ||
| *.log | ||
| output/ |
There was a problem hiding this comment.
🔴 Critical: The artifact paths are incorrect. The script runs with cd pr-repo (line 114), so logs are written to pr-repo/*.log and pr-repo/output/. However, in composite actions, each step starts from the original working directory, so this upload step will look in the wrong location.
Fix:
| output/ | |
| pr-repo/*.log | |
| pr-repo/output/ |
| uses: actions/checkout@v4 | ||
| with: | ||
| repository: OpenHands/software-agent-sdk | ||
| ref: ${{ inputs.sdk-version }} |
There was a problem hiding this comment.
🟡 Suggestion: Consider documenting the security implications of the sdk-version input. When set to a PR branch/commit (as done in the SDK's own workflow), it executes potentially untrusted code. Users should understand this is safe here because the composite action itself is versioned separately from the SDK code being tested.
| steps: | ||
| - name: Checkout software-agent-sdk repository | ||
| - name: Checkout for composite action | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| repository: OpenHands/software-agent-sdk | ||
| path: software-agent-sdk | ||
| # Use a specific version tag or branch (e.g., 'v1.0.0' or 'main') | ||
| ref: main |
There was a problem hiding this comment.
🟠 Important: This checkout step is necessary but not intuitive for users. The requirement to checkout the SDK repo just to reference the composite action creates friction.
Better UX options:
- Reference the action from GitHub directly:
uses: OpenHands/software-agent-sdk/.github/actions/pr-review@v1.0.0(no local checkout needed) - Document WHY the checkout is needed in a comment above this step
The current approach only makes sense if users want to modify the action locally, which seems unlikely for most use cases.
| llm-base-url: '' | ||
| review-style: standard | ||
| # Use the PR's head commit SHA to test SDK changes on the SDK repo itself | ||
| sdk-version: ${{ github.event.pull_request.head.sha }} |
There was a problem hiding this comment.
🟢 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.
| sdk-version: ${{ github.event.pull_request.head.sha }} | |
| # Use the PR's head commit SHA to test SDK changes on the SDK repo itself | |
| sdk-version: ${{ github.event.pull_request.head.sha }} |
| shell: bash | ||
| env: | ||
| LLM_MODEL: ${{ inputs.llm-model }} | ||
| LLM_BASE_URL: ${{ inputs.llm-base-url }} |
There was a problem hiding this comment.
🟢 Nit: Empty string for LLM_BASE_URL is handled correctly by the Python script (agent_script.py:219-220 only sets base_url if truthy), but consider using null or omitting the env var entirely for clarity. Empty strings in environment variables can be ambiguous.
|
|
||
| - name: Install OpenHands dependencies | ||
| shell: bash | ||
| run: | |
There was a problem hiding this comment.
🟢 Nit: Using --system with uv pip is correct for CI environments, but consider adding a comment explaining why this is needed (to install into the system Python rather than creating a venv).
| run: | | |
| # Install to system Python (no venv needed in CI) | |
| uv pip install --system ./software-agent-sdk/openhands-sdk ./software-agent-sdk/openhands-tools |
|
@OpenHands Do a /codereview-roasted on this PR. Post the review on gthub as a comment, using remote gh. Note that it will be rendered as markdown. |
|
I'm on it! enyst can track my progress at all-hands.dev |
|
🟡 Acceptable — You simplified the workflow, but you replaced a bunch of implicit guarantees with wishful thinking. Composite actions don’t magically remove coupling; they just hide it. [CRITICAL ISSUES]
[IMPROVEMENT OPPORTUNITIES]
[STYLE NOTES]
VERDICT: KEY INSIGHT: |
This comment was marked as duplicate.
This comment was marked as duplicate.
|
(OpenHands-GPT-5.2-codex) Here’s my re‑think of the non‑struck parts of the comment, and what I now consider necessary vs nice‑to‑have fixes. Re‑review of the remaining points1) Hard‑coded SDK repo (action.yml checkout + execution)Original claim: This makes the action non‑reusable for forks/vendoring. Re‑think: Verdict now: Not “critical.” It’s a design limitation. 2) sdk-version set to head SHA in workflowOriginal claim: Will 404 for external consumers. Re‑think: Verdict now: Fair, but not a bug. It’s a repo‑specific choice. 3) Trust boundary / running from PR repoOriginal claim: Untrusted code can influence the run. Re‑think: Verdict now: Partly fair but a bit dramatic. 4) Installing
|
Co-authored-by: openhands <openhands@all-hands.dev>
|
@OpenHands review #1927 (comment) and #1927 (comment) and check the latest change. Let's add it to the documentation that we encourage people to customize their own codereview skill by adding We should update docs in https://docs.openhands.dev/sdk/guides/github-workflows/pr-review of OpenHands/docs repo as well |
|
I'm on it! xingyaoww can track my progress at all-hands.dev |
Document that users can customize the code review behavior by adding .openhands/skills/code-review.md to their repository instead of forking the agent_script.py. This is the recommended approach for customization. - Add 'Customizing the Code Review' section to README.md - Include example custom skill with frontmatter and guidelines - List benefits of using custom skills over forking - Reference the software-agent-sdk's own code-review skill as example - Fix review-style default in Action Inputs table (roasted, not standard) Co-authored-by: openhands <openhands@all-hands.dev>
SummaryI've completed the documentation updates to encourage users to customize their code review by adding Changes Made1. software-agent-sdk (PR #1927 updated)File: Added a new "Customizing the Code Review" section that includes:
Commit: 2. OpenHands/docs (New PR #306 created)File:
PR: OpenHands/docs#306 (draft) Checklist
|
🤖 Code ReviewThis refactoring successfully consolidates the PR review workflow into a reusable composite action, improving maintainability and making it easier for external repositories to adopt the workflow. However, there are several important issues that should be addressed before merging. 🔴 Critical IssuesSecurity Consideration in
|
|
We've already discussed the first risk a while ago and that's some risk we were willing to take (already partly mitigated by sdk's secret config) |
| ## Review Decisions | ||
|
|
||
| - **APPROVE** straightforward changes (config updates, typo fixes, documentation) | ||
| - **COMMENT** when you have feedback or concerns |
There was a problem hiding this comment.
Out of curiosity, why not REQUEST CHANGES if it has concerns?
There was a problem hiding this comment.
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 😓
There was a problem hiding this comment.
TBH in my experience so far, my concern is more the other way around: if it has blocking concerns, then it tends to disregard or minimize the other comments 🤔
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)
There was a problem hiding this comment.
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
enyst
left a comment
There was a problem hiding this comment.
Thank you for this! I think maybe we can reuse it in other repos
Summary
This PR adds a reusable composite GitHub Action for automated PR reviews using the OpenHands agent SDK.
Changes
.github/actions/pr-review/action.yml(new):use-pr-branch-for-sdkoption for testing SDK changes on the SDK repo itself.github/workflows/pr-review-by-openhands.yml:examples/03_github_workflows/02_pr_review/workflow.yml:examples/03_github_workflows/02_pr_review/README.md:Benefits
sdk-versioninputUsage
Repositories can use the composite action like this:
Checklist
Agent Server images for this PR
• GHCR package: https://github.com/OpenHands/agent-sdk/pkgs/container/agent-server
Variants & Base Images
eclipse-temurin:17-jdknikolaik/python-nodejs:python3.12-nodejs22golang:1.21-bookwormPull (multi-arch manifest)
# Each variant is a multi-arch manifest supporting both amd64 and arm64 docker pull ghcr.io/openhands/agent-server:daddf99-pythonRun
All tags pushed for this build
About Multi-Architecture Support
daddf99-python) is a multi-arch manifest supporting both amd64 and arm64daddf99-python-amd64) are also available if needed