refactor: replace Optional[X] with X | None for Python 3.10+ compatib… #9
Workflow file for this run
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
|
Check failure on line 1 in .github/workflows/ci-cd-pipeline.yml
|
||
| name: "🚀 CI/CD Pipeline" | ||
| on: | ||
| push: | ||
| branches: [main, develop] | ||
| pull_request: | ||
| branches: [main, develop] | ||
| workflow_dispatch: | ||
| env: | ||
| PYTHON_VERSION: '3.11' | ||
| POETRY_VERSION: '1.8.0' | ||
| jobs: | ||
| conventional-commits: | ||
| name: "📝 Conventional Commits" | ||
| runs-on: ubuntu-latest | ||
| if: github.event_name == 'pull_request' | ||
| steps: | ||
| - uses: amannn/action-semantic-pull-request@v5 | ||
| env: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| trivy-fs: | ||
| name: "🛡️ Trivy FS Scan" | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Run Trivy filesystem scan (CRITICAL only) | ||
| uses: aquasecurity/trivy-action@0.20.0 | ||
| with: | ||
| scan-type: 'fs' | ||
| scanners: 'vuln,secret,config' | ||
| ignore-unfixed: true | ||
| format: 'table' | ||
| severity: 'CRITICAL' | ||
| exit-code: '1' | ||
| vuln-type: 'os,library' | ||
| limit-severities-for-sarif: true | ||
| hide-progress: true | ||
| continue-on-error: false | ||
| code-quality: | ||
| name: "🎨 Code Quality" | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Set up Python | ||
| uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: ${{ env.PYTHON_VERSION }} | ||
| cache: 'pip' | ||
| - name: Install dependencies | ||
| run: | | ||
| pip install --upgrade pip | ||
| pip install -r requirements.txt | ||
| pip install -r requirements-dev.txt | ||
| - name: Run Ruff (linting) | ||
| run: ruff check app/ --output-format=github | ||
| - name: Run Ruff (formatting check) | ||
| run: ruff format --check app/ | ||
| - name: Run Radon (complexity) | ||
| run: | | ||
| radon cc app/ -a -s -j > radon-cc.json || true | ||
| radon mi app/ -s -j > radon-mi.json || true | ||
| - name: Run Vulture (dead code) | ||
| run: vulture app/ --min-confidence 60 || true | ||
| - name: Run Interrogate (docstring coverage) | ||
| run: interrogate app/ --fail-under 80 || true | ||
| - name: Upload complexity reports | ||
| uses: actions/upload-artifact@v4 | ||
| if: always() | ||
| with: | ||
| name: complexity-reports | ||
| path: radon-*.json | ||
| type-checking: | ||
| name: "🔍 Type Checking" | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Set up Python | ||
| uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: ${{ env.PYTHON_VERSION }} | ||
| cache: 'pip' | ||
| - name: Install dependencies | ||
| run: | | ||
| pip install --upgrade pip | ||
| pip install -r requirements.txt | ||
| pip install -r requirements-dev.txt | ||
| - name: Run MyPy | ||
| run: mypy app/ --junit-xml mypy-report.xml || true | ||
| - name: Upload MyPy report | ||
| uses: actions/upload-artifact@v4 | ||
| if: always() | ||
| with: | ||
| name: mypy-report | ||
| path: mypy-report.xml | ||
| security: | ||
| name: "🔒 Security Scanning" | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Set up Python | ||
| uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: ${{ env.PYTHON_VERSION }} | ||
| cache: 'pip' | ||
| - name: Install dependencies | ||
| run: | | ||
| pip install --upgrade pip | ||
| pip install -r requirements.txt | ||
| pip install -r requirements-dev.txt | ||
| - name: Run Bandit | ||
| run: bandit -r app/ -c .bandit -f json -o bandit-report.json || true | ||
| - name: Run Safety | ||
| run: safety check --json > safety-report.json || true | ||
| - name: Run pip-audit | ||
| run: pip-audit --format json > pip-audit-report.json || true | ||
| - name: Run Semgrep | ||
| run: semgrep --config auto app/ --json > semgrep-report.json || true | ||
| - name: Upload security reports | ||
| uses: actions/upload-artifact@v4 | ||
| if: always() | ||
| with: | ||
| name: security-reports | ||
| path: '*-report.json' | ||
| dependencies: | ||
| name: "📦 Dependency Analysis" | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Set up Python | ||
| uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: ${{ env.PYTHON_VERSION }} | ||
| cache: 'pip' | ||
| - name: Install dependencies | ||
| run: | | ||
| pip install --upgrade pip | ||
| pip install -r requirements.txt | ||
| pip install -r requirements-dev.txt | ||
| - name: Run pipdeptree | ||
| run: pipdeptree --json > pipdeptree.json | ||
| - name: Run deptry | ||
| run: deptry app/ --json-output deptry-report.json || true | ||
| - name: Upload dependency reports | ||
| uses: actions/upload-artifact@v4 | ||
| if: always() | ||
| with: | ||
| name: dependency-reports | ||
| path: '*tree*.json' | ||
| test: | ||
| name: "🧪 Testing" | ||
| runs-on: ubuntu-latest | ||
| strategy: | ||
| matrix: | ||
| python-version: ['3.11', '3.12'] | ||
| steps: | ||
| - 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: | | ||
| pip install --upgrade pip | ||
| pip install -r requirements.txt | ||
| pip install -r requirements-dev.txt | ||
| - name: Run pytest with coverage | ||
| run: | | ||
| pytest --cov=app --cov-report=xml --cov-report=html --cov-report=term-missing --junitxml=test-results.xml | ||
| - name: Upload coverage to Codecov | ||
| uses: codecov/codecov-action@v4 | ||
| if: env.CODECOV_TOKEN != '' | ||
| with: | ||
| file: ./coverage.xml | ||
| flags: unittests | ||
| name: codecov-umbrella | ||
| env: | ||
| CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} | ||
| - name: Upload test results | ||
| uses: actions/upload-artifact@v4 | ||
| if: always() | ||
| with: | ||
| name: test-results-${{ matrix.python-version }} | ||
| path: | | ||
| test-results.xml | ||
| htmlcov/ | ||
| sonarcloud: | ||
| name: "📊 SonarCloud Analysis" | ||
| runs-on: ubuntu-latest | ||
| needs: [test] | ||
| if: env.SONAR_TOKEN != '' | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
| - name: Download test results | ||
| uses: actions/download-artifact@v4 | ||
| with: | ||
| name: test-results-3.11 | ||
| - name: SonarCloud Scan | ||
| uses: SonarSource/sonarcloud-github-action@master | ||
| env: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} | ||
| docker: | ||
| name: "🐳 Docker Build" | ||
| runs-on: ubuntu-latest | ||
| needs: [code-quality, type-checking, security, test] | ||
| if: github.event_name == 'push' | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Set up Docker Buildx | ||
| uses: docker/setup-buildx-action@v3 | ||
| - name: Login to Docker Hub | ||
| if: github.event_name == 'push' | ||
| uses: docker/login-action@v3 | ||
| with: | ||
| username: ${{ secrets.DOCKER_USERNAME }} | ||
| password: ${{ secrets.DOCKER_PASSWORD }} | ||
| - name: Build and push | ||
| if: github.event_name == 'push' | ||
| uses: docker/build-push-action@v5 | ||
| with: | ||
| context: . | ||
| push: true | ||
| tags: | | ||
| ${{ secrets.DOCKER_USERNAME }}/neurobank-fastapi:latest | ||
| ${{ secrets.DOCKER_USERNAME }}/neurobank-fastapi:${{ github.sha }} | ||
| cache-from: type=gha | ||
| cache-to: type=gha,mode=max | ||
| deploy: | ||
| name: "🚂 Deploy to Railway" | ||
| runs-on: ubuntu-latest | ||
| needs: [docker] | ||
| if: github.ref == 'refs/heads/main' && github.event_name == 'push' && secrets.RAILWAY_TOKEN != '' | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Install Railway CLI | ||
| run: npm install -g @railway/cli | ||
| - name: Deploy to Railway | ||
| run: railway up --service neurobank-api | ||
| env: | ||
| RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }} | ||