Skip to content

Commit 038b699

Browse files
authored
Speed up and simplify github workflows (python-kasa#1128)
- Enable parallel tests in the CI with pytest-xdist - Migrate to the official `astral-sh/setup-uv` github action - Call `pre-commit` run as a single job in CI instead of relisting each check - Use `uv` version 0.4.16 - Fix bug with pre-commit cache - Update `publish.yml` to use `astral-sh/setup-uv`
1 parent 1ab08f4 commit 038b699

File tree

8 files changed

+67
-87
lines changed

8 files changed

+67
-87
lines changed

.github/actions/setup/action.yaml

Lines changed: 12 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
---
22
name: Setup Environment
3-
description: Install requested pipx dependencies, configure the system python, and install uv and the package dependencies
3+
description: Install uv, configure the system python, and the package dependencies
44

55
inputs:
66
uv-install-options:
77
default: ""
88
uv-version:
9-
default: 0.4.5
9+
default: 0.4.16
1010
python-version:
1111
required: true
1212
cache-pre-commit:
@@ -17,66 +17,29 @@ inputs:
1717
runs:
1818
using: composite
1919
steps:
20-
- uses: "actions/setup-python@v5"
20+
- name: Install uv
21+
uses: astral-sh/setup-uv@v3
22+
with:
23+
enable-cache: true
24+
25+
- name: "Setup python"
26+
uses: "actions/setup-python@v5"
2127
id: setup-python
2228
with:
2329
python-version: "${{ inputs.python-version }}"
2430
allow-prereleases: true
2531

26-
- name: Setup pipx environment Variables
27-
id: pipx-env-setup
28-
# pipx default home and bin dir are not writable by the cache action
29-
# so override them here and add the bin dir to PATH for later steps.
30-
# This also ensures the pipx cache only contains uv
31-
run: |
32-
SEP="${{ !startsWith(runner.os, 'windows') && '/' || '\\' }}"
33-
PIPX_CACHE="${{ github.workspace }}${SEP}pipx_cache"
34-
echo "pipx-cache-path=${PIPX_CACHE}" >> $GITHUB_OUTPUT
35-
echo "pipx-version=$(pipx --version)" >> $GITHUB_OUTPUT
36-
echo "PIPX_HOME=${PIPX_CACHE}${SEP}home" >> $GITHUB_ENV
37-
echo "PIPX_BIN_DIR=${PIPX_CACHE}${SEP}bin" >> $GITHUB_ENV
38-
echo "PIPX_MAN_DIR=${PIPX_CACHE}${SEP}man" >> $GITHUB_ENV
39-
echo "${PIPX_CACHE}${SEP}bin" >> $GITHUB_PATH
40-
shell: bash
41-
42-
- name: Pipx cache
43-
id: pipx-cache
44-
uses: actions/cache@v4
45-
with:
46-
path: ${{ steps.pipx-env-setup.outputs.pipx-cache-path }}
47-
key: cache-${{ inputs.cache-version }}-${{ runner.os }}-${{ runner.arch }}-python-${{ inputs.python-version }}-${{ steps.setup-python.outputs.python-version }}-pipx-${{ steps.pipx-env-setup.outputs.pipx-version }}-uv-${{ inputs.uv-version }}
48-
49-
- name: Install uv
50-
if: steps.pipx-cache.outputs.cache-hit != 'true'
51-
id: install-uv
52-
shell: bash
53-
run: |-
54-
pipx install uv==${{ inputs.uv-version }} --python "${{ steps.setup-python.outputs.python-path }}"
55-
56-
- name: Read uv cache location
57-
id: uv-cache-location
58-
shell: bash
59-
run: |-
60-
echo "uv-cache-location=$(uv cache dir)" >> $GITHUB_OUTPUT
61-
62-
- uses: actions/cache@v4
63-
name: uv cache
64-
with:
65-
path: |
66-
${{ steps.uv-cache-location.outputs.uv-cache-location }}
67-
key: cache-${{ inputs.cache-version }}-${{ runner.os }}-${{ runner.arch }}-python-${{ steps.setup-python.outputs.python-version }}-uv-${{ inputs.uv-version }}-${{ hashFiles('uv.lock') }}-options-${{ inputs.uv-install-options }}
68-
69-
- name: "uv install"
32+
- name: "Install project"
7033
shell: bash
7134
run: |
72-
uv sync --python "${{ steps.setup-python.outputs.python-path }}" ${{ inputs.uv-install-options }}
35+
uv sync ${{ inputs.uv-install-options }}
7336
7437
- name: Read pre-commit version
7538
if: inputs.cache-pre-commit == 'true'
7639
id: pre-commit-version
7740
shell: bash
7841
run: >-
79-
echo "pre-commit-version=$(uv run pre-commit -- -V | awk '{print $2}')" >> $GITHUB_OUTPUT
42+
echo "pre-commit-version=$(uv run pre-commit -V | awk '{print $2}')" >> $GITHUB_OUTPUT
8043
8144
- uses: actions/cache@v4
8245
if: inputs.cache-pre-commit == 'true'

.github/workflows/ci.yml

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ on:
88
workflow_dispatch: # to allow manual re-runs
99

1010
env:
11-
UV_VERSION: 0.4.5
11+
UV_VERSION: 0.4.16
1212

1313
jobs:
1414
linting:
@@ -20,39 +20,19 @@ jobs:
2020
python-version: ["3.12"]
2121

2222
steps:
23-
- uses: "actions/checkout@v4"
23+
- name: "Checkout source files"
24+
uses: "actions/checkout@v4"
2425
- name: Setup environment
2526
uses: ./.github/actions/setup
2627
with:
2728
python-version: ${{ matrix.python-version }}
2829
cache-pre-commit: true
2930
uv-version: ${{ env.UV_VERSION }}
3031
uv-install-options: "--all-extras"
31-
- name: "Check supported device md files are up to date"
32-
run: |
33-
uv run pre-commit run generate-supported --all-files
34-
- name: "Linting and code formating (ruff)"
35-
run: |
36-
uv run pre-commit run ruff --all-files
37-
- name: "Typing checks (mypy)"
38-
run: |
39-
source .venv/bin/activate
40-
pre-commit run mypy --all-files
41-
- name: "Run trailing-whitespace"
42-
run: |
43-
uv run pre-commit run trailing-whitespace --all-files
44-
- name: "Run end-of-file-fixer"
45-
run: |
46-
uv run pre-commit run end-of-file-fixer --all-files
47-
- name: "Run check-docstring-first"
48-
run: |
49-
uv run pre-commit run check-docstring-first --all-files
50-
- name: "Run debug-statements"
51-
run: |
52-
uv run pre-commit run debug-statements --all-files
53-
- name: "Run check-ast"
32+
33+
- name: "Run pre-commit checks"
5434
run: |
55-
uv run pre-commit run check-ast --all-files
35+
uv run pre-commit run --all-files --verbose
5636
5737
5838
tests:
@@ -83,6 +63,13 @@ jobs:
8363
- os: ubuntu-latest
8464
python-version: "3.10"
8565
extras: true
66+
# Exclude pypy on windows due to significant performance issues
67+
# running pytest requires ~12 min instead of 2 min on other platforms
68+
- os: windows-latest
69+
python-version: "pypy-3.9"
70+
- os: windows-latest
71+
python-version: "pypy-3.10"
72+
8673

8774
steps:
8875
- uses: "actions/checkout@v4"
@@ -95,11 +82,11 @@ jobs:
9582
- name: "Run tests (no coverage)"
9683
if: ${{ startsWith(matrix.python-version, 'pypy') }}
9784
run: |
98-
uv run pytest
85+
uv run pytest -n auto
9986
- name: "Run tests (with coverage)"
10087
if: ${{ !startsWith(matrix.python-version, 'pypy') }}
10188
run: |
102-
uv run pytest --cov kasa --cov-report xml
89+
uv run pytest -n auto --cov kasa --cov-report xml
10390
- name: "Upload coverage to Codecov"
10491
if: ${{ !startsWith(matrix.python-version, 'pypy') }}
10592
uses: "codecov/codecov-action@v4"

.github/workflows/publish.yml

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ on:
44
types: [published]
55

66
env:
7-
UV_VERSION: 0.4.5
7+
UV_VERSION: 0.4.16
8+
PYTHON_VERSION: 3.12
89

910
jobs:
1011
build-n-publish:
@@ -14,16 +15,19 @@ jobs:
1415
id-token: write
1516

1617
steps:
17-
- uses: actions/checkout@master
18+
- name: Checkout source files
19+
uses: actions/checkout@v4
20+
21+
- name: Install uv
22+
uses: astral-sh/setup-uv@v3
23+
1824
- name: Setup python
1925
uses: actions/setup-python@v4
2026
with:
21-
python-version: "3.x"
27+
python-version: ${{ env.PYTHON_VERSION }}
2228

23-
- name: Install uv
24-
run: |-
25-
pipx install uv==${{ env.UV_VERSION }} --python "${{ steps.setup-python.outputs.python-path }}"
2629
- name: Build a binary wheel and a source tarball
2730
run: uv build
31+
2832
- name: Publish release on pypi
2933
uses: pypa/gh-action-pypi-publish@release/v1

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ repos:
22

33
- repo: https://github.com/astral-sh/uv-pre-commit
44
# uv version.
5-
rev: 0.4.5
5+
rev: 0.4.16
66
hooks:
77
# Update the uv lockfile
88
- id: uv-lock

kasa/tests/test_device.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def _get_subclasses(of_class):
3232
and module.__package__ != "kasa.interfaces"
3333
):
3434
subclasses.add((module.__package__ + "." + name, obj))
35-
return subclasses
35+
return sorted(subclasses)
3636

3737

3838
device_classes = pytest.mark.parametrize(

kasa/tests/test_protocol.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ def _get_subclasses(of_class):
481481
and name != "_deprecated_TPLinkSmartHomeProtocol"
482482
):
483483
subclasses.add((name, obj))
484-
return subclasses
484+
return sorted(subclasses)
485485

486486

487487
@pytest.mark.parametrize(

pyproject.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ dev-dependencies = [
5555
"coverage[toml]",
5656
"pytest-timeout~=2.0",
5757
"pytest-freezer~=0.4",
58-
"mypy~=1.0"
58+
"mypy~=1.0",
59+
"pytest-xdist>=3.6.1",
5960
]
6061

6162

@@ -105,6 +106,7 @@ markers = [
105106
"requires_dummy: test requires dummy data to pass, skipped on real devices",
106107
]
107108
asyncio_mode = "auto"
109+
asyncio_default_fixture_loop_scope = "function"
108110
timeout = 10
109111

110112
[tool.doc8]

uv.lock

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)