From 83dcc161cfab363133f5a2d07e89768584bd5f5d Mon Sep 17 00:00:00 2001 From: Ramesh Padmanabhaiah <22363102+codeforester@users.noreply.github.com> Date: Sun, 9 Aug 2026 09:19:29 -0700 Subject: [PATCH] ci: define tested dependency compatibility windows --- .github/workflows/dependency-matrix.yml | 48 +++++++++++++++++++++++++ CHANGELOG.md | 5 +++ docs/api-stability.md | 14 ++++---- docs/dependency-support.md | 38 ++++++++++++++++++++ docs/platform-support.md | 10 ++++++ mkdocs.yml | 1 + pyproject.toml | 4 +-- scripts/validate_package_artifact.py | 2 +- tests/validate.sh | 1 + 9 files changed, 114 insertions(+), 9 deletions(-) create mode 100644 .github/workflows/dependency-matrix.yml create mode 100644 docs/dependency-support.md diff --git a/.github/workflows/dependency-matrix.yml b/.github/workflows/dependency-matrix.yml new file mode 100644 index 0000000..cbac924 --- /dev/null +++ b/.github/workflows/dependency-matrix.yml @@ -0,0 +1,48 @@ +name: Dependency compatibility + +on: + push: + pull_request: + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + core: + name: Click ${{ matrix.click-version }} / PyYAML ${{ matrix.pyyaml-version }} / Python ${{ matrix.python-version }} + runs-on: ubuntu-latest + timeout-minutes: 15 + strategy: + fail-fast: false + matrix: + python-version: ["3.10", "3.14"] + click-version: ["8.1.*", "8.2.*"] + pyyaml-version: ["6.0.*"] + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Set up Python + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 + with: + python-version: ${{ matrix.python-version }} + - name: Install framework and test dependencies + run: python -m pip install "setuptools<77" "wheel" ".[dev]" + - name: Select tested core dependency lines + run: | + python -m pip install --upgrade --force-reinstall \ + "click==${{ matrix.click-version }}" \ + "PyYAML==${{ matrix.pyyaml-version }}" + - name: Verify resolved dependency contract + run: | + python - <<'PY' + from importlib.metadata import version + + click_version = version("click") + yaml_version = version("PyYAML") + print(f"Click {click_version}; PyYAML {yaml_version}") + PY + - name: Run core suite + run: python -m pytest diff --git a/CHANGELOG.md b/CHANGELOG.md index d503b65..88ee72e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,11 @@ and versions are tracked in the repo-root `VERSION` file. - Continue compatibility hardening and adoption work for the next release. +### Changed + +- Bound the core Click and PyYAML dependency windows, publish the tested + compatibility matrix, and document the dependency update policy. + ### Added - Add a framework choice guide, five-minute evaluation path, and clearer diff --git a/docs/api-stability.md b/docs/api-stability.md index 0df27f9..14bb6ab 100644 --- a/docs/api-stability.md +++ b/docs/api-stability.md @@ -49,12 +49,14 @@ that need a frozen API should pin a minor release (for example, `~=0.4.0`). The core package requires Python `>=3.10` and currently tests CPython 3.10 through 3.14 on Linux, macOS, and Windows. Core runtime dependencies are -Click `>=8.1` and PyYAML `>=6.0`. Optional integrations are independently -versioned and constrained in `pyproject.toml`: Typer `>=0.12,<0.28`, Rich -`>=13.7,<15`, and OpenTelemetry API `>=1.24,<2`. The lower bounds are the -minimum supported versions; a dependency major release is supported after it -passes the compatibility suite. A future minor release may drop an end-of-life -Python or dependency window with a migration note. +Click `>=8.1,<9` and PyYAML `>=6.0,<7`. Optional integrations are +independently versioned and constrained in `pyproject.toml`: Typer +`>=0.12,<0.28`, Rich `>=13.7,<15`, and OpenTelemetry API `>=1.24,<2`. The +lower bounds are the minimum supported versions; a dependency major release +is supported only after it passes the compatibility suite. The tested core +dependency matrix is maintained in [`dependency-support.md`](dependency-support.md). +A future minor release may drop an end-of-life Python or dependency window with +a migration note. Platform tier details and the operating-system support test matrix are kept in [`platform-support.md`](platform-support.md). diff --git a/docs/dependency-support.md b/docs/dependency-support.md new file mode 100644 index 0000000..7e1caef --- /dev/null +++ b/docs/dependency-support.md @@ -0,0 +1,38 @@ +# Dependency support matrix + +This page is the human-readable dependency contract for the current release +line. The package metadata is authoritative for installation; this matrix +documents the versions covered by CI and the process for widening a window. + +## Core runtime + +| Dependency | Declared window | CI coverage | Policy | +| --- | --- | --- | --- | +| Python | `>=3.10,<4` (CPython 3.10--3.14) | Every OS test job | Drop an end-of-life line only in a documented compatibility release | +| Click | `>=8.1,<9` | 8.1 and 8.2 lines on Python 3.10 and 3.14 | Review the next major before widening the upper bound | +| PyYAML | `>=6.0,<7` | 6.0 line on Python 3.10 and 3.14 | Keep YAML optionality and parser behavior covered by profile tests | + +The `base-cli[yaml]` extra is planned as the minimal installation for YAML +profiles. Until that extra is released, PyYAML remains part of the core +runtime metadata. + +## Optional integrations + +Optional integrations are intentionally independent of the core window: + +| Extra | Declared window | Compatibility evidence | +| --- | --- | --- | +| `typer` | `>=0.12,<0.28` | Typer 0.25--0.27 across Python 3.10--3.14 | +| `rich` | `>=13.7,<15` | Integration tests and graceful-degradation checks | +| `telemetry` | `>=1.24,<2` | Telemetry integration tests | + +## Updating a window + +1. Add the candidate lower or upper line to the dependency matrix. +2. Run the full test, type-check, documentation, and installed-wheel gates. +3. Review release notes and consumer impact, including resolver behavior. +4. Update `pyproject.toml`, this page, and the API stability contract in one + pull request. + +An untested major version is not considered supported merely because it can be +installed successfully. diff --git a/docs/platform-support.md b/docs/platform-support.md index 4366e51..74a3833 100644 --- a/docs/platform-support.md +++ b/docs/platform-support.md @@ -34,6 +34,16 @@ include the operating system, distribution or WSL version when relevant, Python version, and whether paths live on the native filesystem or a mounted filesystem. +## Dependency support + +The core runtime dependency contract is Click `>=8.1,<9` and PyYAML +`>=6.0,<7`. The lower bound is the oldest supported line; the upper bound +prevents an unreviewed major release from entering a production install. The +CI [dependency matrix](https://github.com/basefoundry/base-cli/actions/workflows/dependency-matrix.yml) +exercises the supported Click lines on the oldest and newest supported Python +versions. Optional integrations have independent extras and version windows; +see [`api-stability.md`](api-stability.md). + ## WSL2 WSL2 is supported when Python runs inside the Linux distribution. Validate a diff --git a/mkdocs.yml b/mkdocs.yml index 98bead3..b8450b1 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -37,6 +37,7 @@ nav: - Consumer profiles: consumer-profiles.md - API and contracts: - API stability: api-stability.md + - Dependency support: dependency-support.md - Migration guide: migrations.md - Output contracts: output-contracts.md - JSON contracts: json-contracts.md diff --git a/pyproject.toml b/pyproject.toml index e4ffa7f..d5ace10 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,8 +41,8 @@ classifiers = [ "Topic :: Software Development :: Libraries :: Python Modules", ] dependencies = [ - "click>=8.1", - "PyYAML>=6.0", + "click>=8.1,<9", + "PyYAML>=6.0,<7", ] [project.optional-dependencies] diff --git a/scripts/validate_package_artifact.py b/scripts/validate_package_artifact.py index 679596f..6965ae2 100644 --- a/scripts/validate_package_artifact.py +++ b/scripts/validate_package_artifact.py @@ -15,7 +15,7 @@ PACKAGE_NAME = "base-cli" IMPORT_NAME = "base_cli" MINIMUM_PYTHON = ">=3.10" -REQUIRED_DEPENDENCIES = ("click>=8.1", "PyYAML>=6.0") +REQUIRED_DEPENDENCIES = ("click<9,>=8.1", "PyYAML<7,>=6.0") DOCUMENTATION_URL = "Documentation, https://basefoundry.github.io/base-cli/" ALLOWED_WHEEL_DIST_INFO_FILES = frozenset({"METADATA", "RECORD", "WHEEL", "top_level.txt", "entry_points.txt"}) ALLOWED_SDIST_FILES = frozenset( diff --git a/tests/validate.sh b/tests/validate.sh index 925c781..483d3d3 100755 --- a/tests/validate.sh +++ b/tests/validate.sh @@ -18,6 +18,7 @@ required_files=( .github/workflows/package.yml .github/workflows/examples.yml .github/workflows/compatibility.yml + .github/workflows/dependency-matrix.yml .github/ISSUE_TEMPLATE/support.md docs/releasing.md docs/index.md