fix: use GITHUB_SHA env var for image tag in server workflow - #2799
Conversation
For pull requests, github.sha is the merge commit SHA, not the PR head commit SHA. The workflow correctly sets GITHUB_SHA env var to the PR head SHA (line 214), but then used github.sha directly when computing the short SHA for image tags. This caused a mismatch where images were built with tags like `8ff5c53-python-amd64` (merge commit) while run-examples.yml tried to pull `f848121-python-amd64` (PR head commit). Fix by using the GITHUB_SHA env var instead of github.sha context. Co-authored-by: openhands <openhands@all-hands.dev>
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.
🟢 Good taste - Clean fix for a real problem.
VERDICT: ✅ Worth merging
KEY INSIGHT: This correctly uses the already-set GITHUB_SHA env var (which handles PR head SHA vs merge commit) instead of always using github.sha context, ensuring Docker images are tagged with the commit that consumers expect.
This review was created by an AI assistant (OpenHands) on behalf of the user.
🔄 Running Examples with
|
| Example | Status | Duration | Cost |
|---|---|---|---|
| 01_standalone_sdk/02_custom_tools.py | ✅ PASS | 27.6s | $0.03 |
| 01_standalone_sdk/03_activate_skill.py | ✅ PASS | 18.8s | $0.02 |
| 01_standalone_sdk/05_use_llm_registry.py | ✅ PASS | 12.1s | $0.01 |
| 01_standalone_sdk/07_mcp_integration.py | ✅ PASS | 29.8s | $0.02 |
| 01_standalone_sdk/09_pause_example.py | ✅ PASS | 12.0s | $0.01 |
| 01_standalone_sdk/10_persistence.py | ✅ PASS | 35.3s | $0.03 |
| 01_standalone_sdk/11_async.py | ✅ PASS | 30.2s | $0.04 |
| 01_standalone_sdk/12_custom_secrets.py | ✅ PASS | 10.1s | $0.01 |
| 01_standalone_sdk/13_get_llm_metrics.py | ✅ PASS | 39.0s | $0.03 |
| 01_standalone_sdk/14_context_condenser.py | ✅ PASS | 2m 13s | $0.16 |
| 01_standalone_sdk/17_image_input.py | ✅ PASS | 15.5s | $0.01 |
| 01_standalone_sdk/18_send_message_while_processing.py | ✅ PASS | 24.1s | $0.02 |
| 01_standalone_sdk/19_llm_routing.py | ✅ PASS | 13.8s | $0.02 |
| 01_standalone_sdk/20_stuck_detector.py | ✅ PASS | 16.0s | $0.02 |
| 01_standalone_sdk/21_generate_extraneous_conversation_costs.py | ✅ PASS | 8.8s | $0.00 |
| 01_standalone_sdk/22_anthropic_thinking.py | ✅ PASS | 15.3s | $0.01 |
| 01_standalone_sdk/23_responses_reasoning.py | ✅ PASS | 52.3s | $0.01 |
| 01_standalone_sdk/24_planning_agent_workflow.py | ✅ PASS | 3m 30s | $0.26 |
| 01_standalone_sdk/25_agent_delegation.py | ✅ PASS | 49.7s | $0.06 |
| 01_standalone_sdk/26_custom_visualizer.py | ✅ PASS | 23.5s | $0.03 |
| 01_standalone_sdk/28_ask_agent_example.py | ✅ PASS | 37.9s | $0.05 |
| 01_standalone_sdk/29_llm_streaming.py | ✅ PASS | 37.7s | $0.03 |
| 01_standalone_sdk/30_tom_agent.py | ✅ PASS | 9.5s | $0.01 |
| 01_standalone_sdk/31_iterative_refinement.py | ✅ PASS | 9m 34s | $0.73 |
| 01_standalone_sdk/32_configurable_security_policy.py | ✅ PASS | 17.5s | $0.02 |
| 01_standalone_sdk/34_critic_example.py | ✅ PASS | 6m 10s | $0.53 |
| 01_standalone_sdk/36_event_json_to_openai_messages.py | ✅ PASS | 9.6s | $0.01 |
| 01_standalone_sdk/37_llm_profile_store/main.py | ✅ PASS | 3.8s | $0.00 |
| 01_standalone_sdk/38_browser_session_recording.py | ✅ PASS | 33.0s | $0.03 |
| 01_standalone_sdk/39_llm_fallback.py | ✅ PASS | 9.7s | $0.01 |
| 01_standalone_sdk/40_acp_agent_example.py | ✅ PASS | 27.6s | $0.04 |
| 01_standalone_sdk/41_task_tool_set.py | ✅ PASS | 26.5s | $0.03 |
| 01_standalone_sdk/42_file_based_subagents.py | ✅ PASS | 57.8s | $0.06 |
| 01_standalone_sdk/43_mixed_marketplace_skills/main.py | ✅ PASS | 3.2s | $0.00 |
| 01_standalone_sdk/44_model_switching_in_convo.py | ✅ PASS | 7.5s | $0.01 |
| 01_standalone_sdk/45_parallel_tool_execution.py | ✅ PASS | 3m 28s | $0.47 |
| 01_standalone_sdk/46_agent_settings.py | ✅ PASS | 11.6s | $0.01 |
| 01_standalone_sdk/47_defense_in_depth_security.py | ✅ PASS | 3.2s | $0.00 |
| 02_remote_agent_server/01_convo_with_local_agent_server.py | ✅ PASS | 38.0s | $0.03 |
| 02_remote_agent_server/02_convo_with_docker_sandboxed_server.py | ✅ PASS | 1m 46s | $0.07 |
| 02_remote_agent_server/03_browser_use_with_docker_sandboxed_server.py | ✅ PASS | 1m 2s | $0.07 |
| 02_remote_agent_server/04_convo_with_api_sandboxed_server.py | ✅ PASS | 2m 1s | $0.10 |
| 02_remote_agent_server/07_convo_with_cloud_workspace.py | ✅ PASS | 37.7s | $0.03 |
| 02_remote_agent_server/08_convo_with_apptainer_sandboxed_server.py | ✅ PASS | 3m 11s | $0.03 |
| 02_remote_agent_server/09_acp_agent_with_remote_runtime.py | ✅ PASS | 1m 15s | $0.12 |
| 02_remote_agent_server/10_cloud_workspace_share_credentials.py | ✅ PASS | 31.2s | $0.05 |
| 04_llm_specific_tools/01_gpt5_apply_patch_preset.py | ✅ PASS | 21.2s | $0.02 |
| 04_llm_specific_tools/02_gemini_file_tools.py | ✅ PASS | 46.5s | $0.07 |
| 05_skills_and_plugins/01_loading_agentskills/main.py | ✅ PASS | 12.4s | $0.01 |
| 05_skills_and_plugins/02_loading_plugins/main.py | ✅ PASS | 20.5s | $0.03 |
✅ All tests passed!
Total: 50 | Passed: 50 | Failed: 0 | Total Cost: $3.47
all-hands-bot
left a comment
There was a problem hiding this comment.
QA Report: FAIL ❌
Summary
The fix in this PR does not solve the stated problem. Docker images are still being tagged with the merge commit SHA (f30ba37) instead of the PR head SHA (834779c).
Environment Setup
✅ Repository cloned and dependencies installed successfully
$ cd /home/runner/work/software-agent-sdk/software-agent-sdk/pr-repo
$ uv sync --frozen
# Completed successfullyCI & Test Status
✅ All CI checks passing for commit 834779c
- Agent Server workflow: SUCCESS (run 24248418358)
- All 9 build jobs completed successfully
Functional Verification
❌ Docker Image Tags - FAILED
Expected behavior (from PR description):
Docker images should be tagged with PR head SHA (
834779c) instead of merge commit SHA
Actual behavior (from CI logs):
Tags: ghcr.io/openhands/agent-server:f30ba37-java-amd64,ghcr.io/openhands/agent-server:f30ba37-eclipse-temurin_tag_17-jdk-amd64
Short SHA: f30ba37
Verification steps:
- Examined workflow run 24248418358 logs
- Confirmed GITHUB_SHA env var is set correctly:
834779c90599f448cf5795e444448651c92afe6a - Checked actual image tags produced: All use
f30ba37(merge commit SHA) - Tested
build.pylocally - confirmed it correctly reads GITHUB_SHA when set
Evidence from CI logs:
Build & Push (java-amd64) Checkout 2026-04-10T14:39:32.5Z GITHUB_SHA: 834779c90599f448cf5795e444448651c92afe6a
Build & Push (java-amd64) Checkout 2026-04-10T14:39:33.7Z HEAD is now at f30ba37 Merge 834779c...
Build & Push (java-amd64) Prepare build context 2026-04-10T14:39:56.9Z Tags: ghcr.io/openhands/agent-server:f30ba37-java-amd64
Build & Push (java-amd64) Prepare build context 2026-04-10T14:39:56.9Z Short SHA: f30ba37
Root Cause Analysis
The PR changes line 257-258 to calculate the workflow's SHORT_SHA output using $GITHUB_SHA instead of ${{ github.sha }}. However:
- The workflow's SHORT_SHA output is NOT used for Docker image tags
- Docker image tags are generated by
build.pyvia_git_info() _git_info()should read theGITHUB_SHAenv var (line 301 of build.py)- In CI,
build.pyis falling back togit rev-parse HEADwhich returns the merge commit SHA - This suggests GITHUB_SHA is not being propagated correctly to
build.pyin the CI environment
Issues Found
🔴 Critical: Fix Does Not Work
The stated goal is:
"Fix a bug in the Agent Server build workflow where PR Docker images are tagged with the merge commit SHA instead of the PR head commit SHA."
But after applying this fix, images are still tagged with the merge commit SHA.
Recommended solution:
The workflow needs to either:
- Set
SDK_SHAenv var (which has higher priority in build.py) - Pass the SHA explicitly to build.py as a CLI argument
- Investigate why GITHUB_SHA isn't being read by build.py in CI
Verdict
❌ FAIL - The change does not solve the stated problem. Docker images are still tagged with the merge commit SHA instead of the PR head SHA, which means the underlying issue persists.
Co-authored-by: openhands <openhands@all-hands.dev>
The checkout action overwrites the GITHUB_SHA env var to be the merge commit SHA. Using SDK_SHA instead, which build.py already checks first in its priority order. Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: openhands <openhands@all-hands.dev>
Fix Verified ✅I found the actual root cause and fixed it. The ProblemSetting
This is why the debug output showed: The SolutionUse git_sha = os.environ.get("SDK_SHA") or os.environ.get("GITHUB_SHA")VerificationThe latest CI run (ID 24250020814) shows the fix working: The images are now tagged with the PR head commit SHA ( This comment was created by an AI assistant (OpenHands) on behalf of the user. |
…ds#2799) Co-authored-by: openhands <openhands@all-hands.dev>
…ds#2799) Co-authored-by: openhands <openhands@all-hands.dev>
Summary
Fix a bug in the Agent Server build workflow where PR Docker images are tagged with the merge commit SHA instead of the PR head commit SHA.
Problem
The
server.ymlworkflow was setting:However,
GITHUB_SHAis a built-in GitHub Actions environment variable that gets overwritten by the checkout action to be the merge commit SHA.Evidence from CI logs
This caused images to be built with the merge commit SHA while
run-examples.ymlexpected the PR head commit SHA.Fix
Use
SDK_SHAinstead ofGITHUB_SHA. Thebuild.pyscript already checksSDK_SHAfirst in its priority order (see_git_info()):So by setting
SDK_SHAto the PR head SHA,build.pywill use it correctly without being affected by the checkout action overwritingGITHUB_SHA.Impact
This fixes the Docker-related example test failures that were seen in PR #2765 and likely other PRs.
Test plan
SDK_SHAis used correctlytest-examplesworkflow to verify the fixThis PR was created by an AI assistant (OpenHands) on behalf of the user.
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:6f96e03-pythonRun
All tags pushed for this build
About Multi-Architecture Support
6f96e03-python) is a multi-arch manifest supporting both amd64 and arm646f96e03-python-amd64) are also available if needed