Update requirements.txt #92
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 | |
| on: | |
| push: | |
| branches: ["main"] | |
| pull_request: | |
| branches: ["main"] | |
| workflow_dispatch: | |
| jobs: | |
| test-and-scan: | |
| runs-on: ubuntu-latest | |
| env: | |
| PYTHONIOENCODING: "UTF-8" | |
| steps: | |
| - name: Check out code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up Python 3.11 | |
| uses: actions/setup-python@v4 | |
| with: | |
| python-version: "3.11" | |
| cache: pip | |
| - name: Install dependencies & tooling | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -r requirements.txt -r requirements-dev.txt | |
| pip install bandit pytest-cov | |
| - name: Run tests and collect coverage | |
| run: | | |
| pytest --cov=ChatApp --cov=WebSocketChatApp \ | |
| --cov-report=xml:coverage.xml \ | |
| --cov-report=term > coverage.txt | |
| - name: Extract coverage percent | |
| id: extract_coverage | |
| run: | | |
| RATE=$(awk '/^TOTAL/ { gsub("%",""); print $NF }' coverage.txt) | |
| if [ -z "$RATE" ]; then | |
| RATE="0.00" | |
| fi | |
| echo "coverage=$RATE" >> $GITHUB_OUTPUT | |
| - name: Enforce minimum coverage | |
| run: | | |
| RATE="${{ steps.extract_coverage.outputs.coverage }}" | |
| THRESHOLD=70 | |
| if (( $(echo "$RATE < $THRESHOLD" | bc -l) )); then | |
| echo "Coverage $RATE% is below ${THRESHOLD}% – failing build." | |
| exit 1 | |
| fi | |
| - name: Ensure badge folder exists | |
| if: github.ref == 'refs/heads/main' | |
| run: mkdir -p .github/badges | |
| - name: Generate coverage badge | |
| if: github.ref == 'refs/heads/main' | |
| uses: emibcn/badge-action@v1 | |
| with: | |
| label: coverage | |
| status: "${{ steps.extract_coverage.outputs.coverage }}%" | |
| color: green | |
| path: .github/badges/coverage.svg | |
| - name: Commit coverage artefacts | |
| if: github.ref == 'refs/heads/main' | |
| uses: EndBug/add-and-commit@v9 | |
| with: | |
| add: | | |
| coverage.xml | |
| coverage.txt | |
| .github/badges/coverage.svg | |
| message: "chore(ci): update coverage reports & badge [skip ci]" | |
| - name: Run Bandit | |
| run: bandit -r websocket_chatapp -lll -f json -o bandit.json | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v2 | |
| - name: Build Docker image | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| tags: chatapp:test | |
| load: true | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| - name: Scan image with Trivy | |
| id: trivy | |
| uses: aquasecurity/trivy-action@0.31.0 | |
| with: | |
| image-ref: chatapp:test | |
| format: json | |
| output: trivy-image.json | |
| ignore-unfixed: true | |
| exit-code: 0 | |
| - name: Fail on high CVSS | |
| run: | | |
| if jq '.Results[].Vulnerabilities[] | select((.CVSS.nvd.V3Score // 0) > 7)' trivy-image.json | grep -q .; then | |
| exit 1 | |
| fi | |
| - name: Install Gitleaks | |
| run: | | |
| curl -sSL https://github.com/gitleaks/gitleaks/releases/download/v8.24.3/gitleaks_8.24.3_linux_x64.tar.gz -o gitleaks.tar.gz | |
| tar -xzf gitleaks.tar.gz gitleaks | |
| sudo mv gitleaks /usr/local/bin/ | |
| - name: Run Gitleaks | |
| run: gitleaks detect --source . --no-git -c .gitleaks.toml --report-format json --report-path gitleaks.json | |
| - name: Upload security artefacts | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: security-reports | |
| path: | | |
| bandit.json | |
| trivy-image.json | |
| gitleaks.json | |
| coverage.xml | |
| coverage.txt |