ci: SonarQube-Analyse aufrufen, als Beobachtung und nicht als Torwaechter #73

Merged
jklein merged 1 commits from feat/sonar-analysis into main 2026-10-02 01:58:02 +02:00
Member

Die Aufrufer-Seite der SonarQube-Analyse. Der Baustein liegt seit
workflow-util/pipelines#8
in workflow-util/pipelines und ist als v4 getaggt
(0f7cd04c70d1ac79d30a3545b67a4316079ebaad, leichtgewichtig wie v1–v3).

Was drin ist

Datei
.github/workflows/sonar.yml neu — Hülle derselben Art wie die publish-<chart>.yml, Aufruf an @v4 mit secrets: inherit
sonar-project.properties neu — die projektspezifische Hälfte, Schlüssel jlab-cluster_helm-charts
README.md CI/CD-Abschnitt: Was analysiert wird, dass es kein Torwächter ist, wo der Baustein liegt

Dazu die Wiki-Seite CI-CD
— ist bereits gepusht, weil das Wiki keinen PR-Fluss hat.

Der Auslöser

on:
  push:
    branches: [main]
  workflow_dispatch:

Kein paths-Filter, anders als bei den Publish-Hüllen: Die Analyse
betrachtet den ganzen Baum. Ein Filter ließe nach einer Änderung, die er nicht
abdeckt, das alte Ergebnis stehen — und zwar als aktuelles.

workflow_dispatch ist nicht Dekoration. Drei Dinge an diesem Weg sind
ungemessen (unten), jedes kann mehr als einen Versuch brauchen, und ohne
Dispatch kostete jeder Versuch einen Dummy-Commit auf main. Auslösen kann ihn
nur der Betreuer; das Bot-Konto kann keine Workflows dispatchen.

Kein Torwächter, und das ist eine Entscheidung

Die Community Build analysiert ausschließlich den Hauptzweig — eine
PR-Analyse, in die man sich einhängen könnte, gibt es nicht. Also Push auf
main, und damit erscheint ein Befund nach dem Merge. Dort ist nichts mehr
zu blockieren, weshalb der Baustein keinen Quality-Gate-Schritt trägt.

Ein rotes Gate hinter dem Merge färbte nur main rot, ohne etwas verhindert zu
haben — und ein Dauerzustand nimmt die Glaubwürdigkeit von validate-charts
mit, also der einen Prüfung hier, die einen Merge wirklich aufhalten kann.
Richtig wird ein Gate unter einer von zwei Bedingungen: PR-Analyse ist
verfügbar, oder ein Deployment hängt daran. Beides steht in README und Wiki,
damit die Lücke nicht als Versehen nachgetragen wird.

Praktische Folge für Chart-PRs: Die Analyse steht nie in deren Prüfliste.

Was analysiert wird

Gegen die Sprachliste von SonarQube geprüft, nicht angenommen:

Was hier liegt Analysator
5 Shell-Skripte unter ci/ — die ganze CI-Logik Shell
~30 Workflow-Dateien GitHub Actions
238 YAML und 26 Helm-Template-Verzeichnisse Kubernetes/Helm, YAML
26 values.schema.json JSON
der ganze Baum Secrets

Die letzte Zeile ist der Grund für den Aufwand. Die Prämisse dieses
Repositories ist, dass niemals ein Zugangsdatum darin landet — jedes Secret ist
eine OnePasswordItem-Referenz —, und bisher hat das nichts geprüft. Die
übrigen Zeilen sind eine zweite Meinung zu Dingen, die helm lint --strict,
der Render-Test oder Trivy schon berühren; diese eine deckt eine Annahme ab,
die zwei Jahre allein auf Disziplin getragen wurde.

Keine Ausschlüsse

Nach Entscheidung 4 des Plans, Helm-Templates eingeschlossen — die wegen {{ }}
kein gültiges YAML sind. Was der Helm- und der YAML-Analysator damit machen,
bekommt man nur heraus, indem man sie einmal darauf laufen lässt; ein Ausschluss
auf Verdacht verdeckt außerdem, was sonst noch darauf passt.

Wenn der erste Lauf Rauschen erzeugt, das wirklich nicht lesenswert ist, gehört
der Ausschluss in sonar-project.properties — mit dem Befund daneben
benannt
, den er beantwortet. Nicht in den Baustein: Der trägt keinen
Ausschluss für ein einzelnes Repository.

Der Projektschlüssel

jlab-cluster_helm-charts, mit Eigentümer im Namen. Die Instanz bedient zwei
(jlab-cluster und suer); ein nacktes helm-charts ist heute frei und
kollidiert an dem Tag, an dem der zweite Eigentümer ein Repository dieses Namens
hat — und ein Schlüssel lässt sich nachträglich nicht ändern, ohne die Historie
des Projekts zu verlieren.

Voraussetzungen

Name Art Zustand
SONAR_HOST_URL Variable gesetzt
SONAR_TOKEN Secret vorhanden, vom Betreuer bestätigt

Die Adresse ist bewusst eine Variable und kein Secret: Sie ist kein
Zugangsdatum, und als Variable bleibt sie im Protokoll lesbar — erst das macht
eine falsche Adresse diagnostizierbar. Maskiert ergäbe sie einen Fehler gegen
eine Adresse, die niemand sieht; genau diese Lage hat beim Publish-Baustein
einen eigenen Maskierungsschritt erzwungen.

Beide sind von außen nicht prüfbar — tea actions secrets ls antwortet
user should be the owner of the repo, Variablen listet das Werkzeug gar nicht.
„Vorhanden" heißt hier also bestätigt, nicht nachgemessen; der Wächter des
Bausteins ist das, was eine falsche Annahme in einen benannten Fehler verwandelt
statt in einen rätselhaften.

Der Merge löst den ersten Lauf selbst aus

Anders als beim Publish-Umzug: Dort berührt die Änderung kein Chart-Verzeichnis,
der Merge veröffentlicht also nichts und der neue Weg bleibt bis zu einem
manuellen Dispatch unbewiesen. Hier triggert der Workflow auf Push nach main,
und der Merge dieses PR ist so ein Push. Es braucht keinen Dispatch für den
Erstnachweis.

Worauf dann zu schauen ist:

  1. Ist node24 im Runner-Image vorhanden? Die Scan-Action deklariert
    runs: using: node24, ist also eine JavaScript-Action. Fehlt es, liest sich
    der Fehler als Problem der Action und nicht des Images — deshalb steht es
    aufgeschrieben.
  2. Kommt der Scanner-Download durch? Die Action holt den
    Sonar-Scanner-CLI zur Laufzeit von binaries.sonarsource.com und prüft seine
    GPG-Signatur; gemessen ~59 MiB (Content-Length 61 626 644). Die
    wahrscheinlichste Stelle für den ersten Fehlschlag, und eine mit
    Vorgeschichte: Auf diesem Runner kam einmal eine 17-MB-Datei nicht durch,
    weil eine Docker-Brücke mit MTU 1500 gegen ein Pod-Netz mit 1450 lief. Behoben
    wurde das auf der Knoten-Seite; der Scanner ist ein Mehrfaches davon.
  3. Kommt vars.SONAR_HOST_URL in einem aus einem fremden Repository
    aufgerufenen Workflow an?
    Dieselbe offene Frage, die der Publish-Weg für
    OP_CONNECT_HOST noch trägt — dieser Lauf beantwortet sie für beide.
    Kommt sie nicht an, ist es immerhin laut: Der Wächter greift und benennt die
    Variable. Die Reparatur wäre die dort beim Eigentümer schon gemachte — die
    Adresse als Eingabe, im Aufrufer ausgewertet.

Dazu der Punkt, der kein Ja/Nein ist: was die Analyse tatsächlich meldet,
insbesondere aus den Helm-Templates. Das entscheidet, ob Ausschlüsse nötig sind.

Pipeline

Dieser PR berührt kein Chart-Verzeichnis, die Build- und Install-Test-Matrizen
sind also leer; der Quantity-Render-Test läuft wie immer über alle Charts.
sonar.yml selbst läuft in diesem PR nicht — der Auslöser ist ein Push auf
main.

Erstellt unter dem Bot-Konto.

Fixes #71

Die Aufrufer-Seite der SonarQube-Analyse. Der Baustein liegt seit [workflow-util/pipelines#8](https://git.jk-dev.de/workflow-util/pipelines/pulls/8) in `workflow-util/pipelines` und ist als **`v4`** getaggt (`0f7cd04c70d1ac79d30a3545b67a4316079ebaad`, leichtgewichtig wie `v1`–`v3`). ## Was drin ist | Datei | | | --- | --- | | `.github/workflows/sonar.yml` | neu — Hülle derselben Art wie die `publish-<chart>.yml`, Aufruf an `@v4` mit `secrets: inherit` | | `sonar-project.properties` | neu — die projektspezifische Hälfte, Schlüssel `jlab-cluster_helm-charts` | | `README.md` | CI/CD-Abschnitt: Was analysiert wird, dass es kein Torwächter ist, wo der Baustein liegt | Dazu die Wiki-Seite [CI-CD](https://git.jk-dev.de/jlab-cluster/helm-charts/wiki/CI-CD) — **ist bereits gepusht**, weil das Wiki keinen PR-Fluss hat. ## Der Auslöser ```yaml on: push: branches: [main] workflow_dispatch: ``` **Kein `paths`-Filter**, anders als bei den Publish-Hüllen: Die Analyse betrachtet den ganzen Baum. Ein Filter ließe nach einer Änderung, die er nicht abdeckt, das alte Ergebnis stehen — und zwar als aktuelles. **`workflow_dispatch` ist nicht Dekoration.** Drei Dinge an diesem Weg sind ungemessen (unten), jedes kann mehr als einen Versuch brauchen, und ohne Dispatch kostete jeder Versuch einen Dummy-Commit auf `main`. Auslösen kann ihn nur der Betreuer; das Bot-Konto kann keine Workflows dispatchen. ## Kein Torwächter, und das ist eine Entscheidung Die Community Build analysiert **ausschließlich den Hauptzweig** — eine PR-Analyse, in die man sich einhängen könnte, gibt es nicht. Also Push auf `main`, und damit erscheint ein Befund **nach** dem Merge. Dort ist nichts mehr zu blockieren, weshalb der Baustein keinen Quality-Gate-Schritt trägt. Ein rotes Gate hinter dem Merge färbte nur `main` rot, ohne etwas verhindert zu haben — und ein Dauerzustand nimmt die Glaubwürdigkeit von `validate-charts` mit, also der einen Prüfung hier, die einen Merge *wirklich* aufhalten kann. Richtig wird ein Gate unter einer von zwei Bedingungen: PR-Analyse ist verfügbar, oder ein Deployment hängt daran. Beides steht in README und Wiki, damit die Lücke nicht als Versehen nachgetragen wird. Praktische Folge für Chart-PRs: Die Analyse steht nie in deren Prüfliste. ## Was analysiert wird Gegen die Sprachliste von SonarQube geprüft, nicht angenommen: | Was hier liegt | Analysator | | --- | --- | | 5 Shell-Skripte unter `ci/` — die ganze CI-Logik | Shell | | ~30 Workflow-Dateien | GitHub Actions | | 238 YAML und 26 Helm-Template-Verzeichnisse | Kubernetes/Helm, YAML | | 26 `values.schema.json` | JSON | | der ganze Baum | Secrets | **Die letzte Zeile ist der Grund für den Aufwand.** Die Prämisse dieses Repositories ist, dass niemals ein Zugangsdatum darin landet — jedes Secret ist eine `OnePasswordItem`-Referenz —, und bisher hat das *nichts* geprüft. Die übrigen Zeilen sind eine zweite Meinung zu Dingen, die `helm lint --strict`, der Render-Test oder Trivy schon berühren; diese eine deckt eine Annahme ab, die zwei Jahre allein auf Disziplin getragen wurde. ## Keine Ausschlüsse Nach Entscheidung 4 des Plans, Helm-Templates eingeschlossen — die wegen `{{ }}` kein gültiges YAML sind. Was der Helm- und der YAML-Analysator damit machen, bekommt man nur heraus, indem man sie einmal darauf laufen lässt; ein Ausschluss auf Verdacht verdeckt außerdem, was sonst noch darauf passt. Wenn der erste Lauf Rauschen erzeugt, das wirklich nicht lesenswert ist, gehört der Ausschluss in `sonar-project.properties` — **mit dem Befund daneben benannt**, den er beantwortet. Nicht in den Baustein: Der trägt keinen Ausschluss für ein einzelnes Repository. ## Der Projektschlüssel `jlab-cluster_helm-charts`, mit Eigentümer im Namen. Die Instanz bedient zwei (`jlab-cluster` und `suer`); ein nacktes `helm-charts` ist heute frei und kollidiert an dem Tag, an dem der zweite Eigentümer ein Repository dieses Namens hat — und ein Schlüssel lässt sich nachträglich nicht ändern, ohne die Historie des Projekts zu verlieren. ## Voraussetzungen | Name | Art | Zustand | | --- | --- | --- | | `SONAR_HOST_URL` | Variable | gesetzt | | `SONAR_TOKEN` | Secret | vorhanden, vom Betreuer bestätigt | Die Adresse ist bewusst eine **Variable** und kein Secret: Sie ist kein Zugangsdatum, und als Variable bleibt sie im Protokoll lesbar — erst das macht eine falsche Adresse diagnostizierbar. Maskiert ergäbe sie einen Fehler gegen eine Adresse, die niemand sieht; genau diese Lage hat beim Publish-Baustein einen eigenen Maskierungsschritt erzwungen. Beide sind von außen nicht prüfbar — `tea actions secrets ls` antwortet `user should be the owner of the repo`, Variablen listet das Werkzeug gar nicht. „Vorhanden" heißt hier also bestätigt, nicht nachgemessen; der Wächter des Bausteins ist das, was eine falsche Annahme in einen benannten Fehler verwandelt statt in einen rätselhaften. ## Der Merge löst den ersten Lauf selbst aus Anders als beim Publish-Umzug: Dort berührt die Änderung kein Chart-Verzeichnis, der Merge veröffentlicht also nichts und der neue Weg bleibt bis zu einem manuellen Dispatch unbewiesen. Hier triggert der Workflow auf Push nach `main`, **und der Merge dieses PR ist so ein Push**. Es braucht keinen Dispatch für den Erstnachweis. Worauf dann zu schauen ist: 1. **Ist `node24` im Runner-Image vorhanden?** Die Scan-Action deklariert `runs: using: node24`, ist also eine JavaScript-Action. Fehlt es, liest sich der Fehler als Problem der Action und nicht des Images — deshalb steht es aufgeschrieben. 2. **Kommt der Scanner-Download durch?** Die Action holt den Sonar-Scanner-CLI zur Laufzeit von `binaries.sonarsource.com` und prüft seine GPG-Signatur; gemessen **~59 MiB** (`Content-Length` 61 626 644). Die wahrscheinlichste Stelle für den ersten Fehlschlag, und eine mit Vorgeschichte: Auf diesem Runner kam einmal eine 17-MB-Datei nicht durch, weil eine Docker-Brücke mit MTU 1500 gegen ein Pod-Netz mit 1450 lief. Behoben wurde das auf der Knoten-Seite; der Scanner ist ein Mehrfaches davon. 3. **Kommt `vars.SONAR_HOST_URL` in einem aus einem fremden Repository aufgerufenen Workflow an?** Dieselbe offene Frage, die der Publish-Weg für `OP_CONNECT_HOST` noch trägt — dieser Lauf beantwortet sie **für beide**. Kommt sie nicht an, ist es immerhin laut: Der Wächter greift und benennt die Variable. Die Reparatur wäre die dort beim Eigentümer schon gemachte — die Adresse als Eingabe, im Aufrufer ausgewertet. Dazu der Punkt, der kein Ja/Nein ist: **was die Analyse tatsächlich meldet**, insbesondere aus den Helm-Templates. Das entscheidet, ob Ausschlüsse nötig sind. ## Pipeline Dieser PR berührt kein Chart-Verzeichnis, die Build- und Install-Test-Matrizen sind also leer; der Quantity-Render-Test läuft wie immer über alle Charts. `sonar.yml` selbst läuft in diesem PR nicht — der Auslöser ist ein Push auf `main`. Erstellt unter dem Bot-Konto. Fixes #71
jlab-bot added 1 commit 2026-10-02 01:51:10 +02:00
ci: call the shared SonarQube block, and say what it does not do
Validate Helm Charts / Detect changed charts (pull_request) Successful in 4s
Validate Helm Charts / Build ${{ fromJSON(needs.detect-changed-charts.outputs.charts) }} (pull_request) Skipped
Validate Helm Charts / Trivy config ${{ fromJSON(needs.detect-changed-charts.outputs.scan-charts) }} (pull_request) Skipped
Validate Helm Charts / Install-test (pull_request) Skipped
Validate Helm Charts / Resource quantities (pull_request) Successful in 9s
SonarQube Analysis / SonarQube Analysis (push) Failing after 1m0s
67d8c94fb3
Adds the caller side of the analysis: .github/workflows/sonar.yml as a hull of
the same kind as the publish ones, and sonar-project.properties as the
project-specific half. The workflow itself is the shared block in
workflow-util/pipelines, bound to @v4.

No paths filter, unlike the publish hulls: the analysis looks at the whole tree
- the five shell scripts under ci/, every workflow file, the YAML and Helm
templates, the values.schema.json files, and the secret detection over
everything. A filter would leave the previous result standing after a change it
did not cover while still presenting it as current.

workflow_dispatch is on the hull on purpose. Three things about this path are
unmeasured - node24 in the runner image, the ~59 MiB scanner download, and
whether a repository variable reaches a workflow called from another repository
- and any of them may need more than one attempt. Without a dispatch every
attempt would cost a dummy commit on main.

No exclusions, including the Helm templates, which are not valid YAML because
of {{ }}. What the Helm and YAML analysers make of them is only learnable by
letting them run over them once, and an exclusion written on a guess hides
whatever else matches it. If the first run produces noise worth suppressing,
the exclusion belongs in sonar-project.properties with the finding it answers
named next to it.

The project key carries the owner (jlab-cluster_helm-charts) because the
instance serves two, and a key cannot be changed afterwards without losing the
project's history.

The analysis is not a gate. The Community Build analyses the main branch only,
so the trigger is a push to main and a finding appears after the merge - at
which point there is nothing left to block. README and the CI-CD wiki page both
say so, with the two conditions under which a gate would become right, so that
its absence is not read as an oversight.
jklein approved these changes 2026-10-02 01:57:59 +02:00
jklein merged commit 67d8c94fb3 into main 2026-10-02 01:58:02 +02:00
jklein deleted branch feat/sonar-analysis 2026-10-02 01:58:02 +02:00
Sign in to join this conversation.
No Reviewers
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: jlab-cluster/helm-charts#73