name: CI/CD Pipeline on: push: branches: [main, develop] pull_request: branches: [main, develop] env: PYTHONUNBUFFERED: "1" HAIM_API_KEY: "ci-test-key-not-for-production" HAIM_DIMENSIONALITY: "1024" HAIM_ENCODING_MODE: "binary" jobs: # =========================================================================== # LINT JOB - Code Quality Checks # =========================================================================== lint: name: Lint & Format Check runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.11" cache: 'pip' - name: Install dependencies run: | python -m pip install --upgrade pip pip install black isort flake8 mypy - name: Run Black (code formatter check) run: black --check --diff src/ tests/ - name: Run isort (import sorter check) run: isort --check-only --diff src/ tests/ - name: Run flake8 (style guide enforcement) run: flake8 src/ tests/ --max-line-length=120 --extend-ignore=E203,W503 - name: Run mypy (static type checker) run: mypy src/ --ignore-missing-imports --no-strict-optional continue-on-error: true # Non-blocking until type coverage improves # =========================================================================== # TEST JOB - Unit & Integration Tests with Coverage # =========================================================================== test: name: Test (Python ${{ matrix.python-version }}) runs-on: ubuntu-latest needs: lint strategy: fail-fast: false matrix: python-version: ["3.10", "3.11", "3.12"] services: redis: image: redis:7-alpine ports: - 6379:6379 options: >- --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5 steps: - name: Checkout repository uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} cache: 'pip' - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt pip install -r requirements-dev.txt pip install hypothesis fakeredis - name: Create required directories run: mkdir -p data - name: Run tests with coverage env: REDIS_URL: redis://localhost:6379 HAIM_API_KEY: ${{ env.HAIM_API_KEY }} HAIM_DIMENSIONALITY: ${{ env.HAIM_DIMENSIONALITY }} HAIM_ENCODING_MODE: ${{ env.HAIM_ENCODING_MODE }} run: | pytest tests/ \ -m "not integration" \ --cov=src \ --cov-report=xml \ --cov-report=term-missing \ --cov-fail-under=60 \ --tb=short \ -v - name: Upload coverage to Codecov if: matrix.python-version == '3.11' uses: codecov/codecov-action@v4 with: files: ./coverage.xml fail_ci_if_error: false verbose: true env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} # =========================================================================== # SECURITY JOB - Dependency & Code Security Scanning # =========================================================================== security: name: Security Scan runs-on: ubuntu-latest needs: lint steps: - name: Checkout repository uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.11" cache: 'pip' - name: Install dependencies run: | python -m pip install --upgrade pip pip install pip-audit bandit - name: Run pip-audit (dependency vulnerability scan) run: pip-audit -r requirements.txt continue-on-error: true - name: Run Bandit (code security analysis) run: bandit -r src/ -ll --skip B101,B601 continue-on-error: true # =========================================================================== # PROPERTY-BASED TESTS - Hypothesis # =========================================================================== property-tests: name: Property-Based Tests (Hypothesis) runs-on: ubuntu-latest needs: lint steps: - name: Checkout repository uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.11" cache: 'pip' - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt pip install hypothesis pytest pytest-asyncio - name: Run property-based tests env: HAIM_API_KEY: ${{ env.HAIM_API_KEY }} HAIM_DIMENSIONALITY: ${{ env.HAIM_DIMENSIONALITY }} run: | pytest tests/test_binary_hdv_properties.py \ -v \ --tb=short # =========================================================================== # DOCKER BUILD - Validate image builds correctly # =========================================================================== docker: name: Docker Build runs-on: ubuntu-latest needs: [lint] steps: - name: Checkout repository uses: actions/checkout@v4 - name: Build Docker image run: docker build -t mnemocore:ci-${{ github.sha }} . - name: Verify Python imports work in image run: | docker run --rm \ -e HAIM_API_KEY=ci-test-key \ mnemocore:ci-${{ github.sha }} \ python -c "from src.core.engine import HAIMEngine; print('Import OK')" # =========================================================================== # BUILD STATUS - Summary Job # =========================================================================== build-status: name: Build Status runs-on: ubuntu-latest needs: [lint, test, security, property-tests, docker] if: always() steps: - name: Check build status run: | if [[ "${{ needs.test.result }}" == "failure" ]]; then echo "Tests failed!" exit 1 fi if [[ "${{ needs.lint.result }}" == "failure" ]]; then echo "Lint checks failed!" exit 1 fi echo "All checks passed!"