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:
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.
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.
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.
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
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.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Die Aufrufer-Seite der SonarQube-Analyse. Der Baustein liegt seit
workflow-util/pipelines#8
in
workflow-util/pipelinesund ist alsv4getaggt(
0f7cd04c70d1ac79d30a3545b67a4316079ebaad, leichtgewichtig wiev1–v3).Was drin ist
.github/workflows/sonar.ymlpublish-<chart>.yml, Aufruf an@v4mitsecrets: inheritsonar-project.propertiesjlab-cluster_helm-chartsREADME.mdDazu die Wiki-Seite CI-CD
— ist bereits gepusht, weil das Wiki keinen PR-Fluss hat.
Der Auslöser
Kein
paths-Filter, anders als bei den Publish-Hüllen: Die Analysebetrachtet den ganzen Baum. Ein Filter ließe nach einer Änderung, die er nicht
abdeckt, das alte Ergebnis stehen — und zwar als aktuelles.
workflow_dispatchist nicht Dekoration. Drei Dinge an diesem Weg sindungemessen (unten), jedes kann mehr als einen Versuch brauchen, und ohne
Dispatch kostete jeder Versuch einen Dummy-Commit auf
main. Auslösen kann ihnnur 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 mehrzu blockieren, weshalb der Baustein keinen Quality-Gate-Schritt trägt.
Ein rotes Gate hinter dem Merge färbte nur
mainrot, ohne etwas verhindert zuhaben — und ein Dauerzustand nimmt die Glaubwürdigkeit von
validate-chartsmit, 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:
ci/— die ganze CI-Logikvalues.schema.jsonDie 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 danebenbenannt, 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-clusterundsuer); ein nackteshelm-chartsist heute frei undkollidiert 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
SONAR_HOST_URLSONAR_TOKENDie 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 lsantwortetuser 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:
node24im Runner-Image vorhanden? Die Scan-Action deklariertruns: using: node24, ist also eine JavaScript-Action. Fehlt es, liest sichder Fehler als Problem der Action und nicht des Images — deshalb steht es
aufgeschrieben.
Sonar-Scanner-CLI zur Laufzeit von
binaries.sonarsource.comund prüft seineGPG-Signatur; gemessen ~59 MiB (
Content-Length61 626 644). Diewahrscheinlichste 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.
vars.SONAR_HOST_URLin einem aus einem fremden Repositoryaufgerufenen Workflow an? Dieselbe offene Frage, die der Publish-Weg für
OP_CONNECT_HOSTnoch 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.ymlselbst läuft in diesem PR nicht — der Auslöser ist ein Push aufmain.Erstellt unter dem Bot-Konto.
Fixes #71
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.