Skip to content

chore(release): cut v4.1.0-rc9 with consolidated release notes (#1471) #1850

chore(release): cut v4.1.0-rc9 with consolidated release notes (#1471)

chore(release): cut v4.1.0-rc9 with consolidated release notes (#1471) #1850

Workflow file for this run

# Beatify CI Pipeline
# Runs lint, tests, and coverage on every push/PR
#
# Stages:
# 1. lint - Code quality checks (ruff)
# 2. test - Unit and integration tests (pytest)
# 3. burn-in - Flaky test detection (10 iterations on PR to main)
#
# Performance targets:
# - Lint: <1 min
# - Test: <5 min
# - Burn-in: <15 min (10 iterations)
name: Test
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
# Weekly burn-in on schedule
schedule:
- cron: "0 6 * * 1" # Every Monday at 6 AM UTC
# Cancel in-progress runs on new push
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
PYTHON_VERSION: "3.13"
jobs:
# ==========================================================================
# STAGE 1: LINT
# ==========================================================================
lint:
name: Lint (${{ matrix.python-version }})
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.12", "3.13"]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install ruff
run: pip install ruff==0.15.7
- name: Run ruff linter
run: ruff check .
- name: Run ruff formatter check
run: ruff format --check .
# ==========================================================================
# STAGE 1a: TYPE CHECK (mypy)
# ==========================================================================
# Static type checking (#1275). Runs in lenient + scoped mode: only the clean
# subset of game/ + services/ modules listed under [tool.mypy] in
# pyproject.toml is checked today. Catches the provider-URI-mismatch class of
# bug (#768/#808) statically. Scope/strictness ramp up over time β€” see the
# ramp-up plan in pyproject.toml.
typecheck:
name: Type check (mypy, ${{ matrix.python-version }})
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.12", "3.13"]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install mypy
run: pip install mypy==1.18.2
- name: Run mypy
# Config + scoped file list both come from [tool.mypy] in pyproject.toml.
run: mypy
env:
PYTHONPATH: ${{ github.workspace }}
# ==========================================================================
# STAGE 1b: FRONTEND BUILD CHECK
# ==========================================================================
# Rebuilds the served .min.js bundles from their .js sources and fails if any
# committed bundle drifted. Guards against the #1263 class of bug (source edit
# not reflected in the minified bundle that browsers actually load).
frontend-build:
name: Frontend build check
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: "22"
- name: Install dependencies
run: npm install --no-audit --no-fund
- name: Verify min.js bundles match source
run: npm run build:check
# ==========================================================================
# STAGE 2: TEST
# ==========================================================================
test:
name: Test (${{ matrix.python-version }})
runs-on: ubuntu-latest
needs: lint
strategy:
matrix:
python-version: ["3.12", "3.13"]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Cache pip dependencies
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements_test.txt
- name: Run unit tests
run: pytest tests/unit/ -v --tb=short
env:
PYTHONPATH: ${{ github.workspace }}
- name: Run integration tests
run: pytest tests/integration/ -v --tb=short
env:
PYTHONPATH: ${{ github.workspace }}
- name: Run all tests with coverage
env:
PYTHONPATH: ${{ github.workspace }}
run: |
pytest tests/unit/ tests/integration/ \
--cov=custom_components/beatify \
--cov-report=xml \
--cov-report=html \
--cov-report=term-missing \
--cov-fail-under=68 # gate just below measured 69.86% (#1282); raise progressively as coverage grows
- name: Upload coverage report
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: htmlcov/
retention-days: 7
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
files: coverage.xml
fail_ci_if_error: false
continue-on-error: true
# ==========================================================================
# STAGE 3: BURN-IN (Flaky Test Detection)
# ==========================================================================
burn-in:
name: Burn-in (Flaky Detection)
runs-on: ubuntu-latest
needs: test
# Only run on PRs to main or scheduled
if: github.event_name == 'pull_request' && github.base_ref == 'main' || github.event_name == 'schedule'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Cache pip dependencies
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements_test.txt
- name: Run burn-in loop (10 iterations)
env:
PYTHONPATH: ${{ github.workspace }}
run: |
echo "πŸ”₯ Starting burn-in loop - 10 iterations"
echo "Purpose: Detect flaky/non-deterministic tests"
echo ""
for i in {1..10}; do
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "πŸ”₯ Burn-in iteration $i/10"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
pytest tests/unit/ tests/integration/ -v --tb=short || {
echo "❌ FLAKY TEST DETECTED on iteration $i"
echo "Tests must pass 10/10 times to be considered stable"
exit 1
}
echo "βœ… Iteration $i passed"
echo ""
done
echo "πŸŽ‰ All 10 burn-in iterations passed - tests are stable!"
- name: Upload failure artifacts
if: failure()
uses: actions/upload-artifact@v4
with:
name: burn-in-failures
path: |
.pytest_cache/
htmlcov/
retention-days: 30
# ==========================================================================
# STAGE 4: HA VALIDATION (Optional - requires HA dev environment)
# ==========================================================================
# ha-validation:
# name: Home Assistant Validation
# runs-on: ubuntu-latest
# needs: test
# steps:
# - name: Checkout code
# uses: actions/checkout@v4
#
# - name: HACS Validation
# uses: hacs/action@main
# with:
# category: integration
#
# - name: hassfest validation
# uses: home-assistant/actions/hassfest@master