diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5b165fa..81ac6a0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,20 +19,38 @@ concurrency: jobs: test: - name: test (py${{ matrix.python-version }}${{ matrix.pyld != 'latest' && format(', pyld {0}', matrix.pyld) || '' }}) + name: test (py${{ matrix.python-version }}${{ matrix.pyld != 'latest' && format(', pyld {0}', matrix.pyld) || '' }}${{ matrix.extras != 'all' && ', pre-release' || '' }}) runs-on: ubuntu-latest timeout-minutes: 15 + # 3.15 is still a pre-release (final 2026-10-01), so its leg is advisory: it + # reports but never blocks a merge. Drop this line when 3.15.0 ships and the + # trove classifier goes in (#126) — the version pin needs no edit, since + # allow-prereleases only falls back to a pre-release while no GA build exists. + continue-on-error: ${{ matrix.python-version == '3.15' }} strategy: fail-fast: false matrix: python-version: ['3.10', '3.11', '3.12', '3.13', '3.14'] pyld: ['latest'] + extras: ['all'] include: # The [data-integrity] floor edge (#124): oldest supported pyld on the # oldest Python; every other job resolves the newest pyld (3.x). The # golden fixtures are the canonicalization-drift alarm on both edges. - python-version: '3.10' pyld: '2.0.4' + extras: 'all' + # Pre-release watch (#126). Installs core + ebsi + dev, NOT [all]: + # lxml — pulled in by signxml and by pyld 3.x — publishes no cp315 + # wheel yet, and building it from source would test lxml's build, not + # openvc. The DI / trustlist / schema suites therefore importorskip + # here (~1028 of 1107 tests still run, hence the lower coverage floor + # below). What this leg does watch is the hand-rolled, attacker-facing + # core — JOSE, CBOR/COSE, the codecs, status lists, DID resolution — + # on the new interpreter. Widen to 'all' once lxml ships cp315 wheels. + - python-version: '3.15' + pyld: 'latest' + extras: 'ebsi,dev' steps: - uses: actions/checkout@v7 @@ -41,12 +59,14 @@ jobs: uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} + # Only consulted when a version line has no GA build yet (today: 3.15). + allow-prereleases: true cache: pip - - name: Install (core + ebsi + dev) + - name: Install (core + [${{ matrix.extras }}]) run: | python -m pip install --upgrade pip - pip install -e ".[all]" + pip install -e ".[${{ matrix.extras }}]" if [ "${{ matrix.pyld }}" != "latest" ]; then pip install "pyld==${{ matrix.pyld }}"; fi - name: Lint (flake8) @@ -58,9 +78,12 @@ jobs: # Offline tier only: the live EBSI smoke test stays opt-in # (OPENVC_EBSI_LIVE=1) so CI never depends on an external service. - name: Test (pytest + coverage) + # The pre-release leg skips the pyld/signxml/jsonschema-gated suites, so it + # is held to the local gate's floor (80) instead of the full-matrix 85. run: >- pytest -q --cov=openvc --cov=openvc_ebsi - --cov-report=term-missing --cov-fail-under=85 + --cov-report=term-missing + --cov-fail-under=${{ matrix.extras == 'all' && '85' || '80' }} publish: name: Publish to PyPI diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bda09fb..7ce1dd4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,7 +17,13 @@ mypy # type check (strict-ish; the code is fully typed) gitlint # commit-message convention (see below) ``` -CI runs the same on Python 3.10–3.14. +CI runs the same on Python 3.10–3.14, plus a leg pinning the oldest supported +`pyld` and an advisory 3.15 pre-release leg (it reports but never blocks, and +installs `[ebsi,dev]` only — `lxml` has no cp315 wheel yet, so the suites behind +`[data-integrity]`, `[trustlist]` and `[schema]` skip themselves there). + +Working without an extra installed is supported: those test suites +`importorskip`, and `mypy` ignores the missing optional imports. ## Docs diff --git a/pyproject.toml b/pyproject.toml index 0964d12..0a03c00 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -115,5 +115,5 @@ no_implicit_optional = true # Third-party deps behind optional extras that ship no type information. [[tool.mypy.overrides]] module = ["httpx", "httpx.*", "pyld", "pyld.*", "jsonschema", "jsonschema.*", - "referencing", "referencing.*", "lxml", "lxml.*"] + "referencing", "referencing.*", "lxml", "lxml.*", "signxml", "signxml.*"] ignore_missing_imports = true