fix: Update Alembic configuration to use proper initialization and co… #14
This file contains 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: CI | |
on: | |
push: | |
branches: [ main, develop, 'feature/**' ] | |
pull_request: | |
branches: [ main, develop ] | |
jobs: | |
backend-tests: | |
runs-on: ubuntu-latest | |
services: | |
postgres: | |
image: postgres:14 | |
env: | |
POSTGRES_PASSWORD: postgres | |
POSTGRES_DB: test_db | |
ports: | |
- 5432:5432 | |
options: >- | |
--health-cmd pg_isready | |
--health-interval 10s | |
--health-timeout 5s | |
--health-retries 5 | |
steps: | |
- uses: actions/checkout@v3 | |
- name: Set up Python | |
uses: actions/setup-python@v4 | |
with: | |
python-version: '3.12' | |
- name: Install dependencies | |
working-directory: ./backend | |
run: | | |
python -m pip install --upgrade pip | |
# Install system dependencies | |
sudo apt-get update | |
sudo apt-get install -y tesseract-ocr | |
pip install -r requirements.txt | |
# Install test dependencies | |
pip install --upgrade --force-reinstall alembic pytest-cov flake8 psycopg2-binary httpx pytesseract pycountry PyYAML selenium pytest-mock loguru reportlab inputimeout | |
# Add local bin to PATH | |
export PATH="$HOME/.local/bin:$PATH" | |
pip list | grep alembic | |
- name: Verify environment | |
working-directory: ./backend | |
env: | |
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test_db | |
PYTHONPATH: ${GITHUB_WORKSPACE}/backend | |
run: | | |
python -c "import sys; print('Python path:', sys.path)" | |
python -c "import alembic.config; print('Alembic configuration verified')" | |
python -c "import psycopg2; conn=psycopg2.connect('$DATABASE_URL'); print('Database connection verified')" | |
- name: Run migrations | |
working-directory: ./backend | |
env: | |
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test_db | |
PYTHONPATH: ${GITHUB_WORKSPACE}/backend | |
run: | | |
echo "Setting up Python environment..." | |
export PYTHONPATH="${PYTHONPATH}:${PWD}" | |
echo "Current PYTHONPATH: $PYTHONPATH" | |
# Create Alembic directory structure | |
mkdir -p migrations/versions | |
# Create env.py | |
mkdir -p migrations | |
cat > migrations/env.py << 'EOL' | |
from logging.config import fileConfig | |
from sqlalchemy import engine_from_config | |
from sqlalchemy import pool | |
from alembic import context | |
import os | |
config = context.config | |
if config.config_file_name is not None: | |
fileConfig(config.config_file_name) | |
def run_migrations_offline() -> None: | |
url = os.getenv("DATABASE_URL") | |
context.configure( | |
url=url, | |
target_metadata=None, | |
literal_binds=True, | |
dialect_opts={"paramstyle": "named"}, | |
) | |
with context.begin_transaction(): | |
context.run_migrations() | |
def run_migrations_online() -> None: | |
configuration = config.get_section(config.config_ini_section) | |
if configuration is None: | |
configuration = {} | |
configuration["sqlalchemy.url"] = os.getenv("DATABASE_URL") | |
connectable = engine_from_config( | |
configuration, | |
prefix="sqlalchemy.", | |
poolclass=pool.NullPool, | |
) | |
with connectable.connect() as connection: | |
context.configure( | |
connection=connection, | |
target_metadata=None | |
) | |
with context.begin_transaction(): | |
context.run_migrations() | |
if context.is_offline_mode(): | |
run_migrations_offline() | |
else: | |
run_migrations_online() | |
EOL | |
# Create script.py.mako | |
cat > migrations/script.py.mako << 'EOL' | |
"""${message} | |
Revision ID: ${up_revision} | |
Revises: ${down_revision | comma,n} | |
Create Date: ${create_date} | |
""" | |
from alembic import op | |
import sqlalchemy as sa | |
${imports if imports else ""} | |
# revision identifiers, used by Alembic. | |
revision = ${repr(up_revision)} | |
down_revision = ${repr(down_revision)} | |
branch_labels = ${repr(branch_labels)} | |
depends_on = ${repr(depends_on)} | |
def upgrade() -> None: | |
${upgrades if upgrades else "pass"} | |
def downgrade() -> None: | |
${downgrades if downgrades else "pass"} | |
EOL | |
# Create and run migration script | |
cat > run_migrations.py << 'EOL' | |
import os | |
import sys | |
import logging | |
from alembic.config import Config | |
from alembic import command | |
from pathlib import Path | |
logging.basicConfig(level=logging.INFO) | |
logger = logging.getLogger(__name__) | |
try: | |
# Create alembic.ini | |
config_path = Path('alembic.ini') | |
if not config_path.exists(): | |
logger.info("Creating alembic.ini...") | |
config = Config() | |
config.set_main_option('script_location', 'migrations') | |
config.set_main_option('sqlalchemy.url', os.environ['DATABASE_URL']) | |
config.set_main_option('file_template', '%%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d_%%(minute).2d_%%(second).2d_%%(rev)s_%%(slug)s') | |
with open(config_path, 'w') as f: | |
config.write(f) | |
else: | |
config = Config(config_path) | |
# Initialize migrations if needed | |
migrations_dir = Path('migrations/versions') | |
if not migrations_dir.exists(): | |
migrations_dir.mkdir(parents=True, exist_ok=True) | |
logger.info("Creating initial migration...") | |
command.revision(config, message="Initial migration", autogenerate=True) | |
# Run the migration | |
logger.info("Running database migrations...") | |
command.upgrade(config, "head") | |
logger.info("Migrations completed successfully") | |
except Exception as e: | |
logger.error(f"Migration failed: {str(e)}", exc_info=True) | |
sys.exit(1) | |
EOL | |
# Run the migration script | |
python run_migrations.py | |
- name: Run tests with coverage | |
working-directory: ./backend | |
env: | |
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test_db | |
run: | | |
pytest --cov=src tests/ --cov-report=xml | |
- name: Run flake8 | |
working-directory: ./backend | |
run: | | |
flake8 src tests --max-line-length=100 | |
frontend-tests: | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v3 | |
- uses: pnpm/action-setup@v2 | |
with: | |
version: 8 | |
- name: Set up Node.js | |
uses: actions/setup-node@v3 | |
with: | |
node-version: '18' | |
cache: 'pnpm' | |
cache-dependency-path: './frontend/pnpm-lock.yaml' | |
- name: Install dependencies | |
working-directory: ./frontend | |
run: pnpm install | |
- name: Run tests | |
working-directory: ./frontend | |
run: pnpm test |