From e3d9e66574eb81cc05c146c077ab268f3d59d065 Mon Sep 17 00:00:00 2001 From: Fadhli Azhari Date: Wed, 29 Apr 2026 07:39:05 +0800 Subject: [PATCH] build(ci): add sonar-runner image extending java-builder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- ci/sonar-runner/Dockerfile | 50 ++++++++++++++++++++++++++++++++++++ ci/sonar-runner/README.md | 52 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 ci/sonar-runner/Dockerfile create mode 100644 ci/sonar-runner/README.md diff --git a/ci/sonar-runner/Dockerfile b/ci/sonar-runner/Dockerfile new file mode 100644 index 0000000..9b94af3 --- /dev/null +++ b/ci/sonar-runner/Dockerfile @@ -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 diff --git a/ci/sonar-runner/README.md b/ci/sonar-runner/README.md new file mode 100644 index 0000000..5fa0352 --- /dev/null +++ b/ci/sonar-runner/README.md @@ -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.