Repository: All-Hands-AI/OpenHands
Pull request: feat(resolver): Support for User-Defined Runners
- [x] This change is worth documenting at https://docs.all-hands.dev/
- [x] Include this change in the Release Notes. If checked, you **must** provide an **end-user friendly** description for your change below

**End-user friendly description of the problem this fixes or functionality that this introduces.**

It enables User-Defined Runners in [resolver workflow](.github/workflows/openhands-resolver.yml). It allows users to run the resolver on their own self-hosted runners instead of being locked to ubuntu-latest. This is especially helpful in setups where runners are preconfigured with access to private container registries or other infrastructure-specific resources.

---

**Give a summary of what the PR does, explaining any non-trivial design decisions.**

- Creates a new input in resolver workflow for user to specify the runner.
- Updated docs to reflect the changes and instruct users on how to use it.

---

**Link of any specific issues this addresses.**

Closes: https://github.com/All-Hands-AI/OpenHands/issues/8215

Problem statement:
Enhance Workflow Flexibility with Support for User-Defined Runners
**What problem or use case are you trying to solve?**

Right now, the OpenHands resolver workflow have the runs-on locked to ubuntu-latest.

In my setup, for example, I’m running gh runners inside a Kubernetes cluster. These runners are already configured with access to private container registries and the necessary secrets to pull customized runtime images. That setup just works but only if the workflow actually runs on those runners.

Since the OpenHands workflow doesn’t let you set the runs-on, there’s no way to point it to your own runners. So if you need to use pre-configured ones (like I do), your only option is to fork the whole workflow or hack around it (which kinda defeats the whole point of reusing it cleanly)

Adding a runner input fixes this by letting you tell the workflow which runner to use. 


### If you find this feature request or enhancement useful, make sure to add a 👍 to the issue

Hints from issue discussion:

Commit message: Merge branch 'main' into feat/config-resolver-runners

Patch to review:
diff --git a/.github/workflows/openhands-resolver.yml b/.github/workflows/openhands-resolver.yml
index 0b89031fcb4f..f34e49bc6d3e 100644
--- a/.github/workflows/openhands-resolver.yml
+++ b/.github/workflows/openhands-resolver.yml
@@ -34,6 +34,10 @@ on:
         type: string
         default: ""
         description: "Custom sandbox env"
+      runner:
+        required: false
+        type: string
+        default: "ubuntu-latest"
     secrets:
       LLM_MODEL:
         required: false
@@ -79,7 +83,7 @@ jobs:
         (github.event.review.author_association == 'OWNER' || github.event.review.author_association == 'COLLABORATOR' || github.event.review.author_association == 'MEMBER')
         )
       )
-    runs-on: ubuntu-latest
+    runs-on: "${{ inputs.runner }}"
     steps:
       - name: Checkout repository
         uses: actions/checkout@v4
diff --git a/openhands/resolver/README.md b/openhands/resolver/README.md
index 6a2c6afb7523..edf707707349 100644
--- a/openhands/resolver/README.md
+++ b/openhands/resolver/README.md
@@ -37,6 +37,7 @@ Follow these steps to use this workflow in your own repository:
      - `PAT_USERNAME`: GitHub username for the personal access token
      - `PAT_TOKEN`: The personal access token
      - `LLM_BASE_URL`: Base URL for LLM API (only if using a proxy)
+     - `TARGET_RUNNER`: Target runner to execute the agent workflow (default ubuntu-latest)
 
    Note: You can set these secrets at the organization level to use across multiple repositories.
 
diff --git a/openhands/resolver/examples/openhands-resolver.yml b/openhands/resolver/examples/openhands-resolver.yml
index c76e197d36d7..9775f9dc5947 100644
--- a/openhands/resolver/examples/openhands-resolver.yml
+++ b/openhands/resolver/examples/openhands-resolver.yml
@@ -26,6 +26,7 @@ jobs:
       base_container_image: ${{ vars.OPENHANDS_BASE_CONTAINER_IMAGE || '' }}
       LLM_MODEL: ${{ vars.LLM_MODEL || 'anthropic/claude-3-5-sonnet-20241022' }}
       target_branch: ${{ vars.TARGET_BRANCH || 'main' }}
+      runner: ${{ vars.TARGET_RUNNER || '' }}
     secrets:
       PAT_TOKEN: ${{ secrets.PAT_TOKEN }}
       PAT_USERNAME: ${{ secrets.PAT_USERNAME }}


Code review comments:
diff_hunk: @@ -26,6 +26,7 @@ jobs:
       base_container_image: ${{ vars.OPENHANDS_BASE_CONTAINER_IMAGE || '' }}
       LLM_MODEL: ${{ vars.LLM_MODEL || 'anthropic/claude-3-5-sonnet-20241022' }}
       target_branch: ${{ vars.TARGET_BRANCH || 'main' }}
+      runner: ${{ vars.TARGET_RUNNER || '' }}
path: openhands/resolver/examples/openhands-resolver.yml
text: @user1:
```suggestion
      runner: ${{ vars.TARGET_RUNNER }}
```

Will specifying a default here override the default `ubuntu-latest` in the workflow definition? 

@author:
No, it doesnt ... already tested, but I will accept your suggestion.

diff_hunk: @@ -37,6 +37,7 @@ Follow these steps to use this workflow in your own repository:
      - `PAT_USERNAME`: GitHub username for the personal access token
      - `PAT_TOKEN`: The personal access token
      - `LLM_BASE_URL`: Base URL for LLM API (only if using a proxy)
+     - `TARGET_RUNNER`: Target runner to execute the agent workflow (default ubuntu-latest)
path: openhands/resolver/README.md
text: @user1:
```suggestion
```

Actually would you mind moving this to `docs/modules/usage/how-to/github-action.md`?

@author:
Sure