feat: bulk-install-claude-review.sh for smartwatermelon fleet - #69
Conversation
Closes the workflow-templates gap for the smartwatermelon user account. Since GitHub's `workflow-templates/` picker is organization-only, repos under `smartwatermelon` (a user account) never see the org-default stub in their Actions UI. The script opens install/refresh PRs to roll the canonical caller stub across the fleet. Behavior: - Dry-run by default; --apply to actually open PRs. - Classifies each repo: CURRENT / STALE / MISSING / CUSTOMIZED / LOCAL. CUSTOMIZED and LOCAL are skipped automatically. - Idempotent: re-running on a clean fleet produces no PRs. - Target version is derived from the @v… pin in smartwatermelon/.github/workflow-templates/claude-blocking-review.yml, so bumping that file is the single fleet-wide trigger. - PRs carry the [skip-claude-review: bulk-install] tag so the blocking-review workflow doesn't gate its own install/bump PR. Tested via dry-run against the live fleet: - 14 CURRENT, 4 STALE (mix of @V3 floating and @v2.0.2), 1 LOCAL (github-workflows itself), 1 MISSING (.github). Plan: docs/plans/2026-04-30-bulk-install-smartwatermelon-fleet.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Five issues raised by code-reviewer on the prior commit: 1. Validate fetch_file output for the per-repo caller file (mirrors the canonical-fetch validation that already existed). Empty content now classifies as ERROR instead of falling through and misclassifying as "no @Version pin found". 2. Reorder customization check before pin comparison. Previously, a repo with caller-side customizations on a stale pin would get its pin sed-bumped without flagging the customizations. New behavior matches what the README claimed: any customized caller is skipped for human review regardless of pin status. 3. Tighten extract_pin regex from `[^[:space:]]+` to `[A-Za-z0-9._/-]+` so trailing punctuation (commas, quotes from quoted YAML values) doesn't get captured into the pin. Same fix applied to the canonical-version extraction. 4. Validate --only argument: error when missing or starts with `--`. Previously `./script --only --apply` would silently iterate every repo because ONLY="" fell through to the list-all-repos branch. 5. Exit non-zero when REPOS_ERROR is non-empty. Surfaces fetch failures to CI/cron/automation callers. CUSTOMIZED is intentionally not an error — it's a human-review signal. README CUSTOMIZED row updated to reflect "regardless of pin" behavior. All verified via shellcheck -S info clean and live --dry-run against the smartwatermelon fleet. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes #68. The `has_customization` regex used `\s` while the rest of the script and `claude-review-audit.sh` consistently use POSIX `[[:space:]]`. Replaced for portability and to match the convention. Classification still produces identical results on the live fleet. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
<!-- claude-blocking-review sha=85e048f358fa640f52a66a2b8bdc7b54c8b0a529 run=25178990775 --> This PR adds a new Checked for: shell injection, hardcoded credentials, reliability regressions, data loss, silent async failures.
VERDICT: PASS |
Closes #66. TARGET_VERSION extraction skipped strip_comments while extract_pin used it — inconsistent. A commented-out @Version in the canonical stub could be picked up as the target. No real-world hit (the canonical file has no such comment), but the inconsistency is a footgun. Hoists strip_comments to before the canonical-fetch block and reuses it. Removes the duplicate definition from the helpers section. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
Two fixes from pre-push review: Closes #71: command substitution \$() strips trailing newlines from captured file content. Both CANONICAL_CONTENT and current_content lose their trailing \n, so the PUT-uploaded content was missing a final newline — every install/bump PR would produce a file failing yamllint's no-new-line-at-end-of-file rule. Same issue I just fixed in smartwatermelon/.github PR #7. Fixed by switching the upload encoder from `printf "%s"` to `printf "%s\n"`. Closes #70: install branch was named `claude/install-blocking- review` with no version suffix. If a re-run encountered an already-open install PR, the git ref creation would fail. Renamed to `claude/install-blocking-review-\${TARGET_VERSION}` to match the bump-branch convention and let re-runs slide past existing same-version PRs. Issues #67, #72, #73 remain open as tracked tech-debt — they are real but lower-priority edge cases that can be addressed in follow-up PRs (mixed local/remote actions caller, transient gh-API-failure misclassification, .github meta-repo opt-out). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
<!-- claude-blocking-review sha=b741a56a9c15e754a888ca40fe58d713e6ba9476 run=25179472661 --> No blocking issues found. The script constructs JSON via VERDICT: PASS |
|
No blocking issues found. The PR adds a README section and a new bulk-install-claude-review.sh utility script with no changes to the existing claude-blocking-review.yml workflow.
VERDICT: PASS |
Summary
Adds
bulk-install-claude-review.shat the repo root. Closes the workflow-templates gap forsmartwatermelon, which is a user account — GitHub'sworkflow-templates/picker is org-only, so the templates insmartwatermelon/.github/workflow-templates/never appear in the picker UI forsmartwatermelon/*repos. This script opens install/refresh PRs to roll the canonical caller stub across the fleet instead.Behavior:
--applyopens PRs.CURRENT/STALE/MISSING/CUSTOMIZED/LOCAL/ERROR.@v…pin insmartwatermelon/.github/workflow-templates/claude-blocking-review.yml. Bumping that template is the single fleet-wide trigger.[skip-claude-review: bulk-install]so the blocking-review workflow doesn't gate its own install/bump PR.Live dry-run results against the smartwatermelon fleet right now:
Two commits:
--onlyargument, exit non-zero on ERROR class.Plan:
docs/plans/2026-04-30-bulk-install-smartwatermelon-fleet.md.Test plan
shellcheck -S infoclean--only --apply(missing arg) errors out instead of silently iterating fleet--applyrollout still pending — bellwether 1-2 repos before fleet-wide🤖 Generated with Claude Code