feat: auto-backup edited entities before write/destructive tool calls… #506
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
| name: E2E Tests | |
| on: | |
| push: | |
| branches: [ main, master ] | |
| paths: | |
| # Only run on code changes, not documentation | |
| - 'src/**' | |
| - 'tests/**' | |
| - 'pyproject.toml' | |
| - 'Dockerfile' | |
| - 'homeassistant-addon/**' | |
| - '.github/workflows/e2e-tests.yml' | |
| workflow_dispatch: | |
| # Limit GITHUB_TOKEN permissions to minimum required | |
| permissions: | |
| contents: read | |
| env: | |
| PYTHON_VERSION: "3.13" | |
| UV_CACHE_DIR: /tmp/.uv-cache | |
| # renovate: datasource=docker depName=ghcr.io/home-assistant/home-assistant | |
| HA_IMAGE_GHCR: "ghcr.io/home-assistant/home-assistant:2026.5.3" | |
| # Disable Testcontainers' Ryuk reaper: it has been reported to leave | |
| # zombie containers on GHA runners (see #366, Ilya0527 2026-05-18). | |
| # The E2E fixture in tests/src/e2e/conftest.py relies instead on the | |
| # enclosing ``with container:`` context manager — Python guarantees | |
| # its ``__exit__`` fires on both normal and exception flows, so the | |
| # Ryuk safety net is not needed for deterministic cleanup. Refs #366. | |
| TESTCONTAINERS_RYUK_DISABLED: "true" | |
| jobs: | |
| # Comprehensive E2E validation for main branch | |
| e2e-tests: | |
| name: E2E Tests | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| submodules: true | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| with: | |
| cache-binary: true | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v7 | |
| with: | |
| version: "latest" | |
| - name: Set up Python | |
| run: uv python install ${{ env.PYTHON_VERSION }} | |
| - name: Install dependencies | |
| run: uv sync --all-extras --dev | |
| - name: Cache HA Docker image | |
| id: cache-ha-image | |
| uses: actions/cache@v5 | |
| with: | |
| path: /tmp/ha-image.tar | |
| key: ha-image-${{ env.HA_IMAGE_GHCR }}-${{ runner.arch }} | |
| - name: Load cached HA image | |
| if: steps.cache-ha-image.outputs.cache-hit == 'true' | |
| run: docker load -i /tmp/ha-image.tar | |
| - name: Pull HA image (GHCR → Docker Hub fallback) | |
| if: steps.cache-ha-image.outputs.cache-hit != 'true' | |
| run: | | |
| HA_VERSION="${HA_IMAGE_GHCR##*:}" | |
| HA_IMAGE_DOCKERHUB="homeassistant/home-assistant:${HA_VERSION}" | |
| for registry in "$HA_IMAGE_GHCR" "$HA_IMAGE_DOCKERHUB"; do | |
| echo "Trying $registry..." | |
| if docker pull "$registry"; then | |
| if [ "$registry" != "$HA_IMAGE_GHCR" ]; then | |
| docker tag "$registry" "$HA_IMAGE_GHCR" | |
| fi | |
| docker save "$HA_IMAGE_GHCR" -o /tmp/ha-image.tar | |
| echo "Pulled and cached from $registry" | |
| exit 0 | |
| fi | |
| echo "Failed to pull from $registry, trying next..." | |
| sleep 15 | |
| done | |
| echo "All registries failed" && exit 1 | |
| - name: Run full E2E test suite | |
| run: | | |
| echo "🚀 Running full E2E test suite with 3 workers..." | |
| uv run pytest tests/src/e2e/ \ | |
| -n3 \ | |
| --dist loadscope \ | |
| --tb=short \ | |
| -v | |
| echo "✅ Full E2E test suite passed" | |
| env: | |
| HAMCP_ENV_FILE: "tests/.env.test" | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |