Repository navigation
ci(version-bump-prs): also bump agent-server pin in typescript-client - #3864
Conversation
Add an independent bump-typescript-client job to the release version-bump workflow. On each SDK release (dispatched by pypi-release.yml after publish), it waits for ghcr.io/openhands/agent-server:<version>-python to be published, then opens a bump-agent-server-<version> PR in OpenHands/typescript-client updating the pinned agent-server image (package.json config.agentServerImage plus the integration-tests.yml, AGENTS.md, and README.md mirrors). The PR's CI + integration tests run against the new image, validating the client against the new server before merge. The job runs in parallel and does not affect the existing OpenHands / openhands-cli package bumps. This does not release the npm package.
Python API breakage checks — ✅ PASSEDResult: ✅ PASSED |
REST API breakage checks (OpenAPI) — ✅ PASSEDResult: ✅ PASSED |
all-hands-bot
left a comment
There was a problem hiding this comment.
🟡 QA Report: PARTIAL
The new workflow job was exercised against the real OpenHands/typescript-client repo and produced the expected branch, commit, version updates, PR body, and PR-create invocation; only the final external push/PR creation was safely stubbed.
Does this PR achieve its stated goal?
Yes, based on the executable workflow path I could safely verify. The PR adds the bump-typescript-client job, waits successfully for a real ghcr.io/openhands/agent-server:1.29.2-python image, and the job logic updated the TypeScript client from 1.29.0 to 1.29.2 across the intended four files / seven references before invoking the expected push and PR creation commands. I did not perform the actual cross-repo push or create a real TypeScript-client PR to avoid external side effects.
| Phase | Result |
|---|---|
| Environment Setup | ✅ Disposable QA workspace created; git, gh, and docker were available |
| CI Status | |
| Functional Verification | ✅ Workflow shell path works through commit + PR-create invocation; external write side effects stubbed |
Functional Verification
Test 1: Baseline workflow vs PR workflow job list
Step 1 — Establish baseline without the PR:
Ran ruby -e 'require "yaml"; ...' against origin/main:
origin/main: create-version-bump-prs
This shows the release bump workflow previously only had the existing package bump job and did not include a TypeScript-client bump path.
Step 2 — Apply the PR's changes:
Checked the PR head origin/ci/bump-typescript-client-on-release.
Step 3 — Re-run with the PR in place:
Ran the same YAML parse against the PR head:
origin/ci/bump-typescript-client-on-release: create-version-bump-prs, bump-typescript-client
This shows the PR adds the independent bump-typescript-client job the author described.
Test 2: GHCR image wait condition with a real published release image
Step 1 — Establish the release-image condition:
Used a real current release version (1.29.2) and ran the same core operation as the workflow wait loop:
Checking ghcr.io/openhands/agent-server:1.29.2-python
mediaType= application/vnd.oci.image.index.v1+json
manifests= 4
linux amd64
unknown unknown
linux arm64
unknown unknown
This confirms the workflow's docker manifest inspect condition succeeds for a published SDK/agent-server release image.
Step 2 — Apply the PR's changes:
Executed the new job's workflow shell path locally with VERSION=1.29.2.
Step 3 — Re-run with the fix in place:
The workflow path proceeded past image availability into the TypeScript-client bump step, which means the wait condition did not block once the image was present.
Test 3: End-to-end TypeScript-client bump behavior
Step 1 — Establish baseline without the bump:
Cloned the real OpenHands/typescript-client repository from GitHub. The workflow-derived command detected:
CURRENT=1.29.0
This shows the client was not already pinned to the target release version.
Step 2 — Apply the PR's changes:
Ran the new Open bump PR in typescript-client step body against that real clone with VERSION=1.29.2. To avoid modifying another repository, only git push and gh pr create/list were stubbed; clone, branch creation, sed updates, git add, and git commit were real local operations.
Step 3 — Re-run with the fix in place:
Observed the job create the expected branch and commit, then reach the expected external write commands:
Switched to a new branch 'bump-agent-server-1.29.2'
CURRENT=1.29.0
[bump-agent-server-1.29.2 adf510a] Bump agent-server (software-agent-sdk) to v1.29.2
4 files changed, 7 insertions(+), 7 deletions(-)
[QA stub] git push push -u origin bump-agent-server-1.29.2
[QA stub] gh pr create pr create --repo OpenHands/typescript-client --base main --head bump-agent-server-1.29.2 --title Bump agent-server (software-agent-sdk) to v1.29.2 --body-file pr_body.md
✅ PR created for OpenHands/typescript-client
The changed references after execution were:
package.json:45: "agentServerImage": "ghcr.io/openhands/agent-server:1.29.2-python"
.github/workflows/integration-tests.yml:19: AGENT_SERVER_IMAGE: ghcr.io/openhands/agent-server:1.29.2-python
AGENTS.md:307:# Start agent-server in Docker (software-agent-sdk v1.29.2)
AGENTS.md:310: ghcr.io/openhands/agent-server:1.29.2-python
AGENTS.md:339:- The integration workflow pins `ghcr.io/openhands/agent-server:1.29.2-python`, which corresponds to the `software-agent-sdk` release `v1.29.2`.
README.md:379:2. Start the agent-server container (software-agent-sdk v1.29.2):
README.md:386: ghcr.io/openhands/agent-server:1.29.2-python
This confirms the job updates all intended mirrors and prepares the expected bump PR content.
Test 4: Version validation and summary behavior
Step 1 — Establish valid input behavior:
Ran the Get version step logic with VERSION_INPUT=1.29.2:
📦 Version: 1.29.2
version=1.29.2
This confirms valid workflow input is accepted and exported.
Step 2 — Exercise invalid input:
Ran the same logic with VERSION_INPUT=v1.29.2:
invalid status=1
❌ Invalid version format. Expected: X.Y.Z (e.g., 1.30.0)
This confirms the job fails fast before attempting cross-repo writes when the dispatched version includes the unsupported v prefix.
Step 3 — Exercise summary output:
Ran the summary step with VERSION=1.29.2:
## ✅ typescript-client agent-server bump
Bumped the tracked agent-server image to **v1.29.2**:
- [typescript-client](https://github.com/OpenHands/typescript-client/pulls?q=is%3Apr+bump-agent-server-1.29.2)
This confirms the workflow summary points reviewers to the expected TypeScript-client bump PR search.
Unable to Verify
I did not let the job push bump-agent-server-1.29.2 to OpenHands/typescript-client or create a real PR there, because that would mutate an external repository during QA. The local execution reached the exact git push and gh pr create invocations with the expected branch, title, repo, base, and generated body.
Issues Found
None.
This QA review was created by an AI agent (OpenHands) on behalf of the user.
|
✅ Review complete. This review was performed through OpenHands Cloud Automation. You can log in and view the conversation here. |
all-hands-bot
left a comment
There was a problem hiding this comment.
Summary
The new bump-typescript-client job cleanly mirrors the existing create-version-bump-prs pattern to keep the typescript-client agent-server pin in sync on each SDK release. It is appropriately scoped (independent job, reuses OPENHANDS_BOT_GITHUB_PAT_PUBLIC, handles re-runs and no-ops), and the QA report confirms the sed pipeline produces the intended 7 edits across the 4 target files on a real typescript-client clone.
I left one inline suggestion about a fragile sed pattern, but nothing blocking — this is ready to merge.
[RISK ASSESSMENT]
- [Overall PR]
⚠️ Risk Assessment: 🟡 MEDIUM
This PR adds cross-repo CI automation that runs on every SDK release and writes to a downstream consumer (OpenHands/typescript-client). If any of the threesedpatterns misfire, the resulting bump PR could contain incorrect edits. The patterns are simple, currently verified against the real repo (QA: 7/7 intended edits, 0 spurious), and confined to four well-known files, so the likelihood of a bad push is low — but the blast radius touches another repo's history and CI, which is why this isn't 🟢 LOW.
VERDICT:
✅ Worth merging: Core logic is sound, the cross-repo write path is validated end-to-end, and the one fragility is worth tightening in a follow-up rather than blocking.
KEY INSIGHT:
The third sed pattern matches any backticked vX.Y.Z in markdown — fine for the current typescript-client docs, but it will silently rewrite unrelated backticked versions if those docs ever grow to mention them.
This review was generated by an AI agent (OpenHands) on behalf of the user through OpenHands Automation. View conversation
Improve this review? If any feedback above seems incorrect or irrelevant to this repository, you can teach the reviewer to do better:
- Add a
.agents/skills/custom-codereview-guide.mdfile to your branch (or edit it if one already exists) with the/codereviewtrigger and the context the reviewer is missing (e.g., "Security concerns about X do not apply here because Y"). See the customization docs for the required frontmatter format.- Re-request a review - the reviewer reads guidelines from the PR branch, so your changes take effect immediately.
- When your PR is merged, the guideline file goes through normal code review by repository maintainers.
Resolve with AI? Install the iterate skill in your agent and run
/iterateto automatically drive this PR through CI, review, and QA until it's merge-ready.Was this review helpful? React with 👍 or 👎 to give feedback.
| sed -i \ | ||
| -e "s#agent-server:${CURRENT}-python#agent-server:${VERSION}-python#g" \ | ||
| -e "s#software-agent-sdk v${CURRENT}#software-agent-sdk v${VERSION}#g" \ | ||
| -e "s#\`v${CURRENT}\`#\`v${VERSION}\`#g" \ |
There was a problem hiding this comment.
🟡 Suggestion: This sed matches any backticked vX.Y.Z in markdown, not just SDK-release references. Today the only match is the intended release \v1.29.0`inAGENTS.md` line 339, so it's correct — but if typescript-client ever adds a backticked version for an unrelated tool (peer dependency, upstream lib, etc.), this will silently rewrite it.
Tightening the pattern to require nearby context — e.g. release \v${CURRENT}`orsoftware-agent-sdk `v${CURRENT}`— would keep the bump self-contained and avoid future surprise edits. Thesoftware-agent-sdk v${CURRENT}line above already requires the un-backticked form, so a parallel`v${CURRENT}`after the wordreleasewould cover the only known match without becoming a global find-and-replace onvX.Y.Z`.
all-hands-bot
left a comment
There was a problem hiding this comment.
🟡 QA Report: PARTIAL
The added workflow job executed correctly in a safe local harness: it validates release versions, waits for a real GHCR agent-server image, no-ops when typescript-client is already pinned, and produces/pushes the expected bump branch plus gh pr create invocation when starting from an older pin.
Does this PR achieve its stated goal?
Yes, based on the behavior I could safely exercise. The PR's goal is to add release automation that keeps OpenHands/typescript-client's pinned agent-server image in sync; executing the exact new workflow steps against real ghcr.io/openhands/agent-server:1.29.0-python and a real OpenHands/typescript-client clone updated an older local pin from 1.28.0 to 1.29.0 across the expected files, committed, pushed a bump-agent-server-1.29.0 branch, and invoked gh pr create with the expected repo/base/head/title/body. I did not create an actual remote PR in OpenHands/typescript-client to avoid external side effects during QA, so the final GitHub-side PR creation remains intentionally sandboxed.
| Phase | Result |
|---|---|
| Environment Setup | ✅ Docker, gh, git available; real GHCR image reachable; target repo cloned |
| CI Status | ✅ PR checks are green except this qa-changes job was still in progress while running |
| Functional Verification | 🟡 Workflow behavior verified locally; actual external PR creation intentionally not performed |
Functional Verification
Test 1: Base workflow lacks the typescript-client bump job; PR adds it
Step 1 — Establish baseline (without the fix):
Ran python3 -c '... yaml.safe_load(git show origin/main:.github/workflows/version-bump-prs.yml) ...':
base_jobs=create-version-bump-prs
This shows the base workflow has no entry point that can bump OpenHands/typescript-client.
Step 2 — Apply the PR's changes:
Used the checked-out PR commit 6f89b6542cef4a869de2db8154156705048fca59.
Step 3 — Re-run with the fix in place:
Ran the same YAML job extraction against the PR checkout:
pr_jobs=create-version-bump-prs,bump-typescript-client
This shows the PR adds the independent bump-typescript-client workflow job it set out to add.
Test 2: Version validation and real GHCR image wait
Step 1 — Establish baseline / inputs:
Ran the exact new Get version workflow step with valid and invalid dispatch-style inputs:
VERSION_INPUT=1.29.0 rc=0
📦 Version: 1.29.0
version=1.29.0
VERSION_INPUT=v1.29.0 rc=1
❌ Invalid version format. Expected: X.Y.Z (e.g., 1.30.0)
This shows the job accepts the documented X.Y.Z input and rejects a tag-like vX.Y.Z value.
Step 2 — Apply the PR's changes:
Used the exact new Wait for agent-server image in GHCR workflow step from the PR.
Step 3 — Run with a real release image:
Ran VERSION=1.29.0 bash /tmp/qa-pr-3864/wait_image_step.sh:
rc=0
⏳ Waiting for ghcr.io/openhands/agent-server:1.29.0-python to be published...
✅ ghcr.io/openhands/agent-server:1.29.0-python is published
This confirms the workflow can find the real release image before attempting the downstream bump.
Test 3: typescript-client no-op and bump behavior
Step 1 — Establish current-state no-op behavior:
Cloned real OpenHands/typescript-client, which is currently pinned to 1.29.0, then ran the exact new Open bump PR in typescript-client step through a local git origin rewrite:
rc=0
Cloning into 'ts-client'...
Switched to a new branch 'bump-agent-server-1.29.0'
✅ typescript-client already pinned to 1.29.0 — nothing to do
gh_calls=none
This shows the automation exits cleanly and does not call gh when the target repo is already synchronized.
Step 2 — Apply the PR's changes to an older pinned state:
Seeded a local bare origin from the real typescript-client repo with the four target files pinned to 1.28.0, then ran the exact workflow step with VERSION=1.29.0. Only the network-mutating gh pr create/list calls were stubbed; git clone/branch/commit/push ran for real against the local origin.
Step 3 — Re-run with the fix in place:
Ran VERSION=1.29.0 bash /tmp/qa-pr-3864/open_bump_pr_step.sh:
rc=0
Cloning into 'ts-client'...
Switched to a new branch 'bump-agent-server-1.29.0'
[bump-agent-server-1.29.0 c6fe82a] Bump agent-server (software-agent-sdk) to v1.29.0
4 files changed, 7 insertions(+), 7 deletions(-)
To file:///tmp/qa-pr-3864/origin-update.git
* [new branch] bump-agent-server-1.29.0 -> bump-agent-server-1.29.0
branch 'bump-agent-server-1.29.0' set up to track 'origin/bump-agent-server-1.29.0'.
https://github.com/OpenHands/typescript-client/pull/QA-STUB
✅ PR created for OpenHands/typescript-client
The captured gh invocation was:
gh pr list --repo OpenHands/typescript-client --head bump-agent-server-1.29.0 --json number --jq .[0].number
gh pr create --repo OpenHands/typescript-client --base main --head bump-agent-server-1.29.0 --title Bump agent-server (software-agent-sdk) to v1.29.0 --body-file pr_body.md
This shows the workflow reaches the intended PR creation path with the expected repo, branch, title, and generated body.
Step 4 — Verify before/after file effects:
Ran occurrence counts across package.json, .github/workflows/integration-tests.yml, AGENTS.md, and README.md before and after the workflow branch:
before seeded main:
agent-server:1.28.0-python=5
agent-server:1.29.0-python=0
software-agent-sdk v1.28.0=2
software-agent-sdk v1.29.0=0
`v1.28.0`=1
`v1.29.0`=0
after workflow branch:
agent-server:1.28.0-python=0
agent-server:1.29.0-python=5
software-agent-sdk v1.28.0=0
software-agent-sdk v1.29.0=2
`v1.28.0`=0
`v1.29.0`=1
This confirms the generated bump branch replaces the old SDK/agent-server pin with the target release across the mirrored files.
Unable to Verify
I intentionally did not let the workflow create a real PR in OpenHands/typescript-client, because that would mutate another repository during QA and could create duplicate/noisy release-bump PRs. Instead, I verified the exact gh pr create command invocation after a real local git commit and push to a local bare origin. Future QA guidance in AGENTS.md could specify whether release-automation QA agents are allowed to create and close real cross-repo PRs for end-to-end validation.
Issues Found
None.
This review was created by an AI agent (OpenHands) on behalf of the user.
Verdict: PARTIAL
HUMAN:
Adds the typescript-client agent-server bump to our release automation so the TS client stays in sync on each SDK release. Reviewed the workflow and validated it locally.
AGENT:
Why
OpenHands/typescript-clientis tested and documented against a specific agent-server image whose tag (<version>-python) corresponds 1:1 to asoftware-agent-sdkrelease (vX.Y.Z). Nothing kept that pin in sync, so it drifted behind SDK releases and had to be bumped by hand. This wires the bump into the SDK's existing release automation — symmetric with the OpenHands / openhands-cli bumps already done in this workflow.Summary
bump-typescript-clientjob toversion-bump-prs.yml(dispatched bypypi-release.ymlafter each publish).ghcr.io/openhands/agent-server:<version>-pythonin GHCR, then opens abump-agent-server-<version>PR inOpenHands/typescript-clientupdatingpackage.jsonconfig.agentServerImageplus theintegration-tests.yml,AGENTS.md, andREADME.mdmirrors.needs:) so it cannot affect the existing OpenHands / openhands-cli bump PRs, and it does not publish the npm package.How to Test
Manual end-to-end dry run (no real release needed):
workflow_dispatch) withversionset to an already-released SDK version whoseagent-server:<version>-pythonimage exists in GHCR (e.g.1.29.0).bump-typescript-clientjob finds the image, opens abump-agent-server-1.29.0PR in typescript-client (or no-ops if already pinned), and that PR's CI + integration tests run against the new image.Static validation already done: the workflow parses as valid YAML, the generated PR body renders cleanly, and the version
sedwas dry-run against the real typescript-client files (updates all 7 occurrences, nothing spurious). Automatic firing is exercised on the next SDK release.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.13-nodejs22-slimgolang: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:6f89b65-pythonRun
All tags pushed for this build
About Multi-Architecture Support
6f89b65-python) is a multi-arch manifest supporting both amd64 and arm646f89b65-python-amd64) are also available if needed