build(ci): add sonar-runner image extending java-builder

Currently KollectAI-ETL's sonar.yml runs in the java-builder image and
downloads sonar-scanner-cli at runtime via curl, with a separate
actions/cache step keyed on the version. That works but:
- Adds two steps (cache restore + conditional install) per scan
- Depends on the gitea-actions cache backend being healthy (the same
  backend that's been timing out lately)
- Single-purpose tool with single-purpose cache plumbing

New ci/sonar-runner image extends ci/java-builder via FROM and bakes
sonar-scanner-cli at /opt/sonar-scanner with bin/ on PATH. Inherits
everything from java-builder (Java 25, Maven, Node + pnpm, buf, ORAS,
NVD database) — no duplicate state.

Build args:
- REGISTRY (default 192.168.1.72) + JAVA_BUILDER_TAG (default latest)
  for the FROM line
- SONAR_SCANNER_VERSION (default 6.2.1.4610) — must match
  KollectAI-ETL's sonar.yml SONAR_SCANNER_VERSION env

Build order: java-builder first, then sonar-runner. The CI workflow's
auto-discovery handles this naturally; for manual builds use
build-and-push.ps1 -Image ci/java-builder before ci/sonar-runner.

Matching change in KollectAI-ETL drops the cache-scanner-cli + install
steps from sonar.yml; the scan job just runs `sonar-scanner` directly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
main
Fadhli Azhari 2026-04-29 07:39:05 +08:00
parent 0fdc7f59eb
commit e3d9e66574
2 changed files with 102 additions and 0 deletions

View File

@ -0,0 +1,50 @@
# KollectAI CI - SonarQube Runner Image
#
# Extends ci/java-builder with the standalone sonar-scanner CLI baked
# in. Used by KollectAI-ETL's sonar.yml workflow so the scan job goes
# straight from `mvn compile` to `sonar-scanner` with no runtime
# install or cache restore.
#
# Single-purpose image — sonar-scanner is only used by this one
# workflow, so we don't bake it into the shared java-builder.
#
# Build:
# docker build -t 192.168.1.72/kollect-tools/ci/sonar-runner:latest ci/sonar-runner/
#
# Build prerequisite: java-builder:latest must exist in the registry
# (this image FROMs it). Run `build-and-push.ps1 -Image ci/java-builder`
# before this one if java-builder has changed.
#
# Usage in CI:
# container:
# image: 192.168.1.72/kollect-tools/ci/sonar-runner:latest
ARG REGISTRY=192.168.1.72
ARG JAVA_BUILDER_TAG=latest
FROM ${REGISTRY}/kollect-tools/ci/java-builder:${JAVA_BUILDER_TAG}
# Sonar-scanner version. Bump in lockstep with KollectAI-ETL's
# .gitea/workflows/sonar.yml SONAR_SCANNER_VERSION env.
ARG SONAR_SCANNER_VERSION=6.2.1.4610
# ─────────────────────────────────────────────────────────────────────
# sonar-scanner CLI
#
# Installed under /opt/sonar-scanner with its bin/ on PATH so workflows
# can call `sonar-scanner` directly. The standalone CLI bundles its own
# JRE and analyser binaries — Java 25 from java-builder is only used
# when sonar-scanner shells out to javac for project compilation.
# ─────────────────────────────────────────────────────────────────────
RUN curl -fsSL "https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${SONAR_SCANNER_VERSION}-linux-x64.zip" \
-o /tmp/sonar-scanner.zip \
&& unzip -q /tmp/sonar-scanner.zip -d /opt \
&& mv "/opt/sonar-scanner-${SONAR_SCANNER_VERSION}-linux-x64" /opt/sonar-scanner \
&& rm /tmp/sonar-scanner.zip
ENV PATH="/opt/sonar-scanner/bin:${PATH}"
# Verify installation (also re-runs java-builder's verify chain to fail
# fast if the parent image broke).
RUN java -version \
&& mvn -version \
&& sonar-scanner --version

View File

@ -0,0 +1,52 @@
# Sonar Runner — CI Image
Pre-baked build environment for KollectAI-ETL's SonarQube unified scan workflow. Extends [`ci/java-builder`](../java-builder/) with the standalone `sonar-scanner` CLI.
## What's included
Everything from [`java-builder`](../java-builder/) (Java 25, Maven 3.9.x, Node + pnpm, buf, ORAS, OWASP NVD database, jq/git/curl), plus:
- `sonar-scanner` CLI at `/opt/sonar-scanner` with its `bin/` on `PATH`
## Build
```bash
# Prerequisite: java-builder must already exist in the registry.
docker build -t 192.168.1.72/kollect-tools/ci/sonar-runner:latest ci/sonar-runner/
docker push 192.168.1.72/kollect-tools/ci/sonar-runner:latest
```
### Build args
| Arg | Default | Description |
|-----|---------|-------------|
| `REGISTRY` | `192.168.1.72` | Registry hostname for the parent `java-builder` pull |
| `JAVA_BUILDER_TAG` | `latest` | Tag of `java-builder` to extend |
| `SONAR_SCANNER_VERSION` | `6.2.1.4610` | Bump in lockstep with `KollectAI-ETL/.gitea/workflows/sonar.yml`'s `SONAR_SCANNER_VERSION` |
## Usage in CI
```yaml
jobs:
scan:
runs-on: ubuntu-latest
container:
image: 192.168.1.72/kollect-tools/ci/sonar-runner:latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0 # blame-aware analysis
- run: ./mvnw -f backend/pom.xml compile test-compile -DskipTests -q
- run: sonar-scanner
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
```
No more runtime `curl`-install or cache restore step — the scanner is on `PATH` from the moment the container starts.
## Maintenance
- Sonar-scanner version bump: edit the `SONAR_SCANNER_VERSION` ARG default and rebuild. Keep the matching `SONAR_SCANNER_VERSION` env in `KollectAI-ETL/.gitea/workflows/sonar.yml` in sync.
- Java/Maven/etc. bumps: just rebuild — they come from the parent `java-builder` image.
- Build order: `java-builder` first, then `sonar-runner`. The CI workflow's auto-discovery handles this naturally as long as both images exist; for manual builds invoke them in that order.