diff --git a/README.md b/README.md index 6f50793..efa863e 100644 --- a/README.md +++ b/README.md @@ -173,19 +173,21 @@ Why it exists at all: the answer arrived once by accident. Gitea PR #48 correcte ### SonarQube analysis (after the merge, and not a gate) -`sonar.yml` sends the whole tree through a SonarQube analysis. The workflow itself is the shared block [`sonar-analysis.yml`](https://git.jk-dev.de/workflow-util/pipelines/wiki/sonar-analysis) in `workflow-util/pipelines`, bound to `@v4`; the only thing on this side is `sonar-project.properties` in the repo root, holding the project key `jlab-cluster_helm-charts`. The key carries the owner because the instance serves two (`jlab-cluster` and `suer`), and a project key cannot be changed afterwards without losing the project's history. +`sonar.yml` sends the whole tree through a SonarQube analysis. The workflow itself is the shared block [`sonar-analysis.yml`](https://git.jk-dev.de/workflow-util/pipelines/wiki/sonar-analysis) in `workflow-util/pipelines`, bound to `@v4`; the only thing on this side is `sonar-project.properties` in the repo root, holding the project key `JLab-Helm-Charts`. **That key is read off the existing project in SonarQube, not derived** — it is the one the maintainer set up, and a guessed key (`jlab-cluster_helm-charts`, reasoned from the instance serving two owners) is what made the first run fail. The file carries **no `sonar.projectName`** on purpose: once the project exists, the display name belongs to the server, and a name sent with every analysis would overwrite a rename there silently. -**What is analysed** — the languages were checked against SonarQube's list rather than assumed, and the fit is better than expected: +**What is analysed — measured, not taken from a language list.** The first run (run 375) loaded exactly **two quality profiles, `json` and `yaml`**; the sensors that did work were **IaC Kubernetes** (3.4 s) and the **secrets detection** (`TextAndSecretsSensor`) over all 391 indexed files. -| What is in this repository | Analyser | -|---|---| -| the 5 shell scripts under `ci/` — the whole CI logic | Shell | -| ~30 workflow files | GitHub Actions | -| 238 YAML files and 26 Helm template directories | Kubernetes/Helm, YAML | -| 26 `values.schema.json` | JSON | -| the whole tree | Secrets | +| What is in this repository | Analyser | Runs? | +|---|---|---| +| 238 YAML files and 26 Helm template directories | IaC Kubernetes, YAML | yes | +| 26 `values.schema.json` | JSON | yes | +| the whole tree (391 files) | Secrets | yes | +| the 5 shell scripts under `ci/` — the whole CI logic | Shell | **no** | +| the 30 workflow files | GitHub Actions | **no** | -The last row is the valuable one. **The premise of this repository is that no credential ever lands in it** — every secret is a 1Password `OnePasswordItem` reference — and until now nothing checked that premise. +**The two missing rows are not a configuration mistake, and nothing in this repository can fix them: analysers come from the *server*, not from the scanner.** The language list the earlier version of this table was built from describes the newest SonarQube release; this instance does not have the Shell and GitHub Actions plugins. The consequence is worth stating plainly rather than leaving it to be rediscovered — **the files carrying the actual logic, the five `ci/` scripts and the thirty workflows, are not analysed at all.** What runs is IaC over the charts plus secret detection over everything. Whether the instance gets upgraded or gains those plugins is a decision for whoever runs it, not something this repository settles; `shellcheck` and review remain the only check on the scripts until then. + +The secrets row is the valuable one that *does* run. **The premise of this repository is that no credential ever lands in it** — every secret is a 1Password `OnePasswordItem` reference — and until now nothing checked that premise. What it actually reports is still unknown: run 375 built the report (603 kB) but never uploaded it, because the upload is where the wrong project key failed. **It is not a gate, and that is a decision.** The SonarQube Community Build analyses the **main branch only**; there is no pull-request analysis to hook into, so the trigger is a push to `main` and **a finding appears after the merge**. At that point there is nothing left to block, which is why the shared block carries no quality-gate step: a red gate behind the merge would only colour `main` red without having prevented anything, and a permanent red is a thing people learn to ignore — taking the credibility of `validate-charts` with it. A gate becomes the right thing under one of two conditions: pull-request analysis is available, or a deployment hangs off the workflow. Until then, read the findings in SonarQube; nothing in this repository turns red because of them. @@ -193,7 +195,7 @@ The last row is the valuable one. **The premise of this repository is that no cr **Prerequisites**, both on the instance and neither in a file here: the repository **variable `SONAR_HOST_URL`** (a variable and not a secret on purpose — the server address is not a credential, and as a variable it stays readable in the log, which is what makes a wrong one diagnosable) and the **secret `SONAR_TOKEN`**, which reaches the block through `secrets: inherit`. The block guards both and names the setting and its place when one is empty. A *missing* `SONAR_TOKEN` never gets that far: the block declares it `required`, and a missing required secret fails job **creation** on this instance, so the run would show no steps at all — the same quirk as everywhere else here. -**Three things about this path are unmeasured**, and the first run after this change is what answers them: whether `node24` is in the runner image (the scan action is a JavaScript action declaring `runs: using: node24`, so a failure will read as an action problem rather than an image one), whether the scanner download gets through — the action fetches the Sonar Scanner CLI from `binaries.sonarsource.com` at run time, ~59 MiB, and a 17 MB download once failed on this runner for MTU reasons (see "What a GitHub runner had been providing quietly") — and whether a repository **variable** reaches a workflow called from another repository, which is the same open question the publish route has for `OP_CONNECT_HOST`. `workflow_dispatch` is on the hull for exactly this: retrying any of them otherwise costs a dummy commit on `main`. +**Three things about this path were unmeasured, and run 375 answered all three — positively.** `node24` **is** in the runner image, so the JavaScript scan action runs. The scanner download **gets through**: ~59 MiB of archive plus its signature in roughly three seconds, so the MTU failure that once killed a 17 MB download on this runner (see "What a GitHub runner had been providing quietly") does not repeat at five times the size. And a repository **variable does reach a workflow called from another repository** — the block's guard passed and the scanner started, which it could not have done without `vars.SONAR_HOST_URL` arriving. That last one also settles the identical question the publish route carried for `OP_CONNECT_HOST`: same forge version, same mechanism, a repository variable read inside a workflow called from another repository. What the publish route still has unproven is the upload itself, which has never run. `workflow_dispatch` stays on the hull for the retries: without it every attempt costs a dummy commit on `main`. ## Dependency updates (Renovate) diff --git a/sonar-project.properties b/sonar-project.properties index aef7877..852951e 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -2,12 +2,30 @@ # block in workflow-util/pipelines and is identical for every repository that # uses it; everything that is about THIS repository lives here. # -# The key carries the owner. The instance serves two owners (jlab-cluster and -# suer), so a bare "helm-charts" would be free now and collide the moment the -# second owner has a repository of the same name - and a key cannot be changed -# afterwards without losing the project's history. -sonar.projectKey=jlab-cluster_helm-charts -sonar.projectName=jlab-cluster/helm-charts +# The key is the one the project already has on the server, given by the +# maintainer. It is not derivable and must not be guessed: the project is +# created in SonarQube first, and the key is then read off it. +# +# The first attempt here was a guess, "jlab-cluster_helm-charts", reasoned from +# the instance serving two owners. It failed with +# +# ERROR You're not authorized to analyze this project or the project doesn't +# exist on SonarQube and you're not authorized to create it. +# +# which is the message for BOTH a wrong key and a token without "Execute +# Analysis" on the project - the server does not distinguish them, so a wrong +# key here looks exactly like a permission problem over there. Once the key is +# known to be right, that message means the token. +sonar.projectKey=JLab-Helm-Charts + +# NO sonar.projectName, deliberately. +# +# The project exists on the server, so the display name belongs to the server: +# whoever renames it there expects the rename to hold. A name sent with the +# analysis would overwrite it on every single run, silently, and the person who +# renamed it would only see it snap back. A value that rewrites someone else's +# setting without saying so is not a value this repository carries. If the name +# is wrong, it gets fixed in SonarQube, not here. # The whole tree, which is also the scanner's default - stated rather than # implied, because the absence of exclusions below is a decision and an empty