Skip to content

Comments

ci: require deprecation marker before exported symbol removal#2072

Merged
enyst merged 1 commit intomainfrom
ci/require-deprecation-before-removal
Feb 14, 2026
Merged

ci: require deprecation marker before exported symbol removal#2072
enyst merged 1 commit intomainfrom
ci/require-deprecation-before-removal

Conversation

@enyst
Copy link
Collaborator

@enyst enyst commented Feb 14, 2026

Summary

Enforces that any symbol removed from openhands.sdk.__all__ must have been marked deprecated in the previous release using the SDK's canonical deprecation helpers (@deprecated decorator or warn_deprecated() from openhands.sdk.utils.deprecation).

Closes #2066

What changed

.github/scripts/check_sdk_api_breakage.py:

  • _find_deprecated_symbols() — AST-scans the previous release's source for @deprecated decorators and warn_deprecated() calls, building a set of deprecated top-level names
  • _get_source_root() — Derives source directory from griffe's PyPI download cache
  • _compute_breakages() — Now returns (total_breaks, undeprecated_removals): removals without prior deprecation are a hard failure independent of version bumps

Two independent policies

Policy Gate
Deprecation-before-removal Symbol must have @deprecated or warn_deprecated() in old release
MINOR version bump All structural breaks require ≥ MINOR bump

Design decision

Uses the existing openhands.sdk.utils.deprecation module — no new deprecation mechanism needed. The same markers already enforced by check_deprecations.py (deadline scanner) are now also required before any __all__ removal.

Tests

6 new tests (15 total, all passing):

  • @deprecated decorator detection
  • warn_deprecated('Foo.bar') → top-level Foo mapping
  • Syntax error tolerance
  • Integration tests with griffe

Agent Server images for this PR

GHCR package: https://github.com/OpenHands/agent-sdk/pkgs/container/agent-server

Variants & Base Images

Variant Architectures Base Image Docs / Tags
java amd64, arm64 eclipse-temurin:17-jdk Link
python amd64, arm64 nikolaik/python-nodejs:python3.12-nodejs22 Link
golang amd64, arm64 golang:1.21-bookworm Link

Pull (multi-arch manifest)

# Each variant is a multi-arch manifest supporting both amd64 and arm64
docker pull ghcr.io/openhands/agent-server:6edd533-python

Run

docker run -it --rm \
  -p 8000:8000 \
  --name agent-server-6edd533-python \
  ghcr.io/openhands/agent-server:6edd533-python

All tags pushed for this build

ghcr.io/openhands/agent-server:6edd533-golang-amd64
ghcr.io/openhands/agent-server:6edd533-golang_tag_1.21-bookworm-amd64
ghcr.io/openhands/agent-server:6edd533-golang-arm64
ghcr.io/openhands/agent-server:6edd533-golang_tag_1.21-bookworm-arm64
ghcr.io/openhands/agent-server:6edd533-java-amd64
ghcr.io/openhands/agent-server:6edd533-eclipse-temurin_tag_17-jdk-amd64
ghcr.io/openhands/agent-server:6edd533-java-arm64
ghcr.io/openhands/agent-server:6edd533-eclipse-temurin_tag_17-jdk-arm64
ghcr.io/openhands/agent-server:6edd533-python-amd64
ghcr.io/openhands/agent-server:6edd533-nikolaik_s_python-nodejs_tag_python3.12-nodejs22-amd64
ghcr.io/openhands/agent-server:6edd533-python-arm64
ghcr.io/openhands/agent-server:6edd533-nikolaik_s_python-nodejs_tag_python3.12-nodejs22-arm64
ghcr.io/openhands/agent-server:6edd533-golang
ghcr.io/openhands/agent-server:6edd533-java
ghcr.io/openhands/agent-server:6edd533-python

About Multi-Architecture Support

  • Each variant tag (e.g., 6edd533-python) is a multi-arch manifest supporting both amd64 and arm64
  • Docker automatically pulls the correct architecture for your platform
  • Individual architecture tags (e.g., 6edd533-python-amd64) are also available if needed

@enyst enyst force-pushed the ci/require-deprecation-before-removal branch 3 times, most recently from d727b3d to 067ecf2 Compare February 14, 2026 05:13
@enyst enyst marked this pull request as ready for review February 14, 2026 05:14
@enyst enyst force-pushed the ci/require-deprecation-before-removal branch from 067ecf2 to 2d69bdc Compare February 14, 2026 05:16
Copy link
Collaborator

@all-hands-bot all-hands-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Good taste - Pragmatic solution that solves a real problem.

Core assessment: This enforces deprecation-before-removal for public API symbols using AST scanning to detect existing deprecation markers. The approach is straightforward, well-tested, and reuses existing infrastructure (@deprecated and warn_deprecated()). No over-engineering.

Data structures: Clean flow - scan AST → build set of deprecated names → check removals against set. No unnecessary transformations.

Tests: Comprehensive coverage of decorator detection, warn_deprecated() calls, dotted name handling, and integration with griffe.

Worth merging - Fundamentally sound implementation.

Enforce that any symbol removed from openhands.sdk.__all__ was previously
marked with @deprecated or warn_deprecated() in the prior release. The
check AST-scans the old PyPI source for the SDK canonical deprecation
helpers.

Closes #2066

Co-authored-by: openhands <openhands@all-hands.dev>
@enyst enyst force-pushed the ci/require-deprecation-before-removal branch from 2d69bdc to 6f52ccb Compare February 14, 2026 05:19
@enyst enyst merged commit 5fea312 into main Feb 14, 2026
22 checks passed
@enyst enyst deleted the ci/require-deprecation-before-removal branch February 14, 2026 05:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Follow-up: require deprecation marker for intentional SDK API removals

2 participants