|
| 1 | +# Dependency E2E Release Gate |
| 2 | + |
| 3 | +[中文版](2026-10-13-dependency-e2e-release-gate.zh.md) |
| 4 | + |
| 5 | +| Field | Value | |
| 6 | +| --- | --- | |
| 7 | +| Change ID | `dependency-e2e-release-gate` | |
| 8 | +| Created | 2026-10-13 | |
| 9 | +| Status | approved | |
| 10 | +| Component specs | No component contract impact; this change only adds release-time validation for package metadata and dependency resolution. | |
| 11 | + |
| 12 | +## Background |
| 13 | + |
| 14 | +The dependency incident showed that local `uv.lock` success is not enough for PyPI users. VeADK can publish metadata that lets pip resolve an unsupported upstream version, or pin a shared base dependency so tightly that a compatible upstream stack cannot be installed. |
| 15 | + |
| 16 | +## Goals and non-goals |
| 17 | + |
| 18 | +| Type | Scope | |
| 19 | +| --- | --- | |
| 20 | +| Goal | Block PyPI publication when the built wheel cannot be installed in a clean environment. | |
| 21 | +| Goal | Expose high-risk direct dependency upgrades that conflict with current runtime pins or other package metadata. | |
| 22 | +| Goal | Reject high-risk unbounded runtime dependencies and exact pins for shared OpenTelemetry packages. | |
| 23 | +| Non-goal | Exhaustively test every optional extra, Studio/docker/sandbox runtime, or real cloud service. | |
| 24 | + |
| 25 | +## Requirements |
| 26 | + |
| 27 | +| ID | Requirement | |
| 28 | +| --- | --- | |
| 29 | +| FR-1 | The tag publish workflow must install the built wheel in a clean venv, run `pip check`, and run a minimal import smoke before uploading to PyPI. | |
| 30 | +| FR-2 | The tag publish workflow must test selected high-risk base runtime direct dependencies at their highest currently available versions inside VeADK's declared ranges, together with the built wheel's current runtime pins. | |
| 31 | +| FR-3 | The policy check must fail for unbounded `google-adk` and exact `opentelemetry-*` runtime pins. | |
| 32 | +| FR-4 | The checks must run on the release artifact, not the developer `uv.lock` environment. | |
| 33 | + |
| 34 | +## Design |
| 35 | + |
| 36 | +| Part | Decision | |
| 37 | +| --- | --- | |
| 38 | +| Script | Add `scripts/check_dependency_e2e.py` with `policy`, `clean-install`, and `declared-range` commands. | |
| 39 | +| Workflow | Expose a standalone `dependency-policy-gate` on PRs and pushes; run clean install and declared-range checks only for tag publication or manual workflow dispatch. | |
| 40 | +| Dependency scope | Check selected high-risk base dependencies: `google-adk`, `agentkit-sdk-python`, OpenTelemetry packages, `litellm`, `mcp`, `fastmcp`, `tos`, and `jsonschema`; each candidate upgrade is resolved against the full wheel metadata, including exact runtime pins. Optional extras are deferred. | |
| 41 | +| Developer guidance | Add repository-level dependency metadata guidelines so developers and coding agents avoid unbounded high-risk dependencies, unjustified shared base pins, and `uv.lock`-only validation before the heavier release E2E runs. | |
| 42 | +| Runtime smoke | Import `veadk`, `google.adk`, and `opentelemetry` only; no credentials or external service calls. | |
| 43 | + |
| 44 | +## Tasks |
| 45 | + |
| 46 | +| ID | Work | Requirement | |
| 47 | +| --- | --- | --- | |
| 48 | +| T-1 | Add the dependency E2E script. | FR-1, FR-2, FR-3, FR-4 | |
| 49 | +| T-2 | Add unit tests for dependency policy and highest-version selection. | FR-2, FR-3 | |
| 50 | +| T-3 | Wire the script into the tag publish workflow and PR-visible dependency policy gate. | FR-1, FR-2, FR-4 | |
| 51 | +| T-5 | Run the policy check from pre-commit for dependency metadata edits. | FR-3 | |
| 52 | +| T-6 | Document repository-level dependency metadata guidelines for developers and coding agents. | FR-2, FR-3 | |
| 53 | +| T-4 | Adjust runtime dependency metadata if the new checks expose an existing conflict. | FR-2, FR-3 | |
| 54 | + |
| 55 | +## Acceptance |
| 56 | + |
| 57 | +| Requirement | Task | Criterion | Verification | Result | |
| 58 | +| --- | --- | --- | --- | --- | |
| 59 | +| FR-1 | T-1, T-3 | Clean wheel install gate exists before PyPI upload. | `uv run --extra dev pytest tests/test_dependency_e2e.py` | pass | |
| 60 | +| FR-2 | T-1, T-2, T-3 | Selected high-risk direct dependency highest-version checks are implemented and unit-tested against current runtime pins. | `uv run --extra dev pytest tests/test_dependency_e2e.py`; `uv run python scripts/check_dependency_e2e.py --dist-dir <tmp-dist> declared-range` | pass | |
| 61 | +| FR-3 | T-1, T-2, T-4 | `google-adk` requires an upper bound and `opentelemetry-*` exact pins are rejected. | `uv run python scripts/check_dependency_e2e.py policy` | pass | |
| 62 | +| FR-4 | T-3 | Workflow checks `dist/*.whl` instead of `uv.lock`. | workflow diff review | pass | |
| 63 | +| FR-3 | T-5 | Local pre-commit runs the same runtime dependency policy check when `pyproject.toml` changes. | `uv run --extra dev pre-commit run --all-files` | pass | |
| 64 | +| FR-2, FR-3 | T-6 | `AGENTS.md` documents dependency metadata rules for high-risk upper bounds, shared base pins, direct dependency declarations, and heavyweight E2E deferral. | guideline diff review | pass | |
| 65 | + |
| 66 | +## Risks |
| 67 | + |
| 68 | +| Risk | Mitigation | |
| 69 | +| --- | --- | |
| 70 | +| PyPI state can change after release. | Keep the gate on tag publish and optionally run it manually before tagging. | |
| 71 | +| Highest-version installs may be slower than normal unit tests. | Check only selected high-risk dependencies and run the heavy checks only on tag publication or manual workflow dispatch. | |
| 72 | + |
| 73 | +## Review record |
| 74 | + |
| 75 | +User approved implementation after reviewing the E2E plan in chat. Direct review found no component-spec change because public SDK behavior and runtime contracts are unchanged. |
| 76 | + |
| 77 | +## Verification record |
| 78 | + |
| 79 | +| Date | Command | Result | Notes | |
| 80 | +| --- | --- | --- | --- | |
| 81 | +| 2026-10-13 | `uv lock` | pass | Refreshed lock metadata after dependency bound updates. | |
| 82 | +| 2026-10-13 | `uv run --extra dev pytest tests/test_dependency_e2e.py` | pass | 11 tests passed. | |
| 83 | +| 2026-10-13 | `uv run python scripts/check_dependency_e2e.py policy` | pass | Runtime dependency policy passed. | |
| 84 | +| 2026-10-13 | `uv run python scripts/check_dependency_e2e.py --dist-dir <tmp-dist> declared-range` | pass | Validated selected high-risk dependency pins including `google-adk==2.7.1`, `opentelemetry-exporter-otlp==1.42.1`, `opentelemetry-instrumentation-logging==0.63b1`, `fastmcp==3.4.8`, `tos==2.8.7`, and `jsonschema==4.23.0`. | |
| 85 | +| 2026-10-13 | `uv run python scripts/check_dependency_e2e.py --dist-dir <tmp-dist> clean-install` | blocked | Local PyPI download for `google-adk` was too slow and was interrupted; the workflow gate remains wired to run this in GitHub Actions before upload. | |
| 86 | + |
| 87 | +## Dependency metadata adjustments found by the E2E check |
| 88 | + |
| 89 | +| Dependency | Before | After | Reason | |
| 90 | +| --- | --- | --- | --- | |
| 91 | +| `opentelemetry-exporter-otlp` | `>=1.37.0` | `>=1.37.0,<1.43` | `google-adk 2.7.x` caps OpenTelemetry SDK/API at the 1.42 line. | |
| 92 | +| `opentelemetry-instrumentation-logging` | `>=0.56b0` | `>=0.56b0,<0.64` | The 0.64+ instrumentation line resolves with newer OpenTelemetry packages than `google-adk 2.7.x` allows. | |
| 93 | +| `fastmcp` | `>=2.12.3` | `>=2.12.3,<4` | `fastmcp 4.x` requires `mcp>=2`, while VeADK currently declares `mcp==1.26.0`. | |
| 94 | +| `tos` | `>=2.8.4` | `>=2.8.4,<2.9` | `tos 2.9.x` pins `wrapt==1.16.0`, conflicting with VeADK's `wrapt==1.17.2`. | |
| 95 | +| `jsonschema` | `>=4.23,<5` | `>=4.23,<4.24` | `litellm 1.83.x` pins `jsonschema==4.23.0`; the previous range overstated installable versions. | |
0 commit comments