lifx-async 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lifx_async-1.0.0/.claude/settings.json +3 -0
- lifx_async-1.0.0/.github/dependabot.yml +62 -0
- lifx_async-1.0.0/.github/labeler.yml +65 -0
- lifx_async-1.0.0/.github/workflows/ci.yml +173 -0
- lifx_async-1.0.0/.github/workflows/docs.yml +111 -0
- lifx_async-1.0.0/.github/workflows/pr-automation.yml +156 -0
- lifx_async-1.0.0/.gitignore +94 -0
- lifx_async-1.0.0/.pre-commit-config.yaml +101 -0
- lifx_async-1.0.0/CLAUDE.md +567 -0
- lifx_async-1.0.0/LICENSE +35 -0
- lifx_async-1.0.0/PKG-INFO +43 -0
- lifx_async-1.0.0/README.md +20 -0
- lifx_async-1.0.0/docs/api/colors.md +132 -0
- lifx_async-1.0.0/docs/api/devices.md +186 -0
- lifx_async-1.0.0/docs/api/exceptions.md +336 -0
- lifx_async-1.0.0/docs/api/high-level.md +81 -0
- lifx_async-1.0.0/docs/api/index.md +247 -0
- lifx_async-1.0.0/docs/api/network.md +132 -0
- lifx_async-1.0.0/docs/api/protocol.md +363 -0
- lifx_async-1.0.0/docs/architecture/overview.md +311 -0
- lifx_async-1.0.0/docs/changelog.md +7 -0
- lifx_async-1.0.0/docs/faq.md +310 -0
- lifx_async-1.0.0/docs/getting-started/installation.md +134 -0
- lifx_async-1.0.0/docs/getting-started/quickstart.md +189 -0
- lifx_async-1.0.0/docs/index.md +133 -0
- lifx_async-1.0.0/docs/stylesheets/extra.css +49 -0
- lifx_async-1.0.0/docs/user-guide/advanced-usage.md +405 -0
- lifx_async-1.0.0/docs/user-guide/protocol-deep-dive.md +316 -0
- lifx_async-1.0.0/docs/user-guide/troubleshooting.md +401 -0
- lifx_async-1.0.0/examples/01_simple_discovery.py +65 -0
- lifx_async-1.0.0/examples/02_simple_control.py +72 -0
- lifx_async-1.0.0/examples/03_waveforms.py +83 -0
- lifx_async-1.0.0/examples/04_debug_logging.py +66 -0
- lifx_async-1.0.0/mkdocs.yml +180 -0
- lifx_async-1.0.0/pyproject.toml +151 -0
- lifx_async-1.0.0/renovate.json +186 -0
- lifx_async-1.0.0/src/lifx/__init__.py +102 -0
- lifx_async-1.0.0/src/lifx/api.py +1027 -0
- lifx_async-1.0.0/src/lifx/color.py +396 -0
- lifx_async-1.0.0/src/lifx/const.py +62 -0
- lifx_async-1.0.0/src/lifx/devices/__init__.py +37 -0
- lifx_async-1.0.0/src/lifx/devices/base.py +1292 -0
- lifx_async-1.0.0/src/lifx/devices/hev.py +310 -0
- lifx_async-1.0.0/src/lifx/devices/infrared.py +137 -0
- lifx_async-1.0.0/src/lifx/devices/light.py +677 -0
- lifx_async-1.0.0/src/lifx/devices/multizone.py +796 -0
- lifx_async-1.0.0/src/lifx/devices/tile.py +1170 -0
- lifx_async-1.0.0/src/lifx/exceptions.py +45 -0
- lifx_async-1.0.0/src/lifx/network/__init__.py +30 -0
- lifx_async-1.0.0/src/lifx/network/connection.py +1158 -0
- lifx_async-1.0.0/src/lifx/network/discovery.py +520 -0
- lifx_async-1.0.0/src/lifx/network/message.py +152 -0
- lifx_async-1.0.0/src/lifx/network/transport.py +331 -0
- lifx_async-1.0.0/src/lifx/products/__init__.py +30 -0
- lifx_async-1.0.0/src/lifx/products/generator.py +541 -0
- lifx_async-1.0.0/src/lifx/products/registry.py +1479 -0
- lifx_async-1.0.0/src/lifx/protocol/__init__.py +1 -0
- lifx_async-1.0.0/src/lifx/protocol/base.py +347 -0
- lifx_async-1.0.0/src/lifx/protocol/generator.py +1416 -0
- lifx_async-1.0.0/src/lifx/protocol/header.py +221 -0
- lifx_async-1.0.0/src/lifx/protocol/models.py +277 -0
- lifx_async-1.0.0/src/lifx/protocol/packets.py +1351 -0
- lifx_async-1.0.0/src/lifx/protocol/protocol_types.py +844 -0
- lifx_async-1.0.0/src/lifx/protocol/serializer.py +368 -0
- lifx_async-1.0.0/tests/__init__.py +1 -0
- lifx_async-1.0.0/tests/conftest.py +262 -0
- lifx_async-1.0.0/tests/test_api/__init__.py +1 -0
- lifx_async-1.0.0/tests/test_api/test_api_batch_errors.py +235 -0
- lifx_async-1.0.0/tests/test_api/test_api_batch_operations.py +162 -0
- lifx_async-1.0.0/tests/test_api/test_api_context.py +374 -0
- lifx_async-1.0.0/tests/test_api/test_api_discovery.py +330 -0
- lifx_async-1.0.0/tests/test_api/test_api_organization.py +247 -0
- lifx_async-1.0.0/tests/test_color.py +256 -0
- lifx_async-1.0.0/tests/test_devices/__init__.py +1 -0
- lifx_async-1.0.0/tests/test_devices/conftest.py +151 -0
- lifx_async-1.0.0/tests/test_devices/test_base.py +722 -0
- lifx_async-1.0.0/tests/test_devices/test_hev.py +278 -0
- lifx_async-1.0.0/tests/test_devices/test_infrared.py +145 -0
- lifx_async-1.0.0/tests/test_devices/test_light.py +408 -0
- lifx_async-1.0.0/tests/test_devices/test_multizone.py +454 -0
- lifx_async-1.0.0/tests/test_devices/test_tile.py +1073 -0
- lifx_async-1.0.0/tests/test_network/__init__.py +1 -0
- lifx_async-1.0.0/tests/test_network/test_concurrent_requests.py +263 -0
- lifx_async-1.0.0/tests/test_network/test_connection.py +471 -0
- lifx_async-1.0.0/tests/test_network/test_discovery.py +88 -0
- lifx_async-1.0.0/tests/test_network/test_discovery_devices.py +416 -0
- lifx_async-1.0.0/tests/test_network/test_discovery_errors.py +229 -0
- lifx_async-1.0.0/tests/test_network/test_message.py +223 -0
- lifx_async-1.0.0/tests/test_network/test_message_advanced.py +111 -0
- lifx_async-1.0.0/tests/test_network/test_transport.py +67 -0
- lifx_async-1.0.0/tests/test_products/test_product_generator.py +937 -0
- lifx_async-1.0.0/tests/test_products/test_registry.py +360 -0
- lifx_async-1.0.0/tests/test_protocol/test_generated.py +115 -0
- lifx_async-1.0.0/tests/test_protocol/test_header.py +163 -0
- lifx_async-1.0.0/tests/test_protocol/test_protocol_generator.py +1039 -0
- lifx_async-1.0.0/tests/test_protocol/test_serializer.py +309 -0
- lifx_async-1.0.0/tests/test_utils.py +169 -0
- lifx_async-1.0.0/uv.lock +985 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Dependabot configuration for automated dependency updates
|
|
2
|
+
# Docs: https://docs.github.com/en/code-security/dependabot
|
|
3
|
+
|
|
4
|
+
version: 2
|
|
5
|
+
updates:
|
|
6
|
+
# Python dependencies (via pip)
|
|
7
|
+
- package-ecosystem: pip
|
|
8
|
+
directory: /
|
|
9
|
+
schedule:
|
|
10
|
+
interval: weekly
|
|
11
|
+
day: monday
|
|
12
|
+
time: 09:00
|
|
13
|
+
open-pull-requests-limit: 5
|
|
14
|
+
labels:
|
|
15
|
+
- dependencies
|
|
16
|
+
- python
|
|
17
|
+
commit-message:
|
|
18
|
+
prefix: chore(deps)
|
|
19
|
+
include: scope
|
|
20
|
+
# Group updates for easier review
|
|
21
|
+
groups:
|
|
22
|
+
dev-dependencies:
|
|
23
|
+
patterns:
|
|
24
|
+
- pytest*
|
|
25
|
+
- ruff*
|
|
26
|
+
- pyright*
|
|
27
|
+
- mkdocs*
|
|
28
|
+
- hatchling*
|
|
29
|
+
- pyyaml*
|
|
30
|
+
update-types:
|
|
31
|
+
- minor
|
|
32
|
+
- patch
|
|
33
|
+
|
|
34
|
+
# GitHub Actions
|
|
35
|
+
- package-ecosystem: github-actions
|
|
36
|
+
directory: /
|
|
37
|
+
schedule:
|
|
38
|
+
interval: weekly
|
|
39
|
+
day: monday
|
|
40
|
+
time: 09:00
|
|
41
|
+
open-pull-requests-limit: 3
|
|
42
|
+
labels:
|
|
43
|
+
- dependencies
|
|
44
|
+
- github-actions
|
|
45
|
+
commit-message:
|
|
46
|
+
prefix: ci
|
|
47
|
+
include: scope
|
|
48
|
+
# Auto-merge minor and patch updates for actions
|
|
49
|
+
groups:
|
|
50
|
+
github-actions:
|
|
51
|
+
patterns:
|
|
52
|
+
- '*'
|
|
53
|
+
update-types:
|
|
54
|
+
- minor
|
|
55
|
+
- patch
|
|
56
|
+
|
|
57
|
+
# Dependabot will:
|
|
58
|
+
# 1. Check for updates weekly on Monday at 9am
|
|
59
|
+
# 2. Create PRs for outdated dependencies
|
|
60
|
+
# 3. Group related updates together
|
|
61
|
+
# 4. Auto-label PRs for easier triage
|
|
62
|
+
# 5. Limit concurrent PRs to avoid overwhelming maintainers
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Auto-labeling configuration for pull requests
|
|
2
|
+
# See: https://github.com/actions/labeler
|
|
3
|
+
|
|
4
|
+
# Source code categories
|
|
5
|
+
devices:
|
|
6
|
+
- changed-files:
|
|
7
|
+
- any-glob-to-any-file: src/lifx/devices/**
|
|
8
|
+
|
|
9
|
+
network:
|
|
10
|
+
- changed-files:
|
|
11
|
+
- any-glob-to-any-file: src/lifx/network/**
|
|
12
|
+
|
|
13
|
+
protocol:
|
|
14
|
+
- changed-files:
|
|
15
|
+
- any-glob-to-any-file:
|
|
16
|
+
- src/lifx/protocol/**
|
|
17
|
+
- protocol.yml
|
|
18
|
+
|
|
19
|
+
api:
|
|
20
|
+
- changed-files:
|
|
21
|
+
- any-glob-to-any-file: src/lifx/api.py
|
|
22
|
+
|
|
23
|
+
# Testing
|
|
24
|
+
tests:
|
|
25
|
+
- changed-files:
|
|
26
|
+
- any-glob-to-any-file: tests/**
|
|
27
|
+
|
|
28
|
+
# Documentation
|
|
29
|
+
documentation:
|
|
30
|
+
- changed-files:
|
|
31
|
+
- any-glob-to-any-file:
|
|
32
|
+
- '*.md'
|
|
33
|
+
- docs/**
|
|
34
|
+
- examples/**
|
|
35
|
+
|
|
36
|
+
# Examples
|
|
37
|
+
examples:
|
|
38
|
+
- changed-files:
|
|
39
|
+
- any-glob-to-any-file: examples/**
|
|
40
|
+
|
|
41
|
+
# CI/CD
|
|
42
|
+
ci/cd:
|
|
43
|
+
- changed-files:
|
|
44
|
+
- any-glob-to-any-file:
|
|
45
|
+
- .github/**
|
|
46
|
+
- scripts/**
|
|
47
|
+
|
|
48
|
+
# Dependencies
|
|
49
|
+
dependencies:
|
|
50
|
+
- changed-files:
|
|
51
|
+
- any-glob-to-any-file:
|
|
52
|
+
- pyproject.toml
|
|
53
|
+
- requirements*.txt
|
|
54
|
+
- uv.lock
|
|
55
|
+
|
|
56
|
+
# Configuration
|
|
57
|
+
configuration:
|
|
58
|
+
- changed-files:
|
|
59
|
+
- any-glob-to-any-file:
|
|
60
|
+
- .*rc
|
|
61
|
+
- .*rc.js
|
|
62
|
+
- .*rc.json
|
|
63
|
+
- .*.yml
|
|
64
|
+
- .*.yaml
|
|
65
|
+
- pyproject.toml
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
pull_request:
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
env:
|
|
11
|
+
PYTHON_VERSION: '3.11'
|
|
12
|
+
UV_VERSION: 0.9.4
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
# Code quality checks
|
|
16
|
+
quality:
|
|
17
|
+
name: Code Quality
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
|
|
22
|
+
- name: Set up Python
|
|
23
|
+
uses: actions/setup-python@v5
|
|
24
|
+
with:
|
|
25
|
+
python-version: ${{ env.PYTHON_VERSION }}
|
|
26
|
+
|
|
27
|
+
- name: Install uv
|
|
28
|
+
uses: astral-sh/setup-uv@v7
|
|
29
|
+
with:
|
|
30
|
+
version: ${{ env.UV_VERSION }}
|
|
31
|
+
python-version: ${{ env.PYTHON_VERSION }}
|
|
32
|
+
|
|
33
|
+
- name: Install dependencies
|
|
34
|
+
run: uv sync --frozen
|
|
35
|
+
|
|
36
|
+
- name: Run Ruff format check
|
|
37
|
+
run: uv run ruff format --check .
|
|
38
|
+
|
|
39
|
+
- name: Run Ruff linter
|
|
40
|
+
run: uv run ruff check .
|
|
41
|
+
|
|
42
|
+
- name: Run Pyright type checker
|
|
43
|
+
run: uv run pyright
|
|
44
|
+
|
|
45
|
+
- name: Check for security issues
|
|
46
|
+
run: |
|
|
47
|
+
uv pip install bandit
|
|
48
|
+
uv run bandit -r src/
|
|
49
|
+
|
|
50
|
+
# Testing matrix across Python versions and platforms
|
|
51
|
+
test:
|
|
52
|
+
name: Test (Python ${{ matrix.python-version }} on ${{ matrix.os }})
|
|
53
|
+
runs-on: ${{ matrix.os }}
|
|
54
|
+
strategy:
|
|
55
|
+
fail-fast: false
|
|
56
|
+
matrix:
|
|
57
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
58
|
+
python-version: ['3.11', '3.12', '3.13', '3.14']
|
|
59
|
+
steps:
|
|
60
|
+
- uses: actions/checkout@v4
|
|
61
|
+
|
|
62
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
63
|
+
uses: actions/setup-python@v5
|
|
64
|
+
with:
|
|
65
|
+
python-version: ${{ matrix.python-version }}
|
|
66
|
+
|
|
67
|
+
- name: Install uv
|
|
68
|
+
uses: astral-sh/setup-uv@v7
|
|
69
|
+
with:
|
|
70
|
+
version: ${{ env.UV_VERSION }}
|
|
71
|
+
python-version: ${{ matrix.python-version }}
|
|
72
|
+
enable-cache: true
|
|
73
|
+
|
|
74
|
+
- name: Install dependencies
|
|
75
|
+
run: uv sync --frozen
|
|
76
|
+
|
|
77
|
+
- name: Run unit tests
|
|
78
|
+
run: uv run --frozen pytest
|
|
79
|
+
|
|
80
|
+
- name: Upload coverage to Codecov
|
|
81
|
+
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.11'
|
|
82
|
+
uses: codecov/codecov-action@v5
|
|
83
|
+
with:
|
|
84
|
+
slug: Djelibeybi/lifx-async
|
|
85
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
86
|
+
fail_ci_if_error: false
|
|
87
|
+
|
|
88
|
+
- name: Upload test results to Codecov
|
|
89
|
+
if: ${{ !cancelled() }}
|
|
90
|
+
uses: codecov/test-results-action@v1
|
|
91
|
+
with:
|
|
92
|
+
fail_ci_if_error: false
|
|
93
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
94
|
+
|
|
95
|
+
release:
|
|
96
|
+
needs:
|
|
97
|
+
- quality
|
|
98
|
+
- test
|
|
99
|
+
runs-on: ubuntu-latest
|
|
100
|
+
permissions:
|
|
101
|
+
id-token: write
|
|
102
|
+
contents: write
|
|
103
|
+
concurrency:
|
|
104
|
+
group: ${{ github.workflow }}-release-${{ github.ref_name }}
|
|
105
|
+
cancel-in-progress: false
|
|
106
|
+
|
|
107
|
+
steps:
|
|
108
|
+
- name: Checkout repository on release branch
|
|
109
|
+
uses: actions/checkout@v4
|
|
110
|
+
with:
|
|
111
|
+
ref: ${{ github.head_ref || github.ref_name }}
|
|
112
|
+
fetch-depth: 0
|
|
113
|
+
|
|
114
|
+
- name: Test Python Semantic Release
|
|
115
|
+
id: test-release
|
|
116
|
+
uses: python-semantic-release/python-semantic-release@v10.4.1
|
|
117
|
+
if: github.ref_name != 'main'
|
|
118
|
+
with:
|
|
119
|
+
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
120
|
+
no_operation_mode: true
|
|
121
|
+
|
|
122
|
+
- name: Run Semantic Version Release
|
|
123
|
+
id: release
|
|
124
|
+
uses: python-semantic-release/python-semantic-release@v10.4.1
|
|
125
|
+
if: github.ref_name == 'main'
|
|
126
|
+
with:
|
|
127
|
+
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
128
|
+
git_committer_name: github-actions
|
|
129
|
+
git_committer_email: actions@users.noreply.github.com
|
|
130
|
+
|
|
131
|
+
- name: Upload to GitHub Release Assets
|
|
132
|
+
uses: python-semantic-release/publish-action@v10.4.1
|
|
133
|
+
if: steps.release.outputs.released == 'true'
|
|
134
|
+
with:
|
|
135
|
+
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
136
|
+
tag: ${{ steps.release.outputs.tag }}
|
|
137
|
+
|
|
138
|
+
- name: Upload Distribution Artifacts
|
|
139
|
+
uses: actions/upload-artifact@v4
|
|
140
|
+
with:
|
|
141
|
+
name: distribution-artifacts
|
|
142
|
+
path: dist
|
|
143
|
+
|
|
144
|
+
outputs:
|
|
145
|
+
released: ${{ steps.release.outputs.released || 'false' }}
|
|
146
|
+
|
|
147
|
+
deploy:
|
|
148
|
+
runs-on: ubuntu-latest
|
|
149
|
+
needs: release
|
|
150
|
+
if: ${{ needs.release.outputs.released == 'true' }}
|
|
151
|
+
|
|
152
|
+
permissions:
|
|
153
|
+
contents: read
|
|
154
|
+
id-token: write
|
|
155
|
+
|
|
156
|
+
environment:
|
|
157
|
+
name: pypi
|
|
158
|
+
url: https://pypi.org/p/lifx-async
|
|
159
|
+
|
|
160
|
+
steps:
|
|
161
|
+
- name: Download Build Artifacts
|
|
162
|
+
uses: actions/download-artifact@v4
|
|
163
|
+
id: artifact-download
|
|
164
|
+
with:
|
|
165
|
+
name: distribution-artifacts
|
|
166
|
+
path: dist
|
|
167
|
+
|
|
168
|
+
- name: Publish package distributions to PyPI
|
|
169
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
170
|
+
with:
|
|
171
|
+
packages-dir: dist
|
|
172
|
+
print-hash: true
|
|
173
|
+
verbose: true
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
name: Documentation
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
paths:
|
|
8
|
+
- docs/**
|
|
9
|
+
- src/lifx/**
|
|
10
|
+
- mkdocs.yml
|
|
11
|
+
- .github/workflows/docs.yml
|
|
12
|
+
pull_request:
|
|
13
|
+
paths:
|
|
14
|
+
- docs/**
|
|
15
|
+
- mkdocs.yml
|
|
16
|
+
|
|
17
|
+
env:
|
|
18
|
+
PYTHON_VERSION: '3.11'
|
|
19
|
+
UV_VERSION: 0.9.4
|
|
20
|
+
|
|
21
|
+
permissions:
|
|
22
|
+
contents: write
|
|
23
|
+
|
|
24
|
+
jobs:
|
|
25
|
+
build-docs:
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@v4
|
|
29
|
+
with:
|
|
30
|
+
fetch-depth: 0 # Fetch all history for git-revision-date-localized
|
|
31
|
+
|
|
32
|
+
- name: Set up Python
|
|
33
|
+
uses: actions/setup-python@v5
|
|
34
|
+
with:
|
|
35
|
+
python-version: ${{ env.PYTHON_VERSION }}
|
|
36
|
+
|
|
37
|
+
- name: Install uv
|
|
38
|
+
uses: astral-sh/setup-uv@v7
|
|
39
|
+
with:
|
|
40
|
+
version: ${{ env.UV_VERSION }}
|
|
41
|
+
python-version: ${{ env.PYTHON_VERSION }}
|
|
42
|
+
|
|
43
|
+
- name: Install dependencies
|
|
44
|
+
run: |
|
|
45
|
+
uv sync --frozen
|
|
46
|
+
|
|
47
|
+
- name: Build documentation
|
|
48
|
+
run: uv run mkdocs build
|
|
49
|
+
|
|
50
|
+
- name: Upload docs artifact
|
|
51
|
+
if: github.event_name == 'pull_request'
|
|
52
|
+
uses: actions/upload-artifact@v4
|
|
53
|
+
with:
|
|
54
|
+
name: docs
|
|
55
|
+
path: site/
|
|
56
|
+
|
|
57
|
+
deploy-docs:
|
|
58
|
+
runs-on: ubuntu-latest
|
|
59
|
+
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
|
|
60
|
+
needs: build-docs
|
|
61
|
+
steps:
|
|
62
|
+
- uses: actions/checkout@v4
|
|
63
|
+
with:
|
|
64
|
+
fetch-depth: 0
|
|
65
|
+
|
|
66
|
+
- name: Set up Python
|
|
67
|
+
uses: actions/setup-python@v5
|
|
68
|
+
with:
|
|
69
|
+
python-version: ${{ env.PYTHON_VERSION }}
|
|
70
|
+
|
|
71
|
+
- name: Install uv
|
|
72
|
+
uses: astral-sh/setup-uv@v7
|
|
73
|
+
with:
|
|
74
|
+
version: ${{ env.UV_VERSION }}
|
|
75
|
+
python-version: ${{ env.PYTHON_VERSION }}
|
|
76
|
+
|
|
77
|
+
- name: Install dependencies
|
|
78
|
+
run: |
|
|
79
|
+
uv sync --frozen
|
|
80
|
+
|
|
81
|
+
- name: Configure Git
|
|
82
|
+
run: |
|
|
83
|
+
git config user.name "github-actions[bot]"
|
|
84
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
85
|
+
|
|
86
|
+
- name: Deploy to GitHub Pages
|
|
87
|
+
run: uv run mkdocs gh-deploy --force
|
|
88
|
+
|
|
89
|
+
validate-links:
|
|
90
|
+
runs-on: ubuntu-latest
|
|
91
|
+
steps:
|
|
92
|
+
- uses: actions/checkout@v4
|
|
93
|
+
|
|
94
|
+
- name: Set up Python
|
|
95
|
+
uses: actions/setup-python@v5
|
|
96
|
+
with:
|
|
97
|
+
python-version: ${{ env.PYTHON_VERSION }}
|
|
98
|
+
|
|
99
|
+
- name: Install uv
|
|
100
|
+
uses: astral-sh/setup-uv@v7
|
|
101
|
+
with:
|
|
102
|
+
version: ${{ env.UV_VERSION }}
|
|
103
|
+
python-version: ${{ env.PYTHON_VERSION }}
|
|
104
|
+
|
|
105
|
+
- name: Install dependencies
|
|
106
|
+
run: |
|
|
107
|
+
uv sync --frozen
|
|
108
|
+
|
|
109
|
+
- name: Build and check links
|
|
110
|
+
run: |
|
|
111
|
+
uv run mkdocs build
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
name: PR Automation
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
types: [opened, synchronize, reopened, ready_for_review]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
pull-requests: write
|
|
10
|
+
issues: write
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
# Auto-label PRs based on files changed
|
|
14
|
+
auto-label:
|
|
15
|
+
name: Auto Label PR
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/labeler@v5
|
|
19
|
+
with:
|
|
20
|
+
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
21
|
+
configuration-path: .github/labeler.yml
|
|
22
|
+
|
|
23
|
+
# Size label based on lines changed
|
|
24
|
+
size-label:
|
|
25
|
+
name: Add Size Label
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
steps:
|
|
28
|
+
- uses: codelytv/pr-size-labeler@v1
|
|
29
|
+
with:
|
|
30
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
31
|
+
xs_label: size/xs
|
|
32
|
+
xs_max_size: '10'
|
|
33
|
+
s_label: size/s
|
|
34
|
+
s_max_size: '100'
|
|
35
|
+
m_label: size/m
|
|
36
|
+
m_max_size: '500'
|
|
37
|
+
l_label: size/l
|
|
38
|
+
l_max_size: '1000'
|
|
39
|
+
xl_label: size/xl
|
|
40
|
+
fail_if_xl: 'false'
|
|
41
|
+
|
|
42
|
+
# Validate PR title follows conventional commits
|
|
43
|
+
validate-title:
|
|
44
|
+
name: Validate PR Title
|
|
45
|
+
runs-on: ubuntu-latest
|
|
46
|
+
steps:
|
|
47
|
+
- uses: amannn/action-semantic-pull-request@v5
|
|
48
|
+
env:
|
|
49
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
50
|
+
with:
|
|
51
|
+
types: |
|
|
52
|
+
feat
|
|
53
|
+
fix
|
|
54
|
+
docs
|
|
55
|
+
style
|
|
56
|
+
refactor
|
|
57
|
+
perf
|
|
58
|
+
test
|
|
59
|
+
build
|
|
60
|
+
ci
|
|
61
|
+
chore
|
|
62
|
+
revert
|
|
63
|
+
scopes: |
|
|
64
|
+
devices
|
|
65
|
+
discovery
|
|
66
|
+
network
|
|
67
|
+
protocol
|
|
68
|
+
api
|
|
69
|
+
examples
|
|
70
|
+
tests
|
|
71
|
+
docs
|
|
72
|
+
ci
|
|
73
|
+
deps
|
|
74
|
+
requireScope: false
|
|
75
|
+
subjectPattern: ^(?![A-Z]).+$
|
|
76
|
+
subjectPatternError: |
|
|
77
|
+
The subject "{subject}" found in the pull request title "{title}"
|
|
78
|
+
didn't match the configured pattern. Please ensure that the subject
|
|
79
|
+
does not start with an uppercase character.
|
|
80
|
+
|
|
81
|
+
# Comment on first-time contributors
|
|
82
|
+
welcome:
|
|
83
|
+
name: Welcome First-Time Contributors
|
|
84
|
+
runs-on: ubuntu-latest
|
|
85
|
+
steps:
|
|
86
|
+
- uses: actions/first-interaction@v1
|
|
87
|
+
with:
|
|
88
|
+
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
89
|
+
pr-message: |
|
|
90
|
+
👋 Thanks for opening your first pull request! We're excited to have you contributing to lifx-async.
|
|
91
|
+
|
|
92
|
+
Here are a few things to check:
|
|
93
|
+
- [ ] All tests are passing
|
|
94
|
+
- [ ] Code follows our style guide (Ruff + Pyright)
|
|
95
|
+
- [ ] Documentation is updated if needed
|
|
96
|
+
- [ ] Conventional commit format is used
|
|
97
|
+
|
|
98
|
+
A maintainer will review your PR soon. Feel free to ask questions!
|
|
99
|
+
|
|
100
|
+
# Check for breaking changes
|
|
101
|
+
breaking-changes:
|
|
102
|
+
name: Check for Breaking Changes
|
|
103
|
+
runs-on: ubuntu-latest
|
|
104
|
+
steps:
|
|
105
|
+
- uses: actions/checkout@v4
|
|
106
|
+
with:
|
|
107
|
+
fetch-depth: 0
|
|
108
|
+
|
|
109
|
+
- name: Check for breaking changes
|
|
110
|
+
uses: actions/github-script@v7
|
|
111
|
+
with:
|
|
112
|
+
script: |
|
|
113
|
+
const { data: files } = await github.rest.pulls.listFiles({
|
|
114
|
+
owner: context.repo.owner,
|
|
115
|
+
repo: context.repo.repo,
|
|
116
|
+
pull_number: context.issue.number
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// Check for potential breaking changes
|
|
120
|
+
const breakingPatterns = [
|
|
121
|
+
/src\/lifx\/api\.py/,
|
|
122
|
+
/src\/lifx\/devices\/.*\.py/,
|
|
123
|
+
/src\/lifx\/protocol\/packets\.py/
|
|
124
|
+
];
|
|
125
|
+
|
|
126
|
+
const breakingFiles = files.filter(file =>
|
|
127
|
+
breakingPatterns.some(pattern => pattern.test(file.filename))
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
if (breakingFiles.length > 0) {
|
|
131
|
+
const comment = `## ⚠️ Potential Breaking Changes Detected
|
|
132
|
+
|
|
133
|
+
This PR modifies public API files:
|
|
134
|
+
${breakingFiles.map(f => `- \`${f.filename}\``).join('\n')}
|
|
135
|
+
|
|
136
|
+
**Please ensure:**
|
|
137
|
+
- [ ] Changes are backward compatible, OR
|
|
138
|
+
- [ ] This is a major version bump (v2.0.0, v3.0.0, etc.)
|
|
139
|
+
- [ ] Migration guide is provided
|
|
140
|
+
- [ ] Breaking changes are documented in PR description`;
|
|
141
|
+
|
|
142
|
+
await github.rest.issues.createComment({
|
|
143
|
+
owner: context.repo.owner,
|
|
144
|
+
repo: context.repo.repo,
|
|
145
|
+
issue_number: context.issue.number,
|
|
146
|
+
body: comment
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
// Add label
|
|
150
|
+
await github.rest.issues.addLabels({
|
|
151
|
+
owner: context.repo.owner,
|
|
152
|
+
repo: context.repo.repo,
|
|
153
|
+
issue_number: context.issue.number,
|
|
154
|
+
labels: ['breaking-change']
|
|
155
|
+
});
|
|
156
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
|
|
8
|
+
# Distribution / packaging
|
|
9
|
+
build/
|
|
10
|
+
develop-eggs/
|
|
11
|
+
dist/
|
|
12
|
+
downloads/
|
|
13
|
+
eggs/
|
|
14
|
+
.eggs/
|
|
15
|
+
lib/
|
|
16
|
+
lib64/
|
|
17
|
+
parts/
|
|
18
|
+
sdist/
|
|
19
|
+
var/
|
|
20
|
+
wheels/
|
|
21
|
+
pip-wheel-metadata/
|
|
22
|
+
share/python-wheels/
|
|
23
|
+
*.egg-info/
|
|
24
|
+
.installed.cfg
|
|
25
|
+
*.egg
|
|
26
|
+
MANIFEST
|
|
27
|
+
|
|
28
|
+
# Virtual Environments
|
|
29
|
+
.env
|
|
30
|
+
.venv
|
|
31
|
+
env/
|
|
32
|
+
venv/
|
|
33
|
+
ENV/
|
|
34
|
+
env.bak/
|
|
35
|
+
venv.bak/
|
|
36
|
+
.python-version
|
|
37
|
+
|
|
38
|
+
# IDEs
|
|
39
|
+
.vscode/
|
|
40
|
+
.idea/
|
|
41
|
+
*.swp
|
|
42
|
+
*.swo
|
|
43
|
+
*~
|
|
44
|
+
.DS_Store
|
|
45
|
+
|
|
46
|
+
# Testing
|
|
47
|
+
.pytest_cache/
|
|
48
|
+
.coverage
|
|
49
|
+
.coverage.*
|
|
50
|
+
htmlcov/
|
|
51
|
+
.tox/
|
|
52
|
+
.nox/
|
|
53
|
+
coverage.xml
|
|
54
|
+
*.cover
|
|
55
|
+
.hypothesis/
|
|
56
|
+
junit.xml
|
|
57
|
+
|
|
58
|
+
# Type checking
|
|
59
|
+
.mypy_cache/
|
|
60
|
+
.dmypy.json
|
|
61
|
+
dmypy.json
|
|
62
|
+
.pytype/
|
|
63
|
+
pyrightconfig.json
|
|
64
|
+
|
|
65
|
+
# Ruff
|
|
66
|
+
.ruff_cache/
|
|
67
|
+
|
|
68
|
+
# Jupyter Notebook
|
|
69
|
+
.ipynb_checkpoints
|
|
70
|
+
*.ipynb
|
|
71
|
+
|
|
72
|
+
# Documentation
|
|
73
|
+
docs/_build/
|
|
74
|
+
site/
|
|
75
|
+
|
|
76
|
+
# Build artifacts
|
|
77
|
+
*.prof
|
|
78
|
+
*.lprof
|
|
79
|
+
|
|
80
|
+
# OS
|
|
81
|
+
.DS_Store
|
|
82
|
+
Thumbs.db
|
|
83
|
+
.Spotlight-V100
|
|
84
|
+
.Trashes
|
|
85
|
+
|
|
86
|
+
# Temporary files
|
|
87
|
+
*.tmp
|
|
88
|
+
*.bak
|
|
89
|
+
*.log
|
|
90
|
+
.cache/
|
|
91
|
+
|
|
92
|
+
# Local storage
|
|
93
|
+
.notes/
|
|
94
|
+
.claude/settings.local.json
|