Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 26 additions & 111 deletions .github/workflows/release-wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ concurrency:
cancel-in-progress: true

jobs:
py-wheels-matrix:
py-generate-matrix:
name: "generate build matrix"
runs-on: ubuntu-latest
if: >
Expand All @@ -34,59 +34,29 @@ jobs:
contains(github.event.pull_request.labels.*.name, 'check-wheels')
)
outputs:
matrix: ${{ steps.make-matrix.outputs.matrix }}
wheels: ${{ steps.make-matrix-wheels.outputs.matrix }}
tests: ${{ steps.make-matrix-tests.outputs.matrix }}
steps:
- id: make-matrix
shell: python
name: generate matrix
- id: download-matrix-scripts
name: retrieve matrix scripts
run: |
import itertools
import json
import os
import pprint

builder = {
('linux', 'x86_64'): 'ubuntu-latest',
('linux', 'aarch64'): 'ubuntu-24.04-arm',
('musllinux', 'x86_64'): 'ubuntu-latest',
('musllinux', 'aarch64'): 'ubuntu-24.04-arm',
('macos', 'x86_64'): 'macos-15-intel',
('macos', 'aarch64'): 'macos-latest',
('windows', 'x86_64'): 'windows-latest',
('windows', 'aarch64'): 'windows-11-arm',
}

matrix = [
d
for d in map(dict, itertools.product(
(('python-version', v) for v in ["3.x", "3.14t", "pypy-3.11", "graalpy-25"]),
(('arch', a) for a in ["x86_64", "aarch64"]),
(('platform', p) for p in ["linux", "musllinux", "windows", "macos"])
))
# on windows, only cpython has arm builds (?)
if d['python-version'].startswith('3.') \
or d['platform'] != 'windows' \
or d['arch'] != 'aarch64'
]
for job in matrix:
match job['platform']:
case 'linux':
job['manylinux'] = 'auto'
job['args'] = ' --zig' # use zig instead of docker for manylinux cross-builds (see #315)
case 'mussllinux':
job['manylinux'] = 'musllinux_1_2'

job['runs'] = builder[job['platform'], job['arch']]

with open(os.environ['GITHUB_OUTPUT'], 'w') as f:
f.write("matrix=")
json.dump({'include': matrix}, f)
f.flush()

curl -fsSL \
-O https://raw.githubusercontent.com/${{ github.repository }}/${{ github.sha }}/scripts/matrix-wheels.py \
-O https://raw.githubusercontent.com/${{ github.repository }}/${{ github.sha }}/scripts/matrix-tests.py
- id: make-matrix-wheels
name: generate wheels matrix
run: |
echo -n "matrix=" >> $GITHUB_OUTPUT
python3 matrix-wheels.py | tee -a $GITHUB_OUTPUT | jq "."
- id: make-matrix-tests
name: generate tests matrix
run: |
echo -n "matrix=" >> $GITHUB_OUTPUT
python3 matrix-tests.py | tee -a $GITHUB_OUTPUT | jq "."
py-release-wheels:
needs: [py-wheels-matrix]
needs: [py-generate-matrix]
strategy:
matrix: ${{fromJson(needs.py-wheels-matrix.outputs.matrix)}}
matrix: ${{ fromJson(needs.py-generate-matrix.outputs.wheels) }}

runs-on: ${{ matrix.runs }}

Expand All @@ -97,8 +67,7 @@ jobs:
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: ${{ matrix.python-version }}
# windows/arm doesn't have a rust toolchain by default
- if: matrix.platform == 'windows' && matrix.arch == 'aarch64'
- if: (matrix.setup-rust)
uses: actions-rust-lang/setup-rust-toolchain@ecabd13d1c56bd1345c230e542e9144811ad706f # v2.0.0
- name: Build wheels
uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0
Expand All @@ -109,7 +78,7 @@ jobs:
- name: Upload wheels
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ua-parser-rs-${{ matrix.platform }}-${{ matrix.arch }}-${{ matrix.python-version }}
name: ua-parser-rs-${{ matrix.platform }}-${{ matrix.arch }}-${{ matrix.python-version }}.whl
path: dist/*
retention-days: 1
compression-level: 0
Expand All @@ -132,64 +101,9 @@ jobs:
path: dist

py-release-tests:
needs: py-release-wheels

needs: [py-generate-matrix, py-release-wheels]
strategy:
matrix:
python-version:
- "3.10"
- "3.11"
- "3.12"
- "3.13"
- "3.14"
- "3.14t"
- "pypy-3.11"
- "graalpy-25"
platform:
- linux
# probably requires a custom image of some sort
# - musllinux
- windows
- macos
arch:
- x86_64
- aarch64

exclude:
- platform: windows
python-version: 3.10
arch: aarch64
- platform: windows
arch: aarch64
python-version: pypy-3.11
- platform: windows
python-version: graalpy-25

include:
- wheel: "3.x"
- python-version: "3.14t"
wheel: "3.14t"
- python-version: "pypy-3.11"
wheel: "pypy-3.11"
- python-version: "graalpy-25"
wheel: "graalpy-25"

- runner: ubuntu-latest
- arch: aarch64
runner: ubuntu-24.04-arm
- platform: windows
runner: windows-latest
- platform: windows
arch: aarch64
runner: windows-11-arm
- platform: macos
runner: macos-latest
- platform: macos
arch: x86_64
runner: macos-15-intel
- opts: ""
- python-version: graalpy-25
opts: "--experimental-options --engine.CompileOnly='~tregex re'"
matrix: ${{ fromJson(needs.py-generate-matrix.outputs.tests) }}

runs-on: ${{ matrix.runner }}

Expand All @@ -204,10 +118,11 @@ jobs:
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true
freethreaded: ${{ endsWith(matrix.python-version, 't') }}
- name: Retrieve wheel
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # 8.0.1
with:
name: ua-parser-rs-${{ matrix.platform }}-${{ matrix.arch }}-${{ matrix.wheel }}
name: ua-parser-rs-${{ matrix.platform }}-${{ matrix.arch }}-${{ matrix.wheel }}.whl
path: dist
- name: Update pip
run: python -mpip install --upgrade pip
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ classifiers = [
"Programming Language :: Python",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Software Development :: Libraries :: Python Modules",
"Programming Language :: Python",
"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 :: 3.15",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"Programming Language :: Python :: Implementation :: GraalPy",
Expand Down
51 changes: 51 additions & 0 deletions scripts/matrix-tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import itertools
import json

# fmt: off
PYTHON_VERSIONS = [
"3.10", "3.11", "3.12", "3.13", "3.14", "3.15",
"3.14t", "3.15t",
"pypy-3.11", "pypy-3.12",
"graalpy-25",
]
matrix = [
d
for d in map(dict, itertools.product(
(("python-version", v) for v in PYTHON_VERSIONS),
(("arch", a) for a in ["x86_64", "aarch64"]),
(("platform", p) for p in ["linux", "windows", "macos"]),
))
# on windows, only cpython has arm builds (?)
if (d["python-version"].startswith("3.") and d["python-version"] != "3.10")
or d["platform"] != "windows"
or d["arch"] != "aarch64"
]
# fmt: on

RUNNERS = {
("linux", "x86_64"): "ubuntu-latest",
("linux", "aarch64"): "ubuntu-24.04-arm",
("musllinux", "x86_64"): "ubuntu-latest",
("musllinux", "aarch64"): "ubuntu-24.04-arm",
("macos", "x86_64"): "macos-15-intel",
("macos", "aarch64"): "macos-latest",
("windows", "x86_64"): "windows-latest",
("windows", "aarch64"): "windows-11-arm",
}
for job in matrix:
job["opts"] = ""
job["runner"] = RUNNERS[job["platform"], job["arch"]]

match job["python-version"]:
case "3.14t":
job["wheel"] = "3.14t"
case "3.15t":
job["wheel"] = "3.15"
case v if v.startswith("3."):
job["wheel"] = "3.14"
case v: # pypy, graal only do single-version wheels
job["wheel"] = v
if v.startswith("graal"):
job["opts"] = "--experimental-options --engine.CompileOnly='~tregex re'"

print(json.dumps({"include": matrix}))
44 changes: 44 additions & 0 deletions scripts/matrix-wheels.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import itertools
import json

builder = {
("linux", "x86_64"): "ubuntu-latest",
("linux", "aarch64"): "ubuntu-24.04-arm",
("musllinux", "x86_64"): "ubuntu-latest",
("musllinux", "aarch64"): "ubuntu-24.04-arm",
("macos", "x86_64"): "macos-15-intel",
("macos", "aarch64"): "macos-latest",
("windows", "x86_64"): "windows-latest",
("windows", "aarch64"): "windows-11-arm",
}

# fmt: off
matrix = [
d
for d in map(dict, itertools.product(
(("python-version", v) for v in ["3.14", "3.14t", "3.15", "pypy-3.11", "pypy-3.12", "graalpy-25"]),
(("arch", a) for a in ["x86_64", "aarch64"]),
(("platform", p) for p in ["linux", "musllinux", "windows", "macos"]),
))
# on windows, only cpython has arm builds (?)
if d["python-version"].startswith("3.")
or d["platform"] != "windows"
or d["arch"] != "aarch64"
]
# fmt: on
# platform-specific fixups
for job in matrix:
match job["platform"]:
case "linux":
job["manylinux"] = "auto"
# use zig instead of docker for manylinux cross-builds (see #315)
job["args"] = " --zig"
case "mussllinux":
job["manylinux"] = "musllinux_1_2"
# windows/arm doesn't have a rust toolchain by default
case "windows" if job["arch"] == "aarch64":
job["setup-rust"] = True

job["runs"] = builder[job["platform"], job["arch"]]

print(json.dumps({"include": matrix}))
7 changes: 4 additions & 3 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[tox]
min_version = 4.0
env_list = py3{10,11,12,13,14,14t}
pypy{311}
graalpy3{11,12}
env_list = py3{10,11,12,13,14,14t,15,15t}
pypy{311,312}
graalpy313
check, format, typecheck

[testenv]
Expand All @@ -22,6 +22,7 @@ deps =
commands =
pytest -Werror --doctest-glob="*.rst" {posargs}

# versions with re2 support
[testenv:py3{10,11,12,13,14}]
labels = test, cpy
deps =
Expand Down
2 changes: 1 addition & 1 deletion ua-parser-builtins/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ classifiers = [
"Programming Language :: Python",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Software Development :: Libraries :: Python Modules",
"Programming Language :: Python :: 3",
"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 :: 3.15",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"Programming Language :: Python :: Implementation :: GraalPy",
Expand Down
Loading
Loading