# GitLab CI/CD Configuration # ========================= stages: - lint - test - security - build variables: PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip" PYTHON_VERSION: "3.11" # Cache dependencies between jobs cache: paths: - .cache/pip - .venv/ # Lint Stage # ---------- ruff: stage: lint image: python:${PYTHON_VERSION} before_script: - pip install uv - uv sync --frozen script: - .venv/bin/ruff check . rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Test Stage # ---------- pytest: stage: test image: python:${PYTHON_VERSION} services: - name: postgres:15 alias: postgres variables: # PostgreSQL service configuration POSTGRES_DB: wizamart_test POSTGRES_USER: test_user POSTGRES_PASSWORD: test_password # Application database URL for tests TEST_DATABASE_URL: "postgresql://test_user:test_password@postgres:5432/wizamart_test" # Skip database validation during import (tests use TEST_DATABASE_URL) DATABASE_URL: "postgresql://test_user:test_password@postgres:5432/wizamart_test" before_script: - pip install uv - uv sync --frozen # Wait for PostgreSQL to be ready - apt-get update && apt-get install -y postgresql-client - for i in $(seq 1 30); do pg_isready -h postgres -U test_user && break || sleep 1; done script: - .venv/bin/python -m pytest tests/ -v --tb=short coverage: '/TOTAL.*\s+(\d+%)/' artifacts: reports: junit: report.xml coverage_report: coverage_format: cobertura path: coverage.xml rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH architecture: stage: test image: python:${PYTHON_VERSION} variables: # Set DATABASE_URL to satisfy validation (not actually used by validator) DATABASE_URL: "postgresql://dummy:dummy@localhost:5432/dummy" before_script: - pip install uv - uv sync --frozen script: - .venv/bin/python scripts/validate/validate_architecture.py rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Security Stage # -------------- dependency_scanning: stage: security image: python:${PYTHON_VERSION} before_script: - pip install pip-audit script: - pip-audit --requirement requirements.txt || true allow_failure: true rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH audit: stage: security image: python:${PYTHON_VERSION} before_script: - pip install uv - uv sync --frozen script: - .venv/bin/python scripts/validate/validate_audit.py allow_failure: true rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Build Stage # ----------- docs: stage: build image: python:${PYTHON_VERSION} before_script: - pip install uv - uv sync --frozen script: - .venv/bin/mkdocs build artifacts: paths: - site/ rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH