Skip to content

Commit 58c75ff

Browse files
authored
Update ci.yml
1 parent c9c4b72 commit 58c75ff

1 file changed

Lines changed: 97 additions & 36 deletions

File tree

.github/workflows/ci.yml

Lines changed: 97 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,95 +2,156 @@ name: CI
22

33
on:
44
push:
5-
branches: ["main"]
5+
branches: [ "main" ]
66
pull_request:
7-
branches: ["main"]
7+
branches: [ "main" ]
88

99
jobs:
1010
test-and-scan:
1111
runs-on: ubuntu-latest
12+
env:
13+
PYTHONIOENCODING: "UTF-8"
1214

1315
steps:
14-
- uses: actions/checkout@v3
15-
16-
- name: Set up Python
17-
uses: actions/setup-python@v3
16+
# ────────────────────────────────
17+
# 1. Check out repository
18+
# ────────────────────────────────
19+
- name: Check out code
20+
uses: actions/checkout@v4
21+
with:
22+
fetch-depth: 0 # full history for accurate lint / blame if needed
23+
24+
# ────────────────────────────────
25+
# 2. Set up Python with cache
26+
# ────────────────────────────────
27+
- name: Set up Python 3.11
28+
id: setup-python
29+
uses: actions/setup-python@v4
1830
with:
19-
python-version: '3.11'
31+
python-version: "3.11"
32+
cache: "pip"
2033

21-
- name: Install dependencies
34+
# ────────────────────────────────
35+
# 3. Install dependencies
36+
# ────────────────────────────────
37+
- name: Install project and security tooling
2238
run: |
39+
echo "::group::Installing dependencies"
2340
python -m pip install --upgrade pip
2441
pip install -r requirements.txt -r requirements-dev.txt
2542
pip install bandit coverage
43+
echo "::endgroup::"
2644
27-
- name: Run tests with coverage
45+
# ────────────────────────────────
46+
# 4. Run tests + coverage
47+
# ────────────────────────────────
48+
- name: Execute tests and collect coverage
2849
run: |
29-
coverage run --source=ChatApp,WebSocketChatApp -m pytest
30-
coverage xml
50+
echo "::group::pytest"
51+
coverage run --source=ChatApp,WebSocketChatApp -m pytest -q
52+
echo "::endgroup::"
53+
coverage xml -o coverage.xml
3154
coverage report -m > coverage.txt
3255
33-
- name: Generate coverage-summary.json
34-
if: github.ref == 'refs/heads/main'
56+
# ────────────────────────────────
57+
# 5. Fail if coverage < 70 %
58+
# (change the threshold as needed)
59+
# ────────────────────────────────
60+
- name: Enforce minimum coverage
3561
run: |
36-
RATE=$(awk '/TOTAL/ {gsub("%",""); printf "%.2f", $4}' coverage.txt)
37-
if [ -z "$RATE" ]; then
38-
echo "Coverage extraction failed. Setting line_rate_pct to 0.00"
39-
RATE=0.00
62+
RATE=$(awk '$1 == "TOTAL" {gsub("%",""); print $(NF)}' coverage.txt)
63+
echo "Total coverage: $RATE %"
64+
THRESHOLD=70
65+
if [ "$(echo "$RATE < $THRESHOLD" | bc -l)" -eq 1 ]; then
66+
echo "Coverage is below ${THRESHOLD}% – failing the build."
67+
exit 1
4068
fi
41-
echo "{ \"line_rate_pct\": $RATE }" > coverage-summary.json
4269
43-
- name: Commit coverage reports
70+
# ────────────────────────────────
71+
# 6. Generate coverage-summary.json (only on main)
72+
# ────────────────────────────────
73+
- name: Generate JSON summary
74+
if: github.ref == 'refs/heads/main'
75+
run: |
76+
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
79+
80+
- name: Commit coverage artefacts
4481
if: github.ref == 'refs/heads/main'
4582
uses: EndBug/add-and-commit@v9
4683
with:
4784
add: |
4885
coverage.xml
4986
coverage-summary.json
50-
message: Update coverage reports [skip ci]
51-
52-
- name: Bandit Scan
53-
run: bandit -r websocket_chatapp -lll -f json -o bandit.json
87+
message: chore(ci): update coverage artefacts [skip ci]
5488

55-
- name: Set up Docker Buildx
89+
# ────────────────────────────────
90+
# 7. Bandit static analysis
91+
# ────────────────────────────────
92+
- name: Run Bandit (SAST)
93+
run: |
94+
echo "::group::Bandit scan"
95+
bandit -r websocket_chatapp -lll -f json -o bandit.json
96+
echo "::endgroup::"
97+
98+
# ────────────────────────────────
99+
# 8. Build Docker image (Buildx + cache)
100+
# ────────────────────────────────
101+
- name: Set up Buildx
56102
uses: docker/setup-buildx-action@v2
57103

58-
- name: Build Docker image
104+
- name: Build application image
59105
uses: docker/build-push-action@v5
60106
with:
61107
context: .
62108
tags: chatapp:test
63109
load: true
64110
cache-from: type=gha
65-
cache-to: type=gha,mode=max
111+
cache-to: type=gha,mode=max
66112

67-
- name: Trivy Image Scan
113+
# ────────────────────────────────
114+
# 9. Trivy image vulnerability scan
115+
# ────────────────────────────────
116+
- name: Scan image with Trivy
68117
id: trivy
69118
uses: aquasecurity/trivy-action@0.31.0
70119
with:
71120
image-ref: chatapp:test
72121
format: json
73122
output: trivy-image.json
74-
ignore-unfixed: true
75-
exit-code: 0
123+
ignore-unfixed: true # suppress non-fixed CVEs
124+
exit-code: 0 # allow post-processing
76125

77-
- name: Fail on CVSS > 7
126+
- name: Fail pipeline if CVSS high/critical
78127
run: |
128+
echo "::group::Evaluating Trivy results"
79129
if jq '.Results[].Vulnerabilities[] | select((.CVSS.nvd.V3Score // 0) > 7)' trivy-image.json | grep -q .; then
80-
echo 'Vulnerabilities with CVSS > 7 found'
130+
echo 'High/critical CVEs detected (CVSS > 7) – failing build.'
81131
exit 1
82132
fi
133+
echo "::endgroup::"
83134
84-
- name: Install gitleaks
135+
# ────────────────────────────────
136+
# 10. Secrets detection with Gitleaks
137+
# ────────────────────────────────
138+
- name: Install Gitleaks
85139
run: |
86140
curl -sSL https://github.com/gitleaks/gitleaks/releases/download/v8.24.3/gitleaks_8.24.3_linux_x64.tar.gz -o gitleaks.tar.gz
87141
tar -xzf gitleaks.tar.gz gitleaks
88142
sudo mv gitleaks /usr/local/bin/
89143
90-
- name: Scan secrets with gitleaks
91-
run: gitleaks detect --source . --no-git -c .gitleaks.toml --report-format=json --report-path=gitleaks.json
92-
93-
- name: Upload artifacts
144+
- name: Scan repository for secrets
145+
run: |
146+
echo "::group::Gitleaks"
147+
gitleaks detect --source . --no-git -c .gitleaks.toml \
148+
--report-format json --report-path gitleaks.json
149+
echo "::endgroup::"
150+
151+
# ────────────────────────────────
152+
# 11. Upload artefacts
153+
# ────────────────────────────────
154+
- name: Publish security artefacts
94155
if: always()
95156
uses: actions/upload-artifact@v4
96157
with:

0 commit comments

Comments
 (0)