@@ -13,145 +13,121 @@ jobs:
1313 PYTHONIOENCODING : " UTF-8"
1414
1515 steps :
16- # ────────────────────────────────
17- # 1. Check out repository
18- # ────────────────────────────────
19- - name : Check out code
16+ - name : 🔄 Check out code
2017 uses : actions/checkout@v4
2118 with :
22- fetch-depth : 0 # full history for accurate lint / blame if needed
19+ fetch-depth : 0
2320
24- # ────────────────────────────────
25- # 2. Set up Python with cache
26- # ────────────────────────────────
27- - name : Set up Python 3.11
21+ - name : 🐍 Set up Python 3.11 with cache
2822 id : setup-python
2923 uses : actions/setup-python@v4
3024 with :
3125 python-version : " 3.11"
3226 cache : " pip"
3327
34- # ────────────────────────────────
35- # 3. Install dependencies
36- # ────────────────────────────────
37- - name : Install project and security tooling
28+ - name : 📦 Install dependencies and tooling
3829 run : |
3930 echo "::group::Installing dependencies"
4031 python -m pip install --upgrade pip
4132 pip install -r requirements.txt -r requirements-dev.txt
4233 pip install bandit coverage
4334 echo "::endgroup::"
4435
45- # ────────────────────────────────
46- # 4. Run tests + coverage
47- # ────────────────────────────────
48- - name : Execute tests and collect coverage
36+ - name : 🧪 Run tests and collect coverage
4937 run : |
5038 echo "::group::pytest"
5139 coverage run --source=ChatApp,WebSocketChatApp -m pytest -q
5240 echo "::endgroup::"
5341 coverage xml -o coverage.xml
5442 coverage report -m > coverage.txt
5543
56- # ────────────────────────────────
57- # 5. Fail if coverage < 70 %
58- # (change the threshold as needed)
59- # ────────────────────────────────
60- - name : Enforce minimum coverage
44+ - name : ✅ Enforce minimum test coverage
6145 run : |
6246 RATE=$(awk '$1 == "TOTAL" {gsub("%",""); print $(NF)}' coverage.txt)
63- echo "Total coverage: $RATE %"
47+ echo "📊 Total test coverage: $RATE%"
6448 THRESHOLD=70
6549 if [ "$(echo "$RATE < $THRESHOLD" | bc -l)" -eq 1 ]; then
66- echo "Coverage is below ${THRESHOLD}% – failing the build."
50+ echo "❌ Coverage is below ${THRESHOLD}% – failing the build."
6751 exit 1
6852 fi
6953
70- # ────────────────────────────────
71- # 6. Generate coverage-summary.json (only on main)
72- # ────────────────────────────────
73- - name : Generate JSON summary
54+ - name : 📤 Extract coverage percent for badge
55+ id : get_coverage
7456 if : github.ref == 'refs/heads/main'
7557 run : |
7658 RATE=$(awk '$1 == "TOTAL" {gsub("%",""); printf "%.2f", $(NF)}' coverage.txt)
77- printf '{ "line_rate_pct": %.2f }\n' "$RATE" > coverage-summary.json
78- cat coverage-summary.json
59+ echo "coverage=$RATE" >> $GITHUB_OUTPUT
7960
80- - name : Commit coverage artefacts
61+ - name : 🏷️ Generate coverage badge
62+ if : github.ref == 'refs/heads/main'
63+ uses : emibcn/badge-action@v1
64+ with :
65+ label : coverage
66+ status : " ${{ steps.get_coverage.outputs.coverage }}%"
67+ color : green
68+ path : .github/badges/coverage.svg
69+
70+ - name : 💾 Commit coverage reports and badge
8171 if : github.ref == 'refs/heads/main'
8272 uses : EndBug/add-and-commit@v9
8373 with :
8474 add : |
8575 coverage.xml
86- coverage-summary.json
87- message : chore(ci): update coverage artefacts [skip ci]
76+ coverage.txt
77+ .github/badges/coverage.svg
78+ message : chore(ci): update test coverage badge and report [skip ci]
8879
89- # ────────────────────────────────
90- # 7. Bandit static analysis
91- # ────────────────────────────────
92- - name : Run Bandit (SAST)
80+ - name : 🛡️ Bandit Static Analysis (SAST)
9381 run : |
9482 echo "::group::Bandit scan"
9583 bandit -r websocket_chatapp -lll -f json -o bandit.json
9684 echo "::endgroup::"
9785
98- # ────────────────────────────────
99- # 8. Build Docker image (Buildx + cache)
100- # ────────────────────────────────
101- - name : Set up Buildx
86+ - name : 🐳 Set up Docker Buildx
10287 uses : docker/setup-buildx-action@v2
10388
104- - name : Build application image
89+ - name : 🏗️ Build Docker Image
10590 uses : docker/build-push-action@v5
10691 with :
10792 context : .
10893 tags : chatapp:test
10994 load : true
11095 cache-from : type=gha
111- cache-to : type=gha,mode=max
96+ cache-to : type=gha,mode=max
11297
113- # ────────────────────────────────
114- # 9. Trivy image vulnerability scan
115- # ────────────────────────────────
116- - name : Scan image with Trivy
98+ - name : 🔍 Scan Docker Image (Trivy)
11799 id : trivy
118100 uses : aquasecurity/trivy-action@0.31.0
119101 with :
120102 image-ref : chatapp:test
121103 format : json
122104 output : trivy-image.json
123- ignore-unfixed : true # suppress non-fixed CVEs
124- exit-code : 0 # allow post-processing
105+ ignore-unfixed : true
106+ exit-code : 0
125107
126- - name : Fail pipeline if CVSS high/critical
108+ - name : 🚨 Fail on High CVSS (Trivy)
127109 run : |
128110 echo "::group::Evaluating Trivy results"
129111 if jq '.Results[].Vulnerabilities[] | select((.CVSS.nvd.V3Score // 0) > 7)' trivy-image.json | grep -q .; then
130- echo 'High/critical CVEs detected (CVSS > 7) – failing build.'
112+ echo '❌ High/critical CVEs detected – failing build.'
131113 exit 1
132114 fi
133115 echo "::endgroup::"
134116
135- # ────────────────────────────────
136- # 10. Secrets detection with Gitleaks
137- # ────────────────────────────────
138- - name : Install Gitleaks
117+ - name : 🔐 Install Gitleaks
139118 run : |
140119 curl -sSL https://github.com/gitleaks/gitleaks/releases/download/v8.24.3/gitleaks_8.24.3_linux_x64.tar.gz -o gitleaks.tar.gz
141120 tar -xzf gitleaks.tar.gz gitleaks
142121 sudo mv gitleaks /usr/local/bin/
143122
144- - name : Scan repository for secrets
123+ - name : 🔍 Secret scan with Gitleaks
145124 run : |
146125 echo "::group::Gitleaks"
147126 gitleaks detect --source . --no-git -c .gitleaks.toml \
148127 --report-format json --report-path gitleaks.json
149128 echo "::endgroup::"
150129
151- # ────────────────────────────────
152- # 11. Upload artefacts
153- # ────────────────────────────────
154- - name : Publish security artefacts
130+ - name : ☁️ Upload Security Artifacts
155131 if : always()
156132 uses : actions/upload-artifact@v4
157133 with :
0 commit comments