From 526c3fdbc8736051d89a28965061ddaa757807d9 Mon Sep 17 00:00:00 2001 From: Ee Durbin Date: Thu, 15 Jun 2023 10:09:38 -0400 Subject: [PATCH] Support Pydantic <1.11, Test compatibility among supported Python and pydantic versions. (#122) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * setup an initial test matrix * add all the static checks and some collections "check_static" and "check_all" * shim nox in for the Make targets * 🤦 * Run test matrix in its own job, static checks only in pr_checks.yml * feat: merge the test matrix back into the main PR check file * feat: refactor the noxfile to have more discrete sessions * feat: update the PR static checks to use a matrix --------- Co-authored-by: Thomas Co-authored-by: Thomas --- .dockerignore | 1 + .github/workflows/pr_checks.yml | 112 +++++++++----------------------- Makefile | 25 ++++--- dev-requirements.txt | 3 +- noxfile.py | 85 ++++++++++++++++++++++++ requirements.txt | 2 +- 6 files changed, 131 insertions(+), 97 deletions(-) create mode 100644 noxfile.py diff --git a/.dockerignore b/.dockerignore index ff7ca1ca..ae16a0b5 100644 --- a/.dockerignore +++ b/.dockerignore @@ -9,3 +9,4 @@ mkdocs/ # Ignore dev files .github/ .devcontainer/ +.nox/ diff --git a/.github/workflows/pr_checks.yml b/.github/workflows/pr_checks.yml index b93aa563..ed53033e 100644 --- a/.github/workflows/pr_checks.yml +++ b/.github/workflows/pr_checks.yml @@ -1,13 +1,14 @@ -name: PR Checks +name: Static Checks on: pull_request: branches: - - main + - "*" env: CONTAINER: fideslang-local IMAGE: ethyca/fideslang:local + DEFAULT_PYTHON_VERSION: "3.10.11" jobs: Build: @@ -37,25 +38,6 @@ jobs: path: /tmp/${{ env.CONTAINER }}.tar retention-days: 1 - Black: - needs: Build - runs-on: ubuntu-latest - steps: - - name: Download fideslang container - uses: actions/download-artifact@v2 - with: - name: ${{ env.CONTAINER }} - path: /tmp/ - - - name: Load fideslang image - run: docker load --input /tmp/${{ env.CONTAINER }}.tar - - - name: Checkout - uses: actions/checkout@v2 - - - name: Run formatter - run: make black - Export: runs-on: ubuntu-latest steps: @@ -74,78 +56,46 @@ jobs: - name: Run Export run: python scripts/export_default_taxonomy.py - Pylint: - needs: Build + Static-Checks: + continue-on-error: true + strategy: + matrix: + session_name: ["black", "mypy", "pylint", "xenon"] runs-on: ubuntu-latest steps: - - name: Download fideslang container - uses: actions/download-artifact@v2 - with: - name: ${{ env.CONTAINER }} - path: /tmp/ - - - name: Load fideslang image - run: docker load --input /tmp/${{ env.CONTAINER }}.tar - - name: Checkout - uses: actions/checkout@v2 - - - name: Run linter - run: make pylint + uses: actions/checkout@v3 - Mypy: - needs: Build - runs-on: ubuntu-latest - steps: - - name: Download fideslang container - uses: actions/download-artifact@v2 + - name: Set Up Python + uses: actions/setup-python@v4 with: - name: ${{ env.CONTAINER }} - path: /tmp/ - - - name: Load fideslang image - run: docker load --input /tmp/${{ env.CONTAINER }}.tar + python-version: ${{ env.DEFAULT_PYTHON_VERSION }} + cache: "pip" - - name: Checkout - uses: actions/checkout@v2 + - name: Install Nox + run: pip install nox - - name: Run typechecker - run: make mypy + - name: Run Static Check + run: nox -s ${{ matrix.session_name }} - Xenon: - needs: Build + Pytest-Matrix: + strategy: + matrix: + python_version: ["3.8", "3.9", "3.10", "3.11"] + pydantic_version: ["1.8.2", "1.9.2", "1.10.9"] runs-on: ubuntu-latest steps: - - name: Download fideslang container - uses: actions/download-artifact@v2 - with: - name: ${{ env.CONTAINER }} - path: /tmp/ - - - name: Load fideslang image - run: docker load --input /tmp/${{ env.CONTAINER }}.tar - - name: Checkout - uses: actions/checkout@v2 - - - name: Run cyclomatic complexity check - run: make xenon + uses: actions/checkout@v3 - Pytest: - needs: Build - runs-on: ubuntu-latest - steps: - - name: Download fideslang container - uses: actions/download-artifact@v2 + - name: Set Up Python + uses: actions/setup-python@v4 with: - name: ${{ env.CONTAINER }} - path: /tmp/ - - - name: Load fideslang image - run: docker load --input /tmp/${{ env.CONTAINER }}.tar + python-version: ${{ matrix.python_version }} + cache: "pip" - - name: Checkout - uses: actions/checkout@v2 + - name: Install Nox + run: pip install nox - - name: Run unit test suite - run: make pytest + - name: Run Tests + run: nox -s "tests-${{ matrix.python_version }}(pydantic_version='${{ matrix.pydantic_version }}')" diff --git a/Makefile b/Makefile index e6909d84..2f7005a1 100644 --- a/Makefile +++ b/Makefile @@ -28,11 +28,11 @@ help: @echo ---- @echo build - Builds the fideslang Docker image. @echo ---- - @echo check-all - Run all CI checks except for externally dependent ones. + @echo check-all - Run all CI checks @echo ---- @echo clean - Runs Docker commands to clean up the docker local environment. @echo ---- - @echo shell - Spins up the database, API, and starts a shell within the API container to run CLI commands. + @echo shell - Starts a shell within the container to run CLI commands. @echo ---- @echo docs-serve - Spins up the docs server on localhost:8000 @echo -------------------- @@ -71,33 +71,30 @@ push: build #################### black: - @$(RUN) black --check src/ + @$(RUN) nox -s black # The order of dependent targets here is intentional -check-all: teardown build-local-prod check-install black \ - pylint mypy xenon pytest +check-all: teardown build-local-prod check-install check-static pytest @echo "Running formatter, linter, typechecker and tests..." +check-static: + @$(RUN) nox -s check_static + check-install: @echo "Checking that fideslang is installed..." @$(RUN) python -c "import fideslang" mypy: - @$(RUN) mypy + @$(RUN) nox -s mypy pylint: - @$(RUN) pylint src/ + @$(RUN) nox -s pylint pytest: build-local - @$(RUN) pytest -x + @$(RUN) nox -s tests xenon: - @$(RUN) xenon src \ - --max-absolute B \ - --max-modules B \ - --max-average A \ - --ignore "data, tests, docs" \ - --exclude "src/fideslang/_version.py" + @$(RUN) nox -s xenon #################### # Utils diff --git a/dev-requirements.txt b/dev-requirements.txt index 9d7fecb3..d7157620 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,10 +1,11 @@ black==22.3 ipython mypy==0.910 +nox packaging==20.9 pre-commit==2.9.3 pylint==2.10.0 -pytest==6.2.2 +pytest==7.3.1 pytest-cov==2.11.1 requests-mock==1.8.0 setuptools>=64.0.2 diff --git a/noxfile.py b/noxfile.py new file mode 100644 index 00000000..dc1dd86e --- /dev/null +++ b/noxfile.py @@ -0,0 +1,85 @@ +import nox + +nox.options.sessions = [] + +TESTED_PYTHON_VERSIONS = ["3.8", "3.9", "3.10", "3.11"] +TESTED_PYDANTIC_VERSIONS = ["1.8.2", "1.9.2", "1.10.9"] + + +def install_requirements(session: nox.Session) -> None: + session.install("-r", "requirements.txt") + session.install("-r", "dev-requirements.txt") + + +@nox.session(python=TESTED_PYTHON_VERSIONS) +@nox.parametrize("pydantic_version", TESTED_PYDANTIC_VERSIONS) +def tests(session: nox.Session, pydantic_version: str) -> None: + install_requirements(session) + session.install(".") + session.install(f"pydantic=={pydantic_version}") + if session.posargs: + test_args = session.posargs + else: + test_args = [""] + session.run("pytest", *test_args) + + +@nox.session() +def pytest(session: nox.Session) -> None: + """Runs the pytest suite with default versions.""" + install_requirements(session) + session.install(".") + session.run("pytest") + + +@nox.session() +def black(session: nox.Session) -> None: + install_requirements(session) + session.run("black", "--check", "src/") + + +@nox.session() +def mypy(session: nox.Session) -> None: + install_requirements(session) + session.run("mypy") + + +@nox.session() +def pylint(session: nox.Session) -> None: + install_requirements(session) + session.run("pylint", "--jobs", "0", "src/") + + +@nox.session() +def xenon(session: nox.Session) -> None: + install_requirements(session) + session.run( + "xenon", + "src", + "--max-absolute", + "B", + "--max-modules", + "B", + "--max-average", + "A", + "--ignore", + "data,tests,docs", + "--exclude", + "src/fideslang/_version.py", + ) + + +@nox.session() +def static_checks(session: nox.Session) -> None: + """Run the static checks.""" + session.notify("black") + session.notify("xenon") + session.notify("pylint") + session.notify("mypy") + + +@nox.session() +def check_all(session: nox.Session) -> None: + """Run static checks as well as tests.""" + session.notify("static_checks") + session.notify("tests") diff --git a/requirements.txt b/requirements.txt index 0f9f6083..a779745a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ -pydantic>=1.8.1,<1.10.0 +pydantic>=1.8.1,<1.11.0 pyyaml>=5,<6