d925709c77
Single-repo CI now that plugins are bundled in-tree. Three lanes on push to dev/main, modeled on FabledCurator's canonical ci.yml (minus frontend/Redis): - lint: ruff check steward/ plugins/ tests/ (no dep install) - unit: pytest -m 'not integration' — whole current suite (testing=True mocks DB) - integration: postgres:16-alpine service via socket-discovered bridge IP; a boot-and-migrate test creates the real app, running core + all bundled-plugin migrations, then round-trips the DB — guards the folded-in migration graph. Registers the 'integration' pytest marker; adds tests/integration/test_boot.py. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
43 lines
1.4 KiB
Python
43 lines
1.4 KiB
Python
"""Integration: boot the real app against a live Postgres.
|
|
|
|
Creating the app with testing=False runs the core Alembic migrations AND every
|
|
bundled plugin's migrations (discovered across all plugin roots). This is the
|
|
canonical guard that the folded-in plugin migration graph resolves end-to-end —
|
|
a pure-unit test can't catch a broken plugin revision chain.
|
|
|
|
Requires STEWARD_DATABASE_URL pointing at a live Postgres; the integration CI
|
|
lane provides it. Skipped automatically when unset so the unit lane stays green.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import asyncio
|
|
import os
|
|
|
|
import pytest
|
|
|
|
pytestmark = pytest.mark.integration
|
|
|
|
|
|
@pytest.mark.skipif(
|
|
not os.environ.get("STEWARD_DATABASE_URL"),
|
|
reason="integration test needs a live Postgres (STEWARD_DATABASE_URL)",
|
|
)
|
|
def test_real_boot_runs_all_migrations():
|
|
from sqlalchemy import text
|
|
|
|
from steward.app import create_app
|
|
|
|
# testing=False → init_db + run_core_migrations (core + all bundled-plugin
|
|
# migrations) + load_settings_sync + load_plugins all execute here.
|
|
app = create_app(testing=False)
|
|
assert app is not None
|
|
|
|
async def _roundtrip():
|
|
async with app.db_sessionmaker() as session:
|
|
# app_settings exists only if core migrations actually applied.
|
|
result = await session.execute(text("SELECT COUNT(*) FROM app_settings"))
|
|
return result.scalar()
|
|
|
|
count = asyncio.run(_roundtrip())
|
|
assert count is not None
|