CI/CD Pipeline #17
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: CI/CD Pipeline | |
| on: | |
| push: | |
| branches: [ main, develop ] | |
| pull_request: | |
| branches: [ main, develop ] | |
| schedule: | |
| # Run daily at 00:00 UTC | |
| - cron: '0 0 * * *' | |
| workflow_dispatch: | |
| jobs: | |
| lint: | |
| name: Code Quality (Linting) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: '3.11' | |
| - name: Cache pip dependencies | |
| uses: actions/cache@v3 | |
| with: | |
| path: ~/.cache/pip | |
| key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pip- | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install black flake8 mypy | |
| pip install -r requirements.txt | |
| - name: Run Black (code formatting check) | |
| run: black --check . | |
| - name: Run Flake8 (linting) | |
| run: flake8 . | |
| - name: Run MyPy (type checking) | |
| run: mypy . --ignore-missing-imports | |
| continue-on-error: true # Don't fail build on type errors (warning only) | |
| test: | |
| name: Tests (Python ${{ matrix.python-version }}) | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, windows-latest] | |
| python-version: ['3.10', '3.11', '3.12'] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Cache pip dependencies | |
| uses: actions/cache@v3 | |
| with: | |
| path: ~/.cache/pip | |
| key: ${{ runner.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('requirements.txt') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pip-${{ matrix.python-version }}- | |
| ${{ runner.os }}-pip- | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -r requirements.txt | |
| - name: Run unit tests | |
| run: pytest tests/unit -v --cov=core --cov=utils --cov=handlers --cov-report=xml --cov-report=term | |
| - name: Run security tests | |
| run: pytest -m security -v | |
| - name: Upload coverage to Codecov | |
| if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.11' | |
| uses: codecov/codecov-action@v3 | |
| with: | |
| file: ./coverage.xml | |
| flags: unittests | |
| name: codecov-umbrella | |
| fail_ci_if_error: false | |
| security-scan: | |
| name: Security Scanning | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: '3.11' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install safety bandit | |
| pip install -r requirements.txt | |
| - name: Run Safety (dependency vulnerability check) | |
| run: safety check --json | |
| continue-on-error: true | |
| - name: Run Bandit (security linter) | |
| run: bandit -r . -f json -o bandit-report.json | |
| continue-on-error: true | |
| - name: Upload Bandit report | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: bandit-security-report | |
| path: bandit-report.json | |
| docker-build: | |
| name: Docker Build Test | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Build Docker image | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| push: false | |
| load: true | |
| tags: mediabutler:test | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| - name: Test Docker image | |
| run: | | |
| docker run --rm mediabutler:test python --version | |
| docker run --rm mediabutler:test pip list | |
| integration-test: | |
| name: Integration Tests | |
| runs-on: ubuntu-latest | |
| needs: [test] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: '3.11' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -r requirements.txt | |
| - name: Run integration tests | |
| run: pytest tests/integration -v | |
| continue-on-error: true # Integration tests may fail if external services unavailable | |
| frontend-test: | |
| name: Frontend Tests | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| working-directory: web/frontend | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '18' | |
| cache: 'npm' | |
| cache-dependency-path: web/frontend/package-lock.json | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Run ESLint | |
| run: npm run lint | |
| - name: Build frontend | |
| run: npm run build | |
| summary: | |
| name: Build Summary | |
| runs-on: ubuntu-latest | |
| needs: [lint, test, security-scan, docker-build, frontend-test] | |
| if: always() | |
| steps: | |
| - name: Check build status | |
| run: | | |
| echo "### CI/CD Pipeline Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "- Lint: ${{ needs.lint.result }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- Tests: ${{ needs.test.result }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- Security: ${{ needs.security-scan.result }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- Docker: ${{ needs.docker-build.result }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- Frontend: ${{ needs.frontend-test.result }}" >> $GITHUB_STEP_SUMMARY |