diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c2fa363..0564016 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,6 +4,7 @@ name: CI on: push: branches: [main] + tags: ["*"] pull_request: workflow_dispatch: @@ -14,6 +15,7 @@ env: permissions: {} + jobs: lint: name: Run linters @@ -29,45 +31,55 @@ jobs: uvx --with tox-uv tox run -e lint -- --show-diff-on-failure + + build-package: + name: Build & verify package + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - uses: hynek/build-and-inspect-python-package@v2 + id: baipp + + outputs: + # Used to define the matrix for tests below. The value is based on + # packaging metadata (trove classifiers). + python-versions: ${{ steps.baipp.outputs.supported_python_classifiers_json_array }} + + tests: - name: Tests on ${{ matrix.python-version }} + name: Tests & Mypy API on ${{ matrix.python-version }} runs-on: ubuntu-latest + needs: build-package strategy: matrix: - python-version: - - "3.8" - - "3.9" - - "3.10" - - "3.11" - - "3.12" - - "pypy-3.9" - - "pypy-3.10" + # Created by the build-and-inspect-python-package action above. + python-version: ${{ fromJson(needs.build-package.outputs.python-versions) }} steps: - - uses: actions/checkout@v4 + - name: Download pre-built packages + uses: actions/download-artifact@v4 + with: + name: Packages + path: dist + - run: | + tar xf dist/*.tar.gz --strip-components=1 + rm -rf src - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} allow-prereleases: true - uses: hynek/setup-cached-uv@v2 - - name: Prepare tox & run tests - run: | - V=${{ matrix.python-version }} - - if [[ "$V" = pypy-* ]]; then - V=pypy3 - else - V=py$(echo $V | tr -d .) - fi - - uvx --with tox-uv \ - tox run -f "$V" - - - name: Run Mypy on API + - name: Run tests run: > uvx --with tox-uv - tox run -e mypy-api + tox run + --installpkg dist/*.whl + -f py$(echo ${{ matrix.python-version }} | tr -d .) - name: Upload coverage data uses: actions/upload-artifact@v4 @@ -77,8 +89,16 @@ jobs: include-hidden-files: true if-no-files-found: ignore + - name: Check public API with Mypy + run: > + uvx --with tox-uv + tox run + --installpkg dist/*.whl + -e mypy-api + + coverage: - name: Combine & check coverage + name: Ensure 100% test coverage needs: tests runs-on: ubuntu-latest @@ -114,12 +134,19 @@ jobs: path: htmlcov if: ${{ failure() }} + mypy-pkg: - name: Type-check package + name: Mypy Codebase runs-on: ubuntu-latest + needs: build-package steps: - - uses: actions/checkout@v4 + - name: Download pre-built packages + uses: actions/download-artifact@v4 + with: + name: Packages + path: dist + - run: tar xf dist/*.tar.gz --strip-components=1 - uses: actions/setup-python@v5 with: python-version-file: .python-version-default @@ -129,6 +156,7 @@ jobs: uvx --with tox-uv tox run -e mypy-pkg + install-dev: strategy: matrix: @@ -148,12 +176,22 @@ jobs: run: | python -Im pip install -e .[dev] python -Ic 'import service_identity; print(service_identity.__version__)' + python -Ic 'import service_identity.pyopenssl' + python -Ic 'import service_identity.cryptography' + docs: name: Build docs & run doctests + needs: build-package runs-on: ubuntu-latest + steps: - - uses: actions/checkout@v4 + - name: Download pre-built packages + uses: actions/download-artifact@v4 + with: + name: Packages + path: dist + - run: tar xf dist/*.tar.gz --strip-components=1 - uses: actions/setup-python@v5 with: # Keep in sync with tox.ini/docs & .readthedocs.yaml @@ -164,6 +202,7 @@ jobs: uvx --with tox-uv tox run -e docs + required-checks-pass: name: Ensure everything required is passing for branch protection if: always() diff --git a/.github/workflows/pypi-package.yml b/.github/workflows/pypi-package.yml index 85e55ef..87905be 100644 --- a/.github/workflows/pypi-package.yml +++ b/.github/workflows/pypi-package.yml @@ -5,7 +5,6 @@ on: push: branches: [main] tags: ["*"] - pull_request: release: types: - published diff --git a/pyproject.toml b/pyproject.toml index 8e82e69..b7823b3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -89,6 +89,7 @@ addopts = ["-ra", "--strict-markers", "--strict-config"] xfail_strict = true testpaths = "tests" filterwarnings = ["once::Warning"] +norecursedirs = ["tests/typing"] [tool.coverage.run] diff --git a/tox.ini b/tox.ini index 221d18c..f3015ba 100644 --- a/tox.ini +++ b/tox.ini @@ -4,7 +4,6 @@ env_list = lint, mypy-{api,pkg}, docs, - pypy3{,-pyopenssl-latest-idna}, py3{8,9,10,11,12}{,-pyopenssl}{,-oldest}{,-idna}, coverage-report