chore(release): cut v4.1.0-rc9 with consolidated release notes (#1471) #1850
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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 |