Context
Stage: Deployment branch (merge to main / staging / prod)
Tool: sonarqube
Scope: Application source code — all languages supported by SonarQube (30+)
Parent: (see SAST parent issue)
IaC and Helm/Kustomize are out of scope for Step 4 SAST. SonarQube has partial Terraform/CF support but Step 17 (checkov) is the designated IaC security scanner.
Why sonarqube at deployment branch
codeql (#19) provides deep semantic analysis on every PR. SonarQube serves a different function at the deployment branch stage:
- Quality gate: a named pass/fail threshold (coverage %, new bugs, new code smells, new security hotspots) that must be green before a branch is considered promotable to production
- Historical trend analysis: tracks code quality and security debt over time across all branches — identifies regressions introduced between releases
- PR decoration: posts a summary comment on the PR with the delta (new issues introduced by this PR) even when the PR scan is run by codeql
- 30+ language support: same SonarQube server instance covers the full Sparkgeo stack without per-language configuration
codeql does not provide quality gates or trend dashboards — it surfaces findings per scan without aggregation. SonarQube fills that gap. Together they provide: deep semantic analysis (codeql) + quality gate enforcement + longitudinal visibility (SonarQube).
Infrastructure prerequisite
SonarQube Community Edition (free, self-hosted) must be deployed before consuming repos can use this workflow. Deploy once per organisation:
# Recommended: SonarQube via Helm on the existing EKS cluster
helm repo add sonarqube https://SonarSource.github.io/helm-chart-sonarqube
helm upgrade --install sonarqube sonarqube/sonarqube \
--namespace sonarqube --create-namespace \
--set sonarqube.edition=community
Store the following as GitHub org secrets / variables once SonarQube is deployed:
SONAR_HOST_URL (org variable): SonarQube server URL
SONAR_TOKEN (org secret): analysis token scoped to the project
Reusable workflow — sast-gate.yml
name: SAST Gate
on:
workflow_call:
inputs:
project-key:
description: 'SonarQube project key (unique per repo)'
required: true
type: string
sources:
description: 'Comma-separated source directories to analyse'
default: '.'
type: string
quality-gate-wait:
description: 'Block until Quality Gate result is available'
default: true
type: boolean
secrets:
SONAR_TOKEN:
required: true
SONAR_HOST_URL:
required: true
Consuming repo usage
# .github/workflows/sast-gate.yml
name: SAST Gate
on:
push:
branches: [main, staging]
jobs:
sonarqube:
uses: sparkgeo/github-actions/.github/workflows/sast-gate.yml@main
with:
project-key: prescient-platform-api
secrets:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ vars.SONAR_HOST_URL }}
sonar-project.properties (in consuming repo root)
sonar.projectKey=prescient-platform-api
sonar.projectName=Prescient Platform API
sonar.sources=src
sonar.tests=tests
sonar.python.coverage.reportPaths=coverage.xml
Quality gate configuration (recommended baseline)
Configure in SonarQube UI under Administration → Quality Gates:
| Condition |
Threshold |
Blocks deploy |
| New security hotspots reviewed |
100% |
Yes |
| New bugs |
0 |
Yes |
| New code coverage |
≥ 80% |
Yes |
| New duplicated lines |
< 3% |
No (warning) |
Relationship to codeql (#19)
|
codeql (#19) |
sonarqube (#20) |
| Trigger |
Every PR |
Merge to deployment branch |
| Analysis type |
Deep data-flow / taint analysis |
Pattern-based + quality metrics |
| Output |
Inline PR annotations via SARIF |
Quality gate pass/fail + trend dashboard |
| Infrastructure |
Zero (GitHub-hosted) |
Self-hosted SonarQube server |
| Best for |
Catching semantic vulnerabilities at PR |
Enforcing quality gates before promotion + tracking debt over time |
Context
Stage: Deployment branch (merge to
main/staging/prod)Tool:
sonarqubeScope: Application source code — all languages supported by SonarQube (30+)
Parent: (see SAST parent issue)
Why sonarqube at deployment branch
codeql(#19) provides deep semantic analysis on every PR. SonarQube serves a different function at the deployment branch stage:codeqldoes not provide quality gates or trend dashboards — it surfaces findings per scan without aggregation. SonarQube fills that gap. Together they provide: deep semantic analysis (codeql) + quality gate enforcement + longitudinal visibility (SonarQube).Infrastructure prerequisite
SonarQube Community Edition (free, self-hosted) must be deployed before consuming repos can use this workflow. Deploy once per organisation:
Store the following as GitHub org secrets / variables once SonarQube is deployed:
SONAR_HOST_URL(org variable): SonarQube server URLSONAR_TOKEN(org secret): analysis token scoped to the projectReusable workflow —
sast-gate.ymlConsuming repo usage
sonar-project.properties(in consuming repo root)Quality gate configuration (recommended baseline)
Configure in SonarQube UI under Administration → Quality Gates:
Relationship to codeql (#19)