Skip to content

fix(review): the workflows run the shared scripts, and the scripts carry their tests - #16

Merged
soydiloreto merged 2 commits into
mainfrom
refactor/workflows-use-shared-scripts
Sep 29, 2026
Merged

soydiloreto merged 2 commits into
mainfrom
refactor/workflows-use-shared-scripts

Conversation

@soydiloreto

Copy link
Copy Markdown
Member

📝 What changes

The workflows now run the scripts the local review uses, instead of their own inline copies:

  • conventions.yml runs scripts/conventions.sh, read from DiluxOne/.github at the new central-ref input (default v2, like the other workflows); this repository's own pull requests run their own copy.
  • claude-review.yml builds its brief with scripts/review-brief.sh. The code moved as it was: the brief comes out byte for byte the same, checked on two real pull requests.

So what runs on GitHub and what runs on a contributor's machine are the same files and can no longer drift apart.

The three scripts that had no tests now have them, run by the scripts job:

  • local-review.sh --test (11 cases, never runs the review itself): no profile anywhere, a profile the workflow passes (quoted or not, or overridden with --profile), no commit, two commits without a title, a bad commit header, an empty or a filled description, with and without an origin remote, an unknown option. Writing them found one more bug, fixed here: a repository without an origin remote stopped the script. The profile is now read quoted or unquoted, with portable patterns.
  • review-brief.sh --test (15 cases): what the reviewer is shown, including rewritten files, binaries and lock files, the floor-dependent rules, the incremental scope and a diff over the limit.
  • policy.py --test (23 cases): floor, trust, auto-merge, model, budget and the changes mode, against the organisation's default policy.

AGENTS.md gains a rule: a problem a review finds that a test could have caught comes with that test, in the same pull request.

💡 Why

The previous pull request (#15) left the conventions and the brief in two places, the scripts and the workflows, until this switch. Its review also found a bug in local-review.sh that no test covered; the local review had not seen it. A review is a reading and may miss a thing; a test catches it every time. policy.py decides the model and whether a change may merge without a person, and had no test at all.

🧪 How I tested it

  • Every script's --test locally: conventions, review-brief, local-review, policy, release-markers, release-ready, stamp-version, next-version, all green.
  • The local-review.sh test fails with the feat(review): check a branch locally, before its pull request, as CI will check it #15 bug put back.
  • actionlint on every workflow.
  • local-review.sh on this branch before pushing: it found five minor points (three header comments, a duplicated test case, a test that did not check what its name said), fixed here.

🤖 AI-generated · Claude Opus 5.5 (Anthropic)

soydiloreto and others added 2 commits September 29, 2026 01:20
…ts the local review uses

conventions.yml runs scripts/conventions.sh (read from central-ref, new input, default v2; this repository's own pull requests use their own copy) and claude-review.yml builds its brief with scripts/review-brief.sh, the code they held inline until now, unchanged: the brief comes out byte for byte the same. The local review and CI can no longer drift apart.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…own tests

local-review.sh --test runs it (never the review itself) against scratch repositories: no profile anywhere, a profile the workflow passes, quoted, or overridden, no commit, two commits without a title, a bad commit header, an empty or filled description, no origin remote, an unknown option. It found that a repository without an origin remote stopped the script, fixed here, and the profile is now read quoted or not, with portable patterns.

review-brief.sh --test checks what the reviewer is shown: the description, the diff, a rewritten file as new content, binaries and lock files listed but hidden, the repository's rules only above a low floor, the incremental scope, a diff over the limit. policy.py --test checks the floor, trust, auto-merge, model, budget and changes rules against the organisation's default policy. The scripts job runs all three, and AGENTS.md says that a problem a review finds comes with the test that would have caught it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dilux-bot dilux-bot Bot added risk:high Set by the Claude review complexity:medium Set by the Claude review type:fix The kind of change, read from the diff by the Claude review labels Sep 29, 2026
@dilux-bot

dilux-bot Bot commented Sep 29, 2026

Copy link
Copy Markdown
Contributor

Claude review · risk high · complexity medium · type fix

Full review. The inline conventions and brief code moves into the shared scripts. conventions.yml now reads scripts/conventions.sh from DiluxOne/.github at a new central-ref input; for this repository it reads the pull request's own head. claude-review.yml runs scripts/review-brief.sh from central-ref, which for this repository is main. The three untested scripts gain --test cases, now wired into the scripts job. local-review.sh no longer stops in a repository without an origin remote. Checks: the triggers stay pull_request, so nothing runs a fork's code with secrets. The brief script for this repository's reviews still comes from main. The env contract matches what the Brief step passes. README, CONTRIBUTING and the header comments were updated in the same PR. The test counts in the description (11, 15, 23) match the code. I could not run the self-tests here because the sandbox denied it; the description says they are green. No blocker or major problem. The remaining points are minor: profile detection now stops at a profile: line with no literal value, versions can drift when a caller pins the workflow somewhere other than central-ref, and one test case is noisy. Type is fix: besides the refactor and the tests, it corrects the local-review.sh crash when there is no origin remote.

  • minor scripts/local-review.sh:635: Profile detection takes the first profile: line even with no literal value (an input definition, ${{ inputs.profile }}), so it gives general; the old pattern skipped those lines.
  • minor .github/workflows/conventions.yml:390: central-ref defaults to v2 whatever ref the workflow is pinned at: a caller on a SHA or an older tag runs a different conventions.sh. Documented, not enforced.
  • minor scripts/local-review.sh:593: In the self-test, eval "$setup" runs with errexit off (inside $( ) && || ), so a failing setup goes unnoticed; the origin case also passes --no-claude twice.

Policy floor: high (touches high-risk paths: .github/workflows/claude-review.yml, .github/workflows/conventions.yml, .github/workflows/pull-request.yml, AGENTS.md, CONTRIBUTING.md …). Reviewed 0c9ab10 (whole pull request; review 1 of 5 automatic). Author trusted for auto-merge: true.

🤖 AI review · claude-opus-5-5 (Anthropic) · $0.51, 10 turns

@soydiloreto
soydiloreto merged commit a698278 into main Sep 29, 2026
6 checks passed
@soydiloreto
soydiloreto deleted the refactor/workflows-use-shared-scripts branch September 29, 2026 01:29
soydiloreto added a commit that referenced this pull request Oct 1, 2026
…t catches a broken setup (#20)

## 📝 What changes

Five small fixes to the local review, left over from #16 and #28.

- **A `profile:` it cannot read says so.** A workflow that passes the
profile as an expression (or anything that is not a plain name) silently
became `general`, so the local review could differ from CI's. It now
prints that the review uses `general` and points at `--profile`. A
comment after the value (`profile: plugin-wp # the stack`) is read
correctly.
- **The self-test catches a broken setup.** `test_case` built its
scratch repository inside `$( … ) && …`, where errexit is off, so a
setup step that failed went unnoticed. The setup runs in a shell of its
own with `-euo pipefail`, and a failure is reported.
- **Only a `profile:` with a value is read.** A bare `profile:` or a
`profile: { type: … }` map (an input's declaration, as in
`claude-review.yml`) is skipped, so it neither hides the caller's value
nor raises the warning.
- **One case passed `--no-claude` twice** (`test_case` always adds it).
- **`central-ref` follows a pinned `uses:`.** The README and the header
of `claude-review.yml` say that a caller pinning `uses:` to a version
passes the same version as `central-ref`, or the workflow runs at its
pin while the policy and the brief follow `v2`.

## 💡 Why

The local review promises the same answer CI will give; a profile read
wrong breaks that without a word. A self-test that cannot fail its own
setup proves less than it seems.

## 🧪 How I tested it

- [x] `bash scripts/local-review.sh --test`: every case passes,
including three new ones (a profile with a comment after it, an input
declaring `profile:` before the caller's value, a profile that is not a
literal)

🤖 AI-generated · Claude Opus 5.5 (Anthropic)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

complexity:medium Set by the Claude review risk:high Set by the Claude review type:fix The kind of change, read from the diff by the Claude review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant