Repository navigation
ci(sonar): scan on SonarQube Cloud, and fix what its first scan found - #45
Merged
Merged
Conversation
The scan ran only when someone remembered to run `make sonar` against the internal server, and both of its inputs failed silently when forgotten. It now runs from .github/workflows/sonar.yml on every push to master and every same-repo pull request, generating coverage on the scanned checkout and passing sonar.projectVersion from the latest v* tag (failing without one). It uses a full-depth checkout so tags and blame are present. A token job skips the scan when SONAR_TOKEN is unavailable (fork and Dependabot PRs, or before the secret is configured) instead of failing it. The scan action is pinned to a full SHA. make cover now succeeds on toolchains fetched by GOTOOLCHAIN. cmd/koc, the one package without a test, sent -coverpkg through `go tool covdata`, which those toolchains do not ship, so the run exited 1 and the old sonar target never started. It also merges the repeats -coverpkg writes: each block once per test binary, 818k lines collapsed to 23k. The total is unchanged at 76.3%. AGENTS.md documents the one-time SonarQube Cloud setup and a new "Where checks run (agent sessions)" section with measured costs. Vet, the changed packages' tests, the full unit suite (~45 s) and Go 1.27's gofmt run in the session. Lint, race, crossbuild, coverage and the scan run on GitHub. This is because a cloud session's own golangci-lint and gofmt are older than the pinned ones. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XTGXtL5ssZ9bTDz3dHc2PY
An agent reads the result of its own push before moving on, and a change to sonar.yml can only be proved on a branch: workflow_dispatch reaches a workflow only once it is on master. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XTGXtL5ssZ9bTDz3dHc2PY
In the embedded profile without KOC_HOME, koc uses the fixed $TMPDIR/koc-home. A relative KOC_SCOPE_FILE, KOC_HISTORY_FILE or KOC_AUDIT_FILE resolves inside it, and the audit log is opened with O_CREATE|O_APPEND. On a host with a shared /tmp, another user could create that directory first and plant the scope file koc reads (a token and an endpoint), or symlink the audit log at a file the victim owns. koc now creates the directory itself, 0700, before any command runs. It refuses one that is not a real directory (a symlink or a file), belongs to another user, or is writable by group or others, and names KOC_HOME as the way out. A KOC_HOME the host names is trusted as before. Outside Unix the temporary directory is already per-user, so only the symlink/file check applies. Found by SonarQube Cloud (go:S5445). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XTGXtL5ssZ9bTDz3dHc2PY
TestRunStopsOnContextCancel, TestRepaintEntersAndLeavesTheAlternateScreenExactlyOnce and TestDoStopsOnContextCancellation cancel only from inside a callback, so a run that fails before the callback fires leaks the context. Defer the cancel as well; calling it twice is harmless. Found by SonarQube Cloud (godre:S8188). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XTGXtL5ssZ9bTDz3dHc2PY
The checksum check already catches a swapped tarball, but only because checksums.txt comes over the same connection; --proto '=https' and --tlsv1.2 keep a redirect from moving either download off TLS. Found by SonarQube Cloud (githubactions:S6506). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XTGXtL5ssZ9bTDz3dHc2PY
…ompat.sh Both are bash scripts. Every converted test is -n, -z, -d or -eq, where [[ behaves the same as [ but cannot be broken by word splitting. release-notes.sh prints byte-identical notes for v0.41.0, v0.42.0 and an unreleased HEAD before and after. Found by SonarQube Cloud (shelldre:S7688). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XTGXtL5ssZ9bTDz3dHc2PY
--only-binary :all: keeps the GitHub-runner workaround from ever running a source distribution's setup script while upgrading pip. Found by SonarQube Cloud (shell:S8541). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XTGXtL5ssZ9bTDz3dHc2PY
The quality gate measured 69% coverage on the new code against its 80% threshold. Add the paths the first tests skipped: checkEmbedded returning the refusal, a home that cannot be created, and a directory owned by another user (through a FileInfo whose Stat_t names a different uid, so no root is needed). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XTGXtL5ssZ9bTDz3dHc2PY
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



What
SonarQube Cloud from CI (
b628a45,933fde8).github/workflows/sonar.yml— SonarQube Cloud scan on every push tomasterandclaude/**, on same-repo pull requests, and onworkflow_dispatch. It is network-allowed and never a dependency of the offlineci.ymljobs.coverage.outon the checkout it scans (make cover, run offline fromvendor/).sonar.projectVersionfrom the latestv*tag and fails without one. Checks out full history, so tags and blame are present.tokenjob skips the scan with a notice whenSONAR_TOKENis unavailable (fork and Dependabot PRs), instead of failing.v8.3.0).make covernow works on toolchains fetched byGOTOOLCHAIN.cmd/kochad no test, and-coverpkgsent it throughgo tool covdata, which those toolchains do not ship, so the run exited 1.cmd/koc/main_test.gofixes that.-coverpkgrepeats once per test binary: 818k lines become 23k, and the total stays at 76.3%.make sonar(the local podman scan against the internal server) is removed.sonar-project.propertiesnow names the SonarQube Cloud organization and key.Fixes for the first scan's findings (
ecff572..3f1c2e3)fix(kochome): refuse an embedded home another local user could controlgo:S5445(critical)$TMPDIR/koc-homeis now created by koc,0700. A symlink, a file, another user's directory, or a group/world-writable one is refused with a pointer toKOC_HOME. On a shared/tmpanother user could otherwise plant the scope file or redirect the audit log. Unit tests, plus an end-to-end run of the binary for each case;docs/shell.mdupdated.test: cancel the contexts three tests creategodre:S8188×3defer cancel().ci(lint): refuse a plain-HTTP redirect when downloading golangci-lintgithubactions:S6506×2--proto '=https' --tlsv1.2.build(scripts): use [[ ]] for the tests in release-notes.sh and api-compat.shshelldre:S7688×9ci(devstack): install pip from a wheel only on the runnershell:S8541--only-binary :all:. This push triggers the devstack functional run.Not changed, to be accepted in the SonarQube Cloud UI:
go:S4507—--debugis an opt-in operator flag that already redacts secrets.githubactions:S8545×2 —go install …@<exact version>is verified against the checksum database and resolved from the tool's owngo.mod.shell:S5332— plainhttp://to swift on a local devstack, which has no TLS.The 14 findings under
vendor/came from the earlier Automatic Analysis, which ignoredsonar-project.properties. The CI scan excludesvendor/, so they disappear frommasteronce this merges.Verified
933fde8:ci,supply-chain,sonar, CodeQL, and the SonarQube Cloud PR analysis.sonarrun (re-run after Automatic Analysis was turned off) saw the token, resolvedv0.42.0, loadedcoverage.outwith no unresolved files, and the scan succeeded.3f1c2e3:go vet ./...and the fullgo test ./...pass.make coverexits 0, 76.3%.Merge
Please use rebase or fast-forward rather than squash, so each Conventional Commit subject becomes its own release-notes bullet. Merging to
mastergives SonarQube Cloud its first CI-based main-branch analysis, the baseline later branch and PR analyses compare against.🤖 Generated with Claude Code
https://claude.ai/code/session_01XTGXtL5ssZ9bTDz3dHc2PY