1- # This workflow will install Python dependencies, run tests and lint with a single version of Python
2- # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
3-
41name : Unit Tests
52
63on : [push, pull_request]
@@ -10,24 +7,120 @@ jobs:
107 runs-on : ubuntu-latest
118 strategy :
129 matrix :
13- python-version : ["3.11"]
10+ python-version : ["3.11", "3.14" ]
1411
1512 steps :
1613 - uses : actions/checkout@v3
17- - name : Set up Python ${{ matrix.python-version}}
18- uses : actions/setup-python@v3
14+
15+ - name : Set up Python ${{ matrix.python-version }} and uv
16+ uses : astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
1917 with :
18+ version : " 0.12.8"
2019 python-version : ${{ matrix.python-version }}
2120
22- - name : Test with pytest
21+ - name : Sync locked environment
22+ run : uv sync --locked
23+
24+ - name : Run unittest with coverage
25+ run : |
26+ uv run --locked coverage run -m unittest discover . --pattern '*test.py'
27+ uv run --locked coverage report
28+
29+ package :
30+ runs-on : ubuntu-latest
31+
32+ steps :
33+ - uses : actions/checkout@v3
34+
35+ - name : Set up Python 3.11 and uv
36+ uses : astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
37+ with :
38+ version : " 0.12.8"
39+ python-version : " 3.11"
40+
41+ - name : Sync locked environment
42+ run : uv sync --locked
43+
44+ - name : Build source and wheel distributions
45+ run : uv build --no-sources
46+
47+ - name : Inspect distribution metadata and payload
48+ run : |
49+ uv run --locked python - <<'EOF'
50+ import email.parser
51+ import pathlib
52+ import tarfile
53+ import tomllib
54+ import zipfile
55+
56+ expected_dependencies = [
57+ "observable==0.3.*",
58+ "requests==2.*",
59+ "websockets==15.*",
60+ ]
61+ expected_classifiers = [
62+ "Programming Language :: Python :: 3",
63+ "Programming Language :: Python :: 3.11",
64+ "Programming Language :: Python :: 3 :: Only",
65+ "Programming Language :: Python :: Implementation :: CPython",
66+ ]
67+
68+ dist = pathlib.Path("dist")
69+ wheel_path = next(dist.glob("ringcentral-*.whl"))
70+ sdist_path = next(dist.glob("ringcentral-*.tar.gz"))
71+
72+ with zipfile.ZipFile(wheel_path) as wheel:
73+ wheel_names = wheel.namelist()
74+ wheel_metadata_path = next(
75+ name for name in wheel_names if name.endswith(".dist-info/METADATA")
76+ )
77+ wheel_metadata = email.parser.Parser().parsestr(
78+ wheel.read(wheel_metadata_path).decode()
79+ )
80+
81+ with open("pyproject.toml", "rb") as file:
82+ project = tomllib.load(file)["project"]
83+
84+ assert wheel_metadata["Name"] == "ringcentral"
85+ assert wheel_metadata["Version"] == project["version"]
86+ assert wheel_metadata["Requires-Python"] == ">=3.11"
87+ assert wheel_metadata.get_all("Requires-Dist") == expected_dependencies
88+ assert wheel_metadata.get_all("Classifier") == expected_classifiers
89+
90+ wheel_top_levels = {name.split("/")[0] for name in wheel_names}
91+ assert wheel_top_levels == {"ringcentral", wheel_metadata_path.split("/")[0]}
92+ assert "ringcentral/test/testcase.py" in wheel_names
93+ assert "ringcentral/test/spy.py" in wheel_names
94+ assert any(name.endswith("_test.py") for name in wheel_names)
95+ assert not any("demo" in name.lower() for name in wheel_names)
96+
97+ with tarfile.open(sdist_path) as sdist:
98+ sdist_files = {
99+ member.name.split("/", 1)[1]
100+ for member in sdist.getmembers()
101+ if member.isfile()
102+ }
103+ sdist_names = sdist.getnames()
104+
105+ assert sdist_files == {
106+ "PKG-INFO",
107+ "README.md",
108+ "LICENSE.md",
109+ "MANIFEST.in",
110+ "pyproject.toml",
111+ "requirements.txt",
112+ "setup.cfg",
113+ "setup.py",
114+ "ringcentral.egg-info/PKG-INFO",
115+ "ringcentral.egg-info/SOURCES.txt",
116+ "ringcentral.egg-info/dependency_links.txt",
117+ "ringcentral.egg-info/requires.txt",
118+ "ringcentral.egg-info/top_level.txt",
119+ } | {name for name in wheel_names if name.startswith("ringcentral/")}
120+ assert not any("demo" in name.lower() for name in sdist_names)
121+ EOF
122+
123+ - name : Install and import the wheel in a clean environment
23124 run : |
24- #Create virtual environment
25- python -m venv venv
26- #Activate virtual environment
27- source venv/bin/activate
28- #Install dependencies
29- pip install -r requirements.txt
30- pip install -r requirements-dev.txt
31- #Run unit tests
32- coverage run -m unittest discover . --pattern '*test.py'
33- coverage report
125+ wheel=$(ls dist/ringcentral-*.whl)
126+ uv run --no-project --with "$wheel" python -c "import ringcentral; from importlib.metadata import version; print('imported', version('ringcentral'))"
0 commit comments