|
| 1 | +# SonarCloud |
| 2 | + |
| 3 | +SonarCloud runs on every PR via GitHub Actions. The project key is |
| 4 | +`hypercerts-org_ePDS`. Use the public API to check results — no |
| 5 | +authentication required for public projects. |
| 6 | + |
| 7 | +```bash |
| 8 | +# Quality gate status for a PR |
| 9 | +curl -s "https://sonarcloud.io/api/qualitygates/project_status?projectKey=hypercerts-org_ePDS&pullRequest=<N>" | python3 -m json.tool |
| 10 | + |
| 11 | +# List new bugs on a PR |
| 12 | +curl -s "https://sonarcloud.io/api/issues/search?componentKeys=hypercerts-org_ePDS&pullRequest=<N>&types=BUG&resolved=false" | python3 -c " |
| 13 | +import sys,json |
| 14 | +for i in json.load(sys.stdin).get('issues',[]): |
| 15 | + print(f'{i[\"component\"].split(\":\")[-1]}:{i.get(\"line\",\"?\")} — {i[\"message\"]}')" |
| 16 | + |
| 17 | +# List all new issues (bugs, code smells, vulnerabilities) |
| 18 | +curl -s "https://sonarcloud.io/api/issues/search?componentKeys=hypercerts-org_ePDS&pullRequest=<N>&resolved=false&ps=50" | python3 -c " |
| 19 | +import sys,json |
| 20 | +for i in json.load(sys.stdin).get('issues',[]): |
| 21 | + print(f'{i[\"type\"]:15} {i[\"component\"].split(\":\")[-1]}:{i.get(\"line\",\"?\")} — {i[\"message\"]}')" |
| 22 | + |
| 23 | +# Duplication on new code |
| 24 | +curl -s "https://sonarcloud.io/api/measures/component?component=hypercerts-org_ePDS&pullRequest=<N>&metricKeys=new_duplicated_lines_density" | python3 -m json.tool |
| 25 | + |
| 26 | +# Security hotspots |
| 27 | +curl -s "https://sonarcloud.io/api/hotspots/search?projectKey=hypercerts-org_ePDS&pullRequest=<N>" | python3 -c " |
| 28 | +import sys,json |
| 29 | +for h in json.load(sys.stdin).get('hotspots',[]): |
| 30 | + print(f'{h[\"component\"].split(\":\")[-1]}:{h.get(\"line\",\"?\")} — {h[\"message\"]}')" |
| 31 | +``` |
| 32 | + |
| 33 | +## Quality gate thresholds |
| 34 | + |
| 35 | +On new code: reliability A (no bugs), security A, maintainability A, |
| 36 | +duplication < 3%, and 100% of security hotspots reviewed. Fix any |
| 37 | +issues before merging. |
| 38 | + |
| 39 | +## NOSONAR annotations |
| 40 | + |
| 41 | +When Sonar flags a line as a false positive (security hotspot, bug, |
| 42 | +or code smell that is intentional), add `// NOSONAR` at the end of |
| 43 | +the line with a brief reason: |
| 44 | + |
| 45 | +```ts |
| 46 | +['http://', 'http://example.com/data.json', /only https/i], // NOSONAR — testing SSRF guard |
| 47 | +['private 10.x', 'https://10.0.0.1/path'], // NOSONAR — testing SSRF guard |
| 48 | +const html = `<script>${userCode}</script>` // NOSONAR — sanitised by escapeHtml() above |
| 49 | +``` |
| 50 | + |
| 51 | +Common cases: test data with private IPs or `http://` URLs, |
| 52 | +intentional use of patterns Sonar considers risky (inline scripts, |
| 53 | +hardcoded credentials in test fixtures, etc.). |
| 54 | + |
| 55 | +**Do not use NOSONAR to suppress legitimate issues.** Every |
| 56 | +annotation must have a reason that explains why the flagged pattern |
| 57 | +is safe in this specific context. If you can't articulate why it's |
| 58 | +a false positive, fix the code instead. |
0 commit comments