diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 0000000..73bc00c --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,12 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "semiannually" + cooldown: + default-days: 20 + groups: + github-actions: + patterns: + - "*" diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..1a031b9 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,68 @@ +name: '🧪 Test' + +on: + pull_request: null + +permissions: {} +concurrency: + group: "${{ github.workflow }}-${{ github.ref }}" + cancel-in-progress: true + +env: + UV_VERSION: '0.11.29' + +jobs: + test: + name: 'Test' + runs-on: 'ubuntu-24.04' + steps: + - name: 'Checkout' + uses: 'actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0' # v7.0.0 + with: + persist-credentials: 'false' + + - name: 'Setup Python' + uses: 'actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1' # v6.3.0 + with: + allow-prereleases: 'true' + # Pre-release Python versions are listed first + # so that they are not used as the default 'python' command. + python-version: | + 3.15 + + 3.10 + 3.11 + 3.12 + 3.13 + 3.14 + + - name: 'Setup uv' + uses: 'astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39' # v8.2.0 + with: + version: "${{ env.UV_VERSION }}" + enable-cache: 'true' + + - name: 'Run the test suite' + env: + TOX_SKIP_ENV: 'coverage-html' + run: | + uv tool run --with=tox-uv --with=tox-gh tox --colored=yes + + security: + name: 'Security' + runs-on: 'ubuntu-slim' + steps: + - name: 'Checkout' + uses: 'actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0' # v7.0.0 + with: + persist-credentials: 'false' + + - name: 'Setup uv' + uses: 'astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39' # v8.2.0 + with: + version: "${{ env.UV_VERSION }}" + enable-cache: 'false' + + - name: 'Run zizmor' + run: | + uv tool run zizmor --persona=pedantic .github/workflows/* diff --git a/requirements/test/pyproject.toml b/requirements/test/pyproject.toml new file mode 100644 index 0000000..9f0a41b --- /dev/null +++ b/requirements/test/pyproject.toml @@ -0,0 +1,17 @@ +[tool.poetry] +package-mode = false + +[project] +name = "dependencies" +requires-python = ">=3.10" +dependencies = [ + "coverage[toml]", + "pyfakefs", + "pytest", + "pytest-randomly", +] + +[dependency-groups] +coverage = [ + "coverage[toml]", +] diff --git a/requirements/test/requirements-coverage.txt b/requirements/test/requirements-coverage.txt new file mode 100644 index 0000000..8ea19e1 --- /dev/null +++ b/requirements/test/requirements-coverage.txt @@ -0,0 +1,2 @@ +coverage==7.15.2 ; python_version >= "3.10" +tomli==2.4.1 ; python_version >= "3.10" and python_full_version <= "3.11.0a6" diff --git a/requirements/test/requirements.txt b/requirements/test/requirements.txt new file mode 100644 index 0000000..dded8e8 --- /dev/null +++ b/requirements/test/requirements.txt @@ -0,0 +1,12 @@ +colorama==0.4.6 ; python_version >= "3.10" and sys_platform == "win32" +coverage==7.15.2 ; python_version >= "3.10" +exceptiongroup==1.3.1 ; python_version == "3.10" +iniconfig==2.3.0 ; python_version >= "3.10" +packaging==26.2 ; python_version >= "3.10" +pluggy==1.6.0 ; python_version >= "3.10" +pyfakefs==6.2.0 ; python_version >= "3.10" +pygments==2.20.0 ; python_version >= "3.10" +pytest-randomly==4.1.0 ; python_version >= "3.10" +pytest==9.1.1 ; python_version >= "3.10" +tomli==2.4.1 ; python_version >= "3.10" and python_full_version <= "3.11.0a6" +typing-extensions==4.16.0 ; python_version == "3.10" diff --git a/tox.ini b/tox.ini index 8a7e402..73033f2 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,7 @@ [tox] envlist = coverage-erase - test-py{3.14, 3.13, 3.12, 3.11, 3.10} + test-py{3.15, 3.14, 3.13, 3.12, 3.11, 3.10} coverage-report coverage-html build{, -minimum} @@ -15,19 +15,16 @@ wheel_build_env = build_wheel commands = python -c "import sys; sys.exit('This is not a runnable tox environment')" -[testenv:test-py{3.14, 3.13, 3.12, 3.11, 3.10}] +[testenv:test-py{3.15, 3.14, 3.13, 3.12, 3.11, 3.10}] description = Test the code on Python {py_dot_ver} depends = coverage-erase -deps = - coverage[toml] - pytest +deps = -r requirements/test/requirements.txt commands = coverage run -m pytest {posargs} [testenv:coverage_base] description = Base config for coverage-* environments -deps = - coverage[toml] +deps = -r requirements/test/requirements-coverage.txt skip_install = true [testenv:coverage-erase] @@ -39,7 +36,7 @@ commands = [testenv:coverage-report] description = Display a coverage report and verify the fail-under value base = coverage_base -depends = test-py{3.14, 3.13, 3.12, 3.11, 3.10} +depends = test-py{3.15, 3.14, 3.13, 3.12, 3.11, 3.10} commands_pre = - coverage combine commands = @@ -48,7 +45,7 @@ commands = [testenv:coverage-html] description = Create an HTML coverage report base = coverage_base -depends = test-py{3.14, 3.13, 3.12, 3.11, 3.10}, coverage-report +depends = test-py{3.15, 3.14, 3.13, 3.12, 3.11, 3.10}, coverage-report commands = coverage html --fail-under=0 @@ -56,8 +53,7 @@ commands = description = Test building the documentation base_python = py3.14 skip_install = true -deps = - sphinx +deps = -r requirements/docs/requirements.txt commands = sphinx-build -aWEnb html docs/ build/docs/ @@ -94,3 +90,6 @@ deps = commands = poetry update --directory="requirements/docs" --lock poetry export --directory="requirements/docs" --output="requirements.txt" --without-hashes + poetry update --directory="requirements/test" --lock + poetry export --directory="requirements/test" --output="requirements.txt" --without-hashes + poetry export --directory="requirements/test" --output="requirements-coverage.txt" --without-hashes --only="coverage"