Skip to content

👷 ci(sonar): enforce the SonarCloud quality gate in CI - #20

Merged
konih merged 1 commit into
mainfrom
lane/sonar-required-gate
Aug 6, 2026
Merged

👷 ci(sonar): enforce the SonarCloud quality gate in CI#20
konih merged 1 commit into
mainfrom
lane/sonar-required-gate

Conversation

@konih

@konih konih commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

What

  • Removes continue-on-error: true from the sonarqube job in ci.yaml.
  • Adds sonar.qualitygate.wait=true to sonar-project.properties.
  • Adds guard hack/test/sonar_blocking_gate_test.sh, and wires all hack/test/*.sh into task check via a new guards task.

Why

OD-3 made the Sonar gate non-blocking so an ERROR gate could not veto the lanes (E4-S01, E4-S02) remediating it, with an explicit instruction to revisit once it went green. It went green on 2026-08-06:

Condition Before Now
new_duplicated_lines_density ERROR 4.6 OK 0.0
new_coverage not reported OK 93.6
reliability / security / maintainability OK 1 OK 1
new_security_hotspots_reviewed OK 100 OK 100

The earlier diagnosis was wrong: the ERROR was not residual duplication. SonarCloud Automatic Analysis was enabled, which is mutually exclusive with CI analysis (scanner exit 3 every run) and ignores sonar-project.properties — so E4-S02's test exclusions had never been applied and the figure was frozen on a stale baseline.

Two holes, not one

The first revision of this PR removed only continue-on-error and claimed in its subject that the gate was blocking. That was false, and an independent review caught it: sonarqube-scan-action is fire-and-forget, so the job went green on upload and an ERROR gate would still have failed nothing. Both halves are needed:

  1. no continue-on-error → a scanner failure fails the job (this is what hid the exit 3 for a day);
  2. sonar.qualitygate.wait=true → an ERROR quality gate fails the job.

Guards were never run

grep -rn 'hack/test' across Taskfile.yml and .github/workflows/ returned nothing: ten regression guards existed and nothing executed them, so every "guarded by …" claim in this repo was aspirational. Now wired into task check.

Evidence

  • Failing-first: guard run against a clean origin/main tree → RED on both assertions (continue-on-error: true still present, sonar.qualitygate.wait=true missing); GREEN on this branch.
  • task check exit 0 — coverage 92.4% (floor 90), gitleaks no leaks, pinned-actions ok (35 refs), 10/10 guards ok.

Risk

Fork and Dependabot PRs receive no secrets → the existing SONAR_TOKEN gate makes the scan step self-skip rather than fail. The real, accepted cost: CI for in-repo branches now hard-couples to sonarcloud.io availability — a transient outage or flaky download-artifact reds the PR where it was previously swallowed.

Not in scope

main has no branch protection and no rulesets (404 / []), so "blocking" means "the workflow goes red", not "the merge is prevented". Making sonarqube a required check is a separate governance decision — raised in the INBOX for the operator.

@codecov

codecov Bot commented Aug 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

OD-3 set continue-on-error on the sonarqube job so an ERROR quality gate could
not veto the very lanes (E4-S01, E4-S02) that were remediating it, with an
explicit instruction to revisit once the gate went green. It went OK on
2026-08-06 after Automatic Analysis was disabled and CI analysis actually ran
(new_duplicated_lines_density 4.6 -> 0.0, new_coverage 93.6).

Two independent holes had to close, since either alone is a false sense of
safety:

  - continue-on-error swallowed hard scanner failures. It hid an exit 3
    ("running CI analysis while Automatic Analysis is enabled") for a full day
    while the workflow reported success.
  - the scan was fire-and-forget. Without sonar.qualitygate.wait the job went
    green the moment the report was uploaded, so a gate flipping to ERROR would
    never have failed anything. An earlier revision of this commit removed only
    the first and claimed the gate was blocking; that claim was false.

Also wires hack/test/*.sh into task check via a new guards task. Ten config
regression guards existed but nothing ever ran them, so "guarded by" was
aspirational across the whole repo.

Fork PRs receive no secrets, so the scan step self-skips via the SONAR_TOKEN
gate rather than failing. The real cost is that CI now hard-couples to
sonarcloud.io availability for in-repo branches; that is the intended trade.
@konih
konih force-pushed the lane/sonar-required-gate branch from 92f44ec to 1b83a68 Compare August 6, 2026 14:32
@konih konih changed the title 👷 ci(sonar): make SonarCloud gate blocking 👷 ci(sonar): enforce the SonarCloud quality gate in CI Aug 6, 2026
@sonarqubecloud

sonarqubecloud Bot commented Aug 6, 2026

Copy link
Copy Markdown

@konih
konih merged commit 022d50d into main Aug 6, 2026
11 checks passed
@konih
konih deleted the lane/sonar-required-gate branch August 6, 2026 14:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant