Repository navigation
ci(sonarqube): guard step with shell: bash, and SONAR_TOKEN in 2 steps only - #321
Conversation
The script of the guard step is Bash. With no `shell:` key, the shell comes from the runner or from a `defaults.run.shell` key. A copy of this workflow with a different default shell then fails in the guard step, before it can report the state of the token. The step now says `shell: bash`. On the hosted Ubuntu runner the result is the same: the script has no pipe, so `-o pipefail` changes nothing. The fleet recipe `fix-sonarqube-token-guard.sh` (gitbot-fleet) takes the same line after this change. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0136P7ZmiFSCoB3UR9Kk56rK
|
Caution Review failedThe pull request is closed. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. |
|
🟠 indeterminate · commit Advisory: 11 row(s), worst 🔴 high (0 critical, 9 high in grid scope) — reported, never grading the change. Unique graded findings across gating and advisory rows: 19 (19 reporter observations; 19 without sufficient identity to corroborate). Row counts remain per reporter; unique totals do not change gating.
Hypatia scan: error — the scanner produced no SARIF projection
panic-attack assail: 18 finding(s)
pons asinorum: 9 finding(s)
echidnabot: not_applicable — template default: enrol once the repository carries proofs and an ECHIDNA engine is configured
rhodibot (RSR compliance): 13 finding(s)
panicbot: not_applicable — panic-attack is already graded by the verdict grid's own panic-attack row, from static-analysis-gate.yml evidence; enrolling panicbot would report one scanner twice and give two rows that can disagree
sustainabot: not_applicable — reserved fleet slot; no adapter exists (gitbot-fleet bots/sustainabot/README.adoc)
glambot (presentation quality): 82 finding(s)
seambot: not_applicable — template default: enrol once a seam register exists at spec/seams/seam-register.json
finishingbot (release readiness): 174 finding(s)
cipherbot: not_applicable — template default: enrol once the repository implements cryptography
accessibilitybot: not_applicable — template default: enrol once the repository serves HTML
Scope: static findings reported by each row's tool at the named commit. The table grades only findings in files this change touches, so the colour answers "does this change introduce anything?", not "what does the whole repository still carry?". Standing findings are counted in each accordion and in report.json; the baseline filter remains the place where acknowledged debt is recorded. The lane state is the worst GATING row; advisory rows are listed and counted but never set it. Purple, red, yellow and blue grade the worst GRADED finding present; orange is evidence missing, malformed or a scanner that did not run; grey is an explicit scope exclusion with its reason. No row is a security certification. report.json, badge.json and the raw findings are in the verdict-grid artifact on the linked run. |
The token was in the environment of the job, so each step of the job could read the secret, for example the checkout. Only 2 steps use it: the guard step tests it, and the scan step sends it. The token is now in the environment of the guard step. The scan step keeps its own entry. The job has no `env:` key. Owner decision (2026-11-10). The guard step is now the text that the fleet recipe `fix-sonarqube-token-guard.sh` (gitbot-fleet) writes. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0136P7ZmiFSCoB3UR9Kk56rK
shell: bash on the token guard stepshell: bash, and SONAR_TOKEN in 2 steps only
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
…ken guard, split comment keys) (#658) ## Summary A repository gets a copy of the estate template (`rsr-template-repo`) when it is made. Later repairs in the template do not reach that copy. The same CI failures then show in each older repository, although the template has the repair. This pull request adds 3 recipes that make changes which the template already has. The worked example is `hyperpolymath/system-et` (pull requests 90 and 92), where each repair was first made by hand. **The recipes are not dispatched.** The dispatch quarantine (`docs/AUTOMATION-QUARANTINE.adoc`) is not touched. The campaign has no manifest, because a manifest needs an estate scan, and the quarantine document forbids a scan as a workaround. `AGENTIC.a2ml` is not touched: the grant for these recipes is the owner's. **Order of merge.** The token guard recipe writes the guard step of the template after hyperpolymath/rsr-template-repo#321 (owner decisions, 2026-11-10: the template first, then the recipe). That pull request puts the token in the guard step and the scan step only, and sets `shell: bash` on the guard step. Merge it before this one, so that the recipe writes text that the template has. ## The recipes | Recipe id | Script | Target | Repair | |---|---|---|---| | `recipe-workflow-linter-spdx-rule` | `fix-workflow-linter-spdx-rule.sh` | `workflow-linter.yml` with the rule that requires the SPDX line on line 1. `gh actions-lock` writes its comment on line 1, so each lock run makes each managed workflow fail the lint. | The rule of the template: the licence line can be at any position in the leading comment block. | | `recipe-sonarqube-token-guard` | `fix-sonarqube-token-guard.sh` | `sonarqube.yml` that scans with `secrets.SONAR_TOKEN` and has no `if:` line. With no secret, the scan fails on each run. | The guard of the template: the first step tests the token. With no token the job says that the scan is not configured and passes. The guard step is the text of the template after rsr-template-repo#321: the token is in the environment of the guard step and of the scan step only, and the guard step sets `shell: bash`. | | `recipe-workflow-split-comment-keys` | `fix-split-comment-keys.sh` | A workflow where the lock sweep of 2026-08 split a comment line such as `# steps:` into a line `#` and a line `steps:` at column 1. GitHub refuses the file ("Unexpected value 'steps'"). | The 2 lines become 1 comment line again. | Each recipe: - has the predicate `--check <repo-path>` (prints the number of targets, changes nothing), with the header line `# outcome-predicate: --check`; - is idempotent; - does not follow a symlink, and does not leave the repository; - edits the working tree only, and makes no commit; - does not change a target with an unknown shape, and then exits 1, so that the run does not read as a repair; - is bash and awk only. ## Other changes - `scripts/fix-script-registry.json`: 3 `by_recipe` routes. - `tests/template-drift-recipes-test.sh`: the contract test, and 1 step for it in `.github/workflows/e2e.yml`. - `campaigns/TEMPLATE-DRIFT-CAMPAIGN.adoc`: purpose, status, evidence and limits. ## Not in this pull request - **No recipe moves descriptile files** out of a retired directory (`.machine_readable/6a2/`). The files include `AGENTIC.a2ml`, and the quarantine document says that a job must not relocate directive files. A person moves the files. After that, the existing `recipe-retired-descriptile-policy` repairs the references. - No rule in Hypatia finds these targets yet. The recipes can only be routed by recipe id. ## Testing - `bash tests/template-drift-recipes-test.sh`: PASS. For each recipe: the predicate finds the old shape, the repair gives the exact expected text, a second run changes nothing, a file that is not a target is not changed, a symlink is not followed. The test also runs the new SPDX rule on 3 sample files and the guard step with and with no token. - The test fails when a recipe is broken. 6 deliberate defects, each one restored after the run: the old hint text stays; no `if:` line on the steps; an unknown shape is edited; a wrong indentation; `jobs:` treated as a target; a symlink followed. Each defect gave FAIL. - Cases added after review. Each one fails with the recipe before its fix: - 8 cases of a workflow that is the old template with 1 difference: a step with `id: cfg`, a block-scalar step name, the token below `with:`, a Windows runner, a custom runner label `ubuntu-windows`, the label `ubuntu` with no version, a `defaults:` key, and the quoted key `"defaults":`. Each is refused, and the file is not changed. - 1 case with the older action `SonarSource/sonarcloud-github-action`: repaired, and the name of the action is not changed. - 1 case of 2 workflows with split keys where 1 cannot be repaired: the repository is refused, and no file is changed. - The test fails with no registry routes (run before the routes were added). - Each recipe was run on the files of `system-et` at `main` (`04a8b6e`): - SPDX rule: the step is identical to the step of the template (`c5a1da7`). - Token guard: the job is identical to the job in pull request 92 of that repository (`9f529ef`). The guard step is identical to the guard step of the template branch (rsr-template-repo#321, `806dac0`). - Split keys: 19 lines restored. The 19 lines are the lines that the file had before the sweep. The file is identical to the repair in pull request 90 of that repository, except for the order of the first 2 comment lines, which a different commit of that pull request changed. - A second repository (`anytype`) has the first 2 targets and not the third. The template itself is not a target. - `tests/outcome-verdict-test.sh`, `tests/automation-quarantine-test.sh` and `scripts/tests/dispatch-paths.sh` pass with the change, as they do on `main`. - Not run: `shellcheck` (not available in the session), `scripts/tests/fix-workflow-pins.sh`, the Rust tests. - The local awk is mawk 1.3.4. The recipes were not run with gawk. ## Limits - Not verified: that a later run of `gh actions-lock` does not split the restored comment lines again. The template avoids the problem with an inactive file (`e2e.yml.template`). - The token guard recipe edits only the old template. The `jobs:` section must be the text of the old template, line for line. Only these can differ: the reference of the 2 actions, the 2 names of the scan action, the hosted Ubuntu version, the timeout value and the comment on `fetch-depth`. Before `jobs:`, only the 4 top-level keys of the old template can be present. The recipe does not rewrite a workflow that a person changed. - The number of repositories with each target is not known. No estate scan was made. --- _Generated by [Claude Code](https://claude.ai/code/session_0136P7ZmiFSCoB3UR9Kk56rK)_ <!-- This is an auto-generated comment: release notes by coderabbit.ai --> <!-- coderabbit-ai-generated:v1 --> ## Summary by CodeRabbit * **New Features** * Added manual repair options for supported workflow lint, token-handling, and comment-formatting issues. Unsupported workflow formats and shapes are left unchanged. * **Documentation** * Added guidance on repair conditions, limitations, and expected outcomes. * **Tests** * Added checks for repair results, check-mode reporting, repeatability, and handling of unsupported files. * The end-to-end workflow now runs these checks. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude <noreply@anthropic.com>
…X lint rule, after the estate template (#92) Depends on: #90 ## Summary This repository was made from an older copy of the estate template (`hyperpolymath/rsr-template-repo`). Later fixes in the template did not reach it. This pull request ports 3 of them. 1. **6 workflows called a reusable workflow of the standards repository**: `secret-scanner.yml`, `governance.yml`, `hypatia-scan.yml`, `rust-ci.yml`, `mirror.yml` and `scorecard.yml`. No such call started. Each run failed with no job and no check, and one failed run came with each push. The template now has a self-contained form of each one. 2. **`sonarqube.yml` failed on each run**, because the repository has no `SONAR_TOKEN` secret. The template has a guard for this case since 2026-07-28. 3. **The SPDX rule of `workflow-linter.yml` required the licence line on line 1.** The tool `gh actions-lock` writes its own comment on line 1, so each lock run made 30 workflow files fail the lint. The template accepts the licence line at any position in the leading comment block. The branch starts from the head of pull request 90, because the workflow lint fails on `main` until pull request 90 is in. The diff thus shows the 5 commits of pull request 90 also, until that pull request is merged. The change of this pull request is 6 commits: `f16c2d4`, `7fdd25e`, `589a63d`, `6560eca`, `4bb4a7f` and `9f529ef`. ## Changes - The 6 workflow files have the jobs of the template. The text of the jobs is the text of the template, with these changes for this repository: - The references to `actions/*` and `github/*` actions are tags with records in `actions.lock`, as in the other workflows here. The template writes commit SHAs. - The 2 third-party actions (`erlef/setup-beam`, `ossf/scorecard-action`) are pinned with a commit SHA, as in the template. The first commit wrote them as tags, and SonarCloud reported that (rule `githubactions:S7637`). The second commit corrects it. - `github/codeql-action/upload-sarif` is at v4.39.2, the version that the lock of this repository has. - The header comments say what is true for this repository. Comments of the template about its own rulesets and its verdict grid are not copied. - `sonarqube.yml`: the first step tests the token. With no token, it writes a notice that the scan is not configured, the checkout and the scan do not run, and the job passes. With a token, the scan runs as before, with no edit of the file. The action references do not change. - The guard step is the text of the template after hyperpolymath/rsr-template-repo#321 (owner decisions of 2026-11-10). The token is in the environment of the guard step and of the scan step only, and not of the job, where each step can read it. A review of the sweep recipe (gitbot-fleet pull request 658) found this. The guard step sets `shell: bash`. - The job is identical to the output of that recipe on the file of `main`. The guard step is identical to the guard step of the template branch. - `workflow-linter.yml`: the step `Check SPDX Headers` is now identical to the step of the template (`c5a1da7`). Pull request 90 moved the licence line to line 1 in 30 files. That repair holds only until the next lock run. With this rule, the two line orders pass. No other step of the linter changes. - `actions.lock`: the lists of the 6 workflows, and 2 new records with a SHA key (`erlef/setup-beam`, `ossf/scorecard-action`). The records are written by hand, because `gh actions-lock` is not available in the session. Each commit is the commit of the tag (read with `git ls-remote`), and the owner and repository numbers are the numbers in the lock of the template. - `.github/workflows/README.adoc` says what these files are now. What each of the 6 workflows does now: | Workflow | Jobs | |---|---| | `secret-scanner.yml` | `scan / gitleaks` (working tree, full history and AsciiDoc files, with the estate baseline from `metadatastician/standards` at `e064539`), `scan / rust-secrets`, `scan / shell-secrets`. No job has a `secrets:` line. | | `governance.yml` | The TypeScript and package-manager policy. The reusable workflow had more policy jobs; the template form has this one. | | `hypatia-scan.yml` | Hypatia at a pinned commit, a SARIF upload, and a failure on a critical finding. `static-analysis-gate.yml` also runs Hypatia, for the gitbot-fleet deposit. | | `rust-ci.yml` | Compiles `scripts/*.rs` and runs cargo when a `Cargo.toml` is present. This repository has no Rust file. | | `mirror.yml` | Checks out the full history. It does not push to a forge. | | `scorecard.yml` | OSSF Scorecard, on a schedule and on manual dispatch. | ## Results in CI - `scan / gitleaks`: 102 commits scanned, no leaks found (first run of gitleaks on this repository). `scan / rust-secrets` and `scan / shell-secrets` pass. - `Estate Governance Policy`, `Hypatia Neurosymbolic Analysis`, the code-scanning check `Hypatia`, and `Rust standalone tools and workspace gate` pass. - `lint-workflows` passes, so `gh actions-lock --verify-local` accepts the lock file. `SonarCloud Code Analysis` passes. - `SonarQube` passes at `589a63d`: the job reports that the scan is not configured. - At `589a63d`, each of the 38 check runs has the result success, neutral or skipped. The results for the 3 later commits are in the checks of this pull request. - `mirror.yml` and `scorecard.yml` do not run in a pull request. Their first run is after a merge (push to `main`) and on the schedule. ## RSR Quality Checklist ### Required - [ ] Tests pass (`just test` or equivalent). `just` is not available in the session. Run in the session: `tests/workflows/validate_workflows_test.sh` (PASS), `validate-k9.sh` (PASS), `check-root-shape.sh` (PASS), `scan-dangerous.sh` (PASS). - [ ] Code is formatted. Not applicable. - [x] Linter is clean. `lint-workflows` passes in CI. - [x] No banned language patterns - [x] No `unsafe` blocks without `// SAFETY:` comments (none exist) - [x] No banned functions - [x] SPDX license headers present on all new/modified source files - [x] No secrets, credentials, or `.env` files included ### As Applicable - [ ] `.machine_readable/descriptiles/STATE.a2ml` updated. Not applicable. - [ ] `.machine_readable/descriptiles/ECOSYSTEM.a2ml` updated. Not applicable. - [ ] `.machine_readable/descriptiles/META.a2ml` updated. Not applicable. - [x] Documentation updated for user-facing changes (`.github/workflows/README.adoc`) - [ ] `TOPOLOGY.md` updated. Not applicable. - [ ] `CHANGELOG` or release notes updated. Not done: the change is to CI. - [ ] New dependencies reviewed for license compatibility. One new action in CI: `ossf/scorecard-action` (Apache-2.0). The earlier reusable workflow used the same action. - [ ] ABI/FFI changes validated. Not applicable. ## Testing - Each changed workflow file parses, and each has the top-level keys `name`, `on`, `concurrency`, `permissions` and `jobs`. - Each action reference of the 6 files has a list entry and a record in `actions.lock` (a local script). - The governance checks pass on this tree. The shell-secrets pattern finds nothing. - The guard step of `sonarqube.yml` gives `configured=false` with an empty token and `configured=true` with a token. This is a local run of the step, also after the change of the token scope. After the `shell: bash` line, the run uses the command of that key: `bash --noprofile --norc -eo pipefail`. `tests/workflows/validate_workflows_test.sh` passes at `9f529ef`. - The SPDX rule, on 4 sample files: the tool comment on line 1 with the licence on line 2 passes; the licence on line 1 passes; no licence line fails; a licence line after the workflow body fails. The old rule fails the first sample. All 30 workflow files of this branch pass the new rule. - The gitleaks checksum of the template is the checksum of the release file. The standards commit `e064539` exists and has the gitleaks baseline. - Not run locally: gitleaks, Hypatia and Scorecard. ## Screenshots Not applicable. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_0136P7ZmiFSCoB3UR9Kk56rK --------- Co-authored-by: Claude <noreply@anthropic.com>



Summary
2 changes to the guard of
.github/workflows/sonarqube.yml. The owner decided on each one (2026-11-10): the template first, then the fleet recipe.shell: bashon the guard step. The script of the guard step is Bash. With noshell:key, the shell comes from the runner or from adefaults.run.shellkey. A copy of this workflow with a different default shell fails in the guard step, before it can report the state of the token.SONAR_TOKENwas in the environment of the job, so each step could read the secret, for example the checkout. Only 2 steps use it: the guard step tests it, and the scan step sends it.After this change, the guard step is the text that the fleet recipe
fix-sonarqube-token-guard.shwrites (hyperpolymath/gitbot-fleet#658). The recipe then has no difference from the template.Changes
.github/workflows/sonarqube.yml, stepReport configuration state:shell: bash, with a comment of 2 lines that gives the reason;env: SONAR_TOKEN, with a comment of 3 lines..github/workflows/sonarqube.yml, jobsonarqube: theenv:key and its comment are removed. The scan step keeps its ownenv:entry, as before.On the hosted Ubuntu runner the behaviour is the same: the script has no pipe, so
-o pipefailchanges nothing.RSR Quality Checklist
Required
just testor equivalent): not run locally,justis not in the container. CI runs it.just fmtor equivalent): not run locally, same reason.unsafeblocks without// SAFETY:commentsbelieve_me,unsafeCoerce,Obj.magic,Admitted,sorry).envfiles includedAs Applicable
None applies: the change is in 1 workflow job. The deed entry for this job (
:workflow ".github/workflows/sonarqube.yml") describes the scan and stays correct.Testing
Run locally on the changed file:
yqreads the workflow: the job has noenv:key; the steps withSONAR_TOKENareReport configuration stateandSonarQube Scan; the first step hasshell: "bash"; the file names the secret on 2 lines.bash --noprofile --norc -eo pipefail(the command ofshell: bash):SONAR_TOKEN: exit 0, outputconfigured=false;configured=true.bash scripts/check-lock-sync.sh: exit 0.bash tests/workflows/hypatia_ignore_test.sh:PASS(41 checks).sonarqube.ymlofsystem-etatmain:jobs:section is identical to thejobs:section of this branch, when the action references, the runner version and the blank lines are made neutral.Not verified: a run of the workflow on GitHub with a token. This repository has no
SONAR_TOKENsecret, so the run on this pull request shows the path with no token only.Screenshots
Not applicable.
🤖 Generated with Claude Code
https://claude.ai/code/session_0136P7ZmiFSCoB3UR9Kk56rK