diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 633c55e..f82d553 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,27 +4,32 @@ on: push: pull_request: +permissions: {} + jobs: checks: runs-on: ubuntu-latest steps: - name: Checkout working copy - uses: actions/checkout@v4 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # 6.0.1 with: submodules: true fetch-depth: 0 persist-credentials: false - name: ruff check - uses: chartboost/ruff-action@v1 + uses: astral-sh/ruff-action@57714a7c8a2e59f32539362ba31877a1957dded1 # 3.5.1 + with: + version: "latest" - name: ruff format if: always() - uses: chartboost/ruff-action@v1 + uses: astral-sh/ruff-action@57714a7c8a2e59f32539362ba31877a1957dded1 # 3.5.1 with: - args: format --diff + version: "latest" + args: format --check --diff - name: Set up Python id: setup_python if: always() - uses: actions/setup-python@v5 + uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # 6.1.0 with: python-version: "3.x" - name: Install mypy @@ -44,12 +49,12 @@ jobs: steps: - name: Checkout working copy - uses: actions/checkout@v4 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # 6.0.1 with: submodules: true persist-credentials: false - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # 6.1.0 with: python-version: "3.x" - name: Install dependency @@ -60,14 +65,14 @@ jobs: run: | python -mbuild - name: Upload sdist - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # 6.0.0 with: name: sdist path: dist/*.tar.gz retention-days: 1 - name: Upload wheel - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # 6.0.0 with: name: wheel path: dist/*.whl @@ -84,31 +89,31 @@ jobs: - sdist - source python-version: - - "3.9" - "3.10" - "3.11" - "3.12" - "3.13" - - "pypy-3.10" + - "3.14" + - "3.14t" - "pypy-3.11" - - "graalpy-24" + - "graalpy-25" include: - source: sdist artifact: dist/*.tar.gz - source: wheel artifact: dist/*.whl - opts: "" - - python-version: graalpy-24 + - python-version: graalpy-25 opts: "--experimental-options --engine.CompileOnly='~tregex re'" steps: - name: Checkout working copy - uses: actions/checkout@v4 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # 6.0.1 with: submodules: true fetch-depth: 0 persist-credentials: false - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # 6.1.0 with: python-version: ${{ matrix.python-version }} allow-prereleases: true @@ -132,7 +137,7 @@ jobs: - run: 'python -mpip install --only-binary :all: google-re2 || true' - name: download ${{ matrix.source }} artifact if: matrix.artifact - uses: actions/download-artifact@v4 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # 7.0.0 with: name: ${{ matrix.source }} path: dist/ @@ -140,3 +145,12 @@ jobs: run: python -m pip install ${{ matrix.artifact || '.' }} - name: run tests run: python ${{ matrix.opts }} -m pytest -v -Werror -Wignore::ImportWarning --doctest-glob="*.rst" -ra + # necessary to create a unified CI result and not have to update + # branch protection rules every time the matrix gets updated + results: + name: "CI Results" + needs: ["checks", "test"] + runs-on: ubuntu-latest + permissions: {} + steps: + - run: exit 0 diff --git a/.github/workflows/release-builtins.yml b/.github/workflows/release-builtins.yml index 538ef90..db013a2 100644 --- a/.github/workflows/release-builtins.yml +++ b/.github/workflows/release-builtins.yml @@ -2,6 +2,8 @@ name: Publish ua-parser builtins run-name: Publish ${{ inputs.tag || 'master' }} to ${{ inputs.environment || 'pypy (scheduled)' }} +permissions: {} + on: schedule: # schedule a dev release on every 1st of the month, at 2034 UTC @@ -23,13 +25,13 @@ jobs: outputs: release: ${{ steps.check.outputs.release }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # 6.0.1 with: submodules: true fetch-depth: 0 persist-credentials: false - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # 6.1.0 with: python-version: "3.x" @@ -70,7 +72,7 @@ jobs: mv ua-parser-builtins/dist . - name: Store the distribution packages if: ${{ steps.check.outputs.release == 'true' }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # 6.0.0 with: name: python-package-distributions path: dist/ @@ -90,12 +92,12 @@ jobs: steps: - name: Download all the dists - uses: actions/download-artifact@v4 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # 7.0.0 with: name: python-package-distributions path: dist/ - name: Publish - uses: pypa/gh-action-pypi-publish@release/v1 + uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # 1.13.0 with: repository-url: https://test.pypi.org/legacy/ skip-existing: true @@ -114,11 +116,11 @@ jobs: steps: - name: Download all the dists - uses: actions/download-artifact@v4 + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # 7.0.0 with: name: python-package-distributions path: dist/ - name: Publish - uses: pypa/gh-action-pypi-publish@release/v1 + uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # 1.13.0 with: verbose: true diff --git a/.github/workflows/release-main.yml b/.github/workflows/release-main.yml index bc6fca9..0e42d7e 100644 --- a/.github/workflows/release-main.yml +++ b/.github/workflows/release-main.yml @@ -5,6 +5,8 @@ on: release: types: [created] +permissions: {} + env: ENVNAME: ${{ github.event_name == 'release' && 'pypi' || 'testpypi' }} @@ -21,11 +23,11 @@ jobs: steps: - name: Checkout working copy - uses: actions/checkout@v4 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # 6.0.1 with: persist-credentials: false - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # 6.1.0 with: python-version: "3.x" - name: Install dependency @@ -36,7 +38,7 @@ jobs: run: python -mbuild - name: Publish to testpypi if: ${{ env.ENVNAME == 'testpypi' }} - uses: pypa/gh-action-pypi-publish@release/v1 # zizmor: ignore[use-trusted-publishing] + uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # 1.13.0 with: repository-url: https://test.pypi.org/legacy/ skip-existing: true @@ -44,7 +46,7 @@ jobs: password: ${{ secrets.PUBLISH_TOKEN }} - name: Publish to pypi if: ${{ env.ENVNAME == 'pypi' }} - uses: pypa/gh-action-pypi-publish@release/v1 # zizmor: ignore[use-trusted-publishing] + uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # 1.13.0 with: verbose: true password: ${{ secrets.PUBLISH_TOKEN }} diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index 5bf4f98..f94fa7b 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -4,6 +4,8 @@ on: push: pull_request: +permissions: {} + jobs: zizmor: runs-on: ubuntu-latest @@ -13,12 +15,12 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # 6.0.1 with: persist-credentials: false - name: Install the latest version of uv - uses: astral-sh/setup-uv@v5 + uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 # 7.1.6 - name: Run zizmor run: uvx zizmor --format sarif . > results.sarif @@ -26,7 +28,7 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Upload SARIF file - uses: github/codeql-action/upload-sarif@v3 + uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # 4.31.9 with: sarif_file: results.sarif category: zizmor diff --git a/.github/zizmor.yml b/.github/zizmor.yml new file mode 100644 index 0000000..62ab71e --- /dev/null +++ b/.github/zizmor.yml @@ -0,0 +1,4 @@ +rules: + use-trusted-publishing: + ignore: + - release-main.yml # can't do that until pypi/support#6661 diff --git a/pyproject.toml b/pyproject.toml index fb94bbf..d2421d6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ name = "ua-parser" description = "Python port of Browserscope's user agent parser" version = "1.0.1" readme = "README.rst" -requires-python = ">=3.9" +requires-python = ">=3.10" dependencies = ["ua-parser-builtins"] license = {text = "Apache 2.0"} @@ -33,11 +33,11 @@ classifiers = [ "Topic :: Internet :: WWW/HTTP", "Topic :: Software Development :: Libraries :: Python Modules", "Programming Language :: Python", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Programming Language :: Python :: Implementation :: GraalPy", @@ -81,7 +81,7 @@ combine-as-imports = true "tests/test_legacy.py" = ["PT030"] [tool.mypy] -python_version = "3.9" +python_version = "3.10" files = "src,tests" # can't use strict because it's only global diff --git a/tox.ini b/tox.ini index da50c20..63cddcd 100644 --- a/tox.ini +++ b/tox.ini @@ -1,8 +1,8 @@ [tox] min_version = 4.0 -env_list = py3{9,10,11,12,13} - pypy{310,311} - graalpy +env_list = py3{10,11,12,13,14,14t} + pypy{311} + graalpy3{11,12} check, format, typecheck [testenv] @@ -21,7 +21,7 @@ deps = commands = pytest -Werror --doctest-glob="*.rst" {posargs} -[testenv:py3{9,10,11,12,13}] +[testenv:py3{10,11,12,13,14}] labels = test, cpy deps = pytest @@ -30,9 +30,6 @@ deps = ua-parser-rs ./ua-parser-builtins -[testenv:pypy{310,311}] -labels = test, pypy - [testenv:check] labels = check package = skip diff --git a/ua-parser-builtins/pyproject.toml b/ua-parser-builtins/pyproject.toml index 0086e85..6fc800d 100644 --- a/ua-parser-builtins/pyproject.toml +++ b/ua-parser-builtins/pyproject.toml @@ -7,7 +7,7 @@ name = "ua-parser-builtins" description = "Precompiled rules for User Agent Parser" readme = "README.md" dependencies = [] -requires-python = ">=3.9" +requires-python = ">=3.10" license = {text = "Apache 2.0"} urls = {repository = "https://github.com/ua-parser/uap-python"} dynamic = ["version"] @@ -25,11 +25,11 @@ classifiers = [ "Topic :: Internet :: WWW/HTTP", "Topic :: Software Development :: Libraries :: Python Modules", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Programming Language :: Python :: Implementation :: GraalPy",