Commit f70349ad3c

f70349ad3c66108bf649b79d29997a89897ae780

parent: 6df734dd58

Verified · cmc ci/build: success ci/sonar: success ci/test: success ci/vuln: success

cmc <hello@cleberg.net> · 2026-09-04 19:34 UTC

ci: SonarCloud static analysis, report-only

A second static-analysis pass alongside vuln, from the security sweep.

Report-only on purpose: the scan ends in `|| true`, so a first run
against an existing codebase does not turn every build red before anyone
has read what it says. Dropping the `|| true` makes the quality gate
binding.

Three things the vendor's snippet does not survive here:

Each step runs in its own `sh -c`, so the snippet's three exports would
not reach the scanner. It is one step.

A merge request from a fork is built without secrets by design, so
SONAR_TOKEN is absent there. Without a guard every outside contribution
would fail on a missing credential; the step says why it is skipping and
exits 0.

The snippet re-downloads ~50MB per run. The scanner is cached under the
runner's home and only fetched when the binary is not already there.

Only SONAR_TOKEN is secret: it is a build secret, set over SSH with the
value on stdin, and never reaches argv, logs or this file. The
organization, project key and host URL are public configuration and live
in sonar-project.properties so a scan is reproducible from the
repository alone.

Coverage is deliberately not reported. Most of this repository's
coverage comes from the e2e suite, and re-running it under -coverprofile
would double CI time; unit-only coverage would report misleadingly low
numbers for packages e2e exercises heavily.

Ref #149

Layout: unified · split

.gitbay/ci.yml +32
@@ -23,3 +23,35 @@ jobs:
23 vuln: 23 vuln:
24 steps: 24 steps:
25 - go run golang.org/x/vuln/cmd/govulncheck@latest ./... 25 - go run golang.org/x/vuln/cmd/govulncheck@latest ./...
26 # SonarCloud static analysis. Report-only: unlike vuln this does not
27 # gate, so a first scan of an existing codebase does not turn every
28 # build red before anyone has read what it says. Flip the trailing
29 # `|| true` off to make the quality gate binding.
30 #
31 # One step, because each step runs in its own `sh -c` and an export
32 # would not survive to the next. The scanner is cached under the
33 # runner's home rather than re-downloading ~50MB per build, and the
34 # linux-x64 bundle carries its own JRE, which is why the host needs no
35 # Java.
36 sonar:
37 steps:
38 - |
39 set -eu
40 if [ -z "${SONAR_TOKEN:-}" ]; then
41 echo "no SONAR_TOKEN in this build's environment; skipping."
42 echo "A merge request from a fork is built without secrets on purpose,"
43 echo "so this is expected there and is not a failure."
44 exit 0
45 fi
46 VERSION=8.1.0.6389
47 HOME_DIR="${HOME:-/var/lib/gitbay-runner}"
48 SCANNER="$HOME_DIR/.sonar/sonar-scanner-$VERSION-linux-x64"
49 if [ ! -x "$SCANNER/bin/sonar-scanner" ]; then
50 echo "installing sonar-scanner $VERSION"
51 curl --create-dirs -fsSLo "$HOME_DIR/.sonar/sonar-scanner.zip" \
52 "https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$VERSION-linux-x64.zip"
53 unzip -q -o "$HOME_DIR/.sonar/sonar-scanner.zip" -d "$HOME_DIR/.sonar/"
54 rm -f "$HOME_DIR/.sonar/sonar-scanner.zip"
55 fi
56 SONAR_HOST_URL=https://sonarcloud.io \
57 "$SCANNER/bin/sonar-scanner" -Dsonar.scm.revision="${GITBAY_SHA:-}" || true
sonar-project.properties added +21
@@ -0,0 +1,21 @@
1# SonarCloud analysis. Only SONAR_TOKEN is a secret; it is a gitbay build
2# secret (`repo secret set krz/gitbay SONAR_TOKEN`, value on stdin) and
3# never appears here. Everything below is public configuration and is
4# checked in so a scan is reproducible from the repository alone.
5sonar.organization=krz
6sonar.projectKey=krz_gitbay
7sonar.projectName=gitbay
8
9sonar.sources=.
10sonar.tests=.
11sonar.test.inclusions=**/*_test.go
12
13# dist/ is release output, testdata is fixtures meant to be malformed, and
14# the fonts are third-party binaries.
15sonar.exclusions=dist/**,**/testdata/**,internal/web/static/fonts/**
16
17# No sonar.go.coverage.reportPaths yet. Most of this repository's coverage
18# comes from the e2e suite, and re-running that under -coverprofile would
19# double the CI time; unit-only coverage would report misleadingly low
20# numbers for packages e2e exercises heavily. Reporting none is more
21# honest than reporting the wrong number.