Skip to content

Commit 9f5d7f4

Browse files
committed
Merge remote-tracking branch 'origin/main' into jg/docs-sidebar-pro-pages
* origin/main: Fix initial page startup race for late-loading client bundles (#3151) chore: apply prettier formatting to tracked docs files (#3153) docs: comprehensive RSC API documentation and registration consolidation (#3140) Split rspec-package-tests into parallel generator/unit shards (#3134) fix: add concurrency groups to long-running CI workflows (#3133) refactor: add RenderRequest, JsCodeBuilder, and RenderingStrategy abstractions (#3094) fix: address deferred review items from PR #2849 (#3093) Add complimentary OSS license policy for React on Rails Pro (#3123) fix: centralize CI docs-only detection and add CLI flag validation (#3091) refactor: replace stub-throw + Object.assign with capability-based composition (#3096) Enhance address-review with parallel fixes, self-review, and Greptile verification (#3121) fix: Doctor no longer fails custom projects for missing bin/dev (#3117) fix: cap webpack <5.106.0 to prevent ExecJS SSR breakage (#3095) Add Rspack + RSC compatibility tests and documentation (#1828) (#3120) Add error scenarios hub and test pages (#2497) docs: document polyfill requirements for web-targeted server bundles (#3092) docs: RSC integration pitfalls from tutorial app (#3087) docs: fix render function/helper API documentation (#3088) Doctor: accept TS/TSX server bundle suffixes (#3111) feat: add CI guard requiring sidebar updates when adding docs (#3089)
2 parents a7a20bc + 4eb8364 commit 9f5d7f4

125 files changed

Lines changed: 5317 additions & 1293 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.agents/workflows/address-review.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ Execution flow when terminal access is available:
112112
- If a claim is wrong, classify it as `SKIPPED` and say why.
113113
- Preserve comment IDs and thread IDs for later replies and thread resolution.
114114
- Treat actionable review summary bodies as normal feedback to classify (`MUST-FIX`/`DISCUSS` as appropriate); skip only boilerplate or status-only summaries.
115+
- **Claim verification**: Before finalizing `MUST-FIX` classification, verify the reviewer's factual claims against the actual codebase. If local code inspection confirms the code already handles the concern (claim is demonstrably wrong), classify as `SKIPPED` per the rule above. If the evidence is ambiguous or you have only partial confidence the claim is wrong, downgrade to `DISCUSS` and note the discrepancy. If you have access to AI-powered codebase search tools (e.g., Greptile), use them to cross-reference claims for additional confidence, but treat their output as a signal — corroborated claims stay `MUST-FIX`, clearly contradicted claims go to `SKIPPED`, and inconclusive results go to `DISCUSS`.
115116
- Track only `MUST-FIX` items as your working checklist.
116117
- Use one checklist entry per must-fix item or deduplicated issue.
117118
- Use the subject format: `"{file}:{line} - {comment_summary} (@{username})"`.
@@ -151,7 +152,9 @@ Execution flow when terminal access is available:
151152
- Resolve threads only when the issue is actually handled or explicitly declined with my approval:
152153
`gh api graphql -f query='mutation($threadId:ID!) { resolveReviewThread(input:{threadId:$threadId}) { thread { id isResolved } } }' -f threadId="<THREAD_ID>"`
153154
- Do not resolve anything still in progress or uncertain.
155+
- **Self-review gate**: After making all code changes but before committing, review the diff for issues introduced by the fixes themselves. Check for correctness bugs, style violations, and inconsistencies with surrounding code. Fix critical issues immediately. This prevents new review cycles caused by the fixes. If you have access to a code-review agent or tool, use it; otherwise, do a manual diff review.
154156
- Ask for push confirmation before running `git push`.
157+
- **Parallel fixes**: When there are 2+ items to fix that touch different files with no logical dependencies, process them in parallel if your environment supports concurrent execution (e.g., sub-agents, background tasks). Items in the same file or with cross-file dependencies must be fixed sequentially. Instruct each sub-agent **not to commit** — all changes must remain unstaged so the self-review gate can run on the combined diff. After parallel fixes complete, verify no conflicts exist between the changes by checking whether any sub-agents touched the same files (`git diff --name-only`).
155158
156159
9. Create follow-up issue (when `f+i` or `m` is chosen):
157160
- Use `gh issue create --repo "${REPO}"` with title "Follow-up: Review feedback from PR #N"

.claude/commands/address-review.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,18 @@ Triage rules:
151151
- Preserve the original review comment ID and thread ID when available so the command can reply to the correct place and resolve the correct thread later.
152152
- Treat actionable review summary bodies as normal feedback to classify (`MUST-FIX`/`DISCUSS` as appropriate); skip only boilerplate or status-only summaries.
153153

154+
**Greptile claim verification:**
155+
156+
When Greptile MCP tools are available (`mcp__plugin_greptile_greptile__*`), cross-reference reviewer claims against Greptile's codebase analysis before finalizing triage classifications:
157+
158+
1. For each reviewer comment that asserts a factual claim about the codebase (e.g., "this function doesn't handle null", "this breaks the existing API contract"), query Greptile to verify the claim:
159+
- Use `mcp__plugin_greptile_greptile__search_greptile_comments` to find prior Greptile analysis of the same code area
160+
- Use `mcp__plugin_greptile_greptile__search_custom_context` to check project-specific context that may confirm or contradict the claim
161+
2. If Greptile's analysis clearly contradicts the reviewer's claim and local code inspection confirms the code already handles the concern, classify as `SKIPPED` per the existing triage rule (claim is demonstrably wrong). If the analysis is inconclusive or only partially contradicts the claim, downgrade to `DISCUSS` and note the discrepancy (e.g., "Greptile analysis suggests current handling may be correct — needs verification").
162+
3. If Greptile's analysis corroborates the reviewer's claim, keep the `MUST-FIX` classification with higher confidence.
163+
4. If Greptile has no relevant data, fall back to local verification only.
164+
5. Do not block triage on Greptile availability — if the tools are not configured or the API fails, proceed with local verification alone.
165+
154166
## Step 6: Create Todo List
155167

156168
Create a task list with TodoWrite containing **only the `MUST-FIX` items**:
@@ -250,6 +262,34 @@ When addressing items, after completing each selected item (whether `MUST-FIX` o
250262
If the user selects `DISCUSS` items to address, treat them the same as `MUST-FIX`: make the code change, reply, and resolve the thread.
251263
If the user selects skipped/declined items for rationale replies, post those replies too.
252264

265+
**Parallel sub-agents for independent fixes:**
266+
267+
When there are 2+ items to fix that touch different files with no logical dependencies between them, use the Task tool to spawn parallel sub-agents for faster execution:
268+
269+
1. Group items by file path. Items in different files with no cross-file dependencies (e.g., a type change in file A that affects callers in file B) are independent.
270+
2. For each independent group, spawn a sub-agent via the Task tool with:
271+
- The full review comment text and context
272+
- The file path and line number
273+
- Instructions to make the specific fix and run any relevant file-level checks
274+
- A reminder not to modify files outside the assigned scope
275+
- An explicit instruction **not to commit** the changes — leave all modifications unstaged so the orchestrator can run the self-review gate on the combined diff before committing
276+
3. After all sub-agents complete, verify there are no conflicts between their changes by checking whether any sub-agents touched the same files (e.g., `git diff --name-only` to list changed files, then check for overlaps).
277+
4. If conflicts exist, resolve them sequentially before proceeding.
278+
5. If a sub-agent fails (crashes, hits a tool error, or produces an incorrect edit), fall back to fixing that item sequentially in the parent agent before proceeding.
279+
6. Items that touch the same file or have logical dependencies must be fixed sequentially, not in parallel.
280+
7. If only 1 item needs fixing or all items are in the same file, skip parallel dispatch and fix sequentially as before.
281+
282+
**Self-review gate before pushing:**
283+
284+
After making all code changes but before committing, run a self-review on the diff to prevent new review cycles caused by the fixes themselves:
285+
286+
1. Use the Task tool to launch a code-review sub-agent (e.g., `pr-review-toolkit:code-reviewer` if available, or a general-purpose review agent) against the uncommitted changes (`git diff`).
287+
2. The self-review should check for: correctness bugs introduced by the fixes, style violations against project standards (CLAUDE.md, linter rules), missing error handling, and inconsistencies with surrounding code.
288+
3. If the self-review finds critical issues (bugs, security problems, or clear correctness errors), fix them immediately before committing. These are issues that would likely trigger a new review round.
289+
4. If the self-review finds only minor issues (style nits, naming suggestions), note them but proceed — do not block the push for optional improvements.
290+
5. If the self-review catches and fixes additional issues, mention this in the commit message (e.g., "also fixed: null check in adjacent error path caught by self-review").
291+
6. Skip the self-review gate for non-code actions (rationale replies, follow-up issue creation, thread resolution).
292+
253293
**For issue comments (general PR comments):**
254294

255295
```bash

.github/workflows/benchmark.yml

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,7 @@ on:
5151
push:
5252
branches:
5353
- main
54-
paths-ignore:
55-
- '**.md'
56-
- 'AGENTS_USER_GUIDE.md'
57-
- 'docs/**'
58-
- 'llms.txt'
59-
- 'llms-full.txt'
60-
- '.lychee.toml'
54+
# Always trigger on main; docs-only detection handles skipping heavy jobs
6155
pull_request:
6256
types: [opened, synchronize, reopened, labeled]
6357
paths-ignore:
@@ -96,17 +90,50 @@ env:
9690
RAILS_MIN_THREADS: ${{ github.event.inputs.rails_threads || 3 }}
9791

9892
jobs:
93+
detect-changes:
94+
permissions:
95+
contents: read
96+
actions: read
97+
runs-on: ubuntu-22.04
98+
outputs:
99+
docs_only: ${{ steps.detect.outputs.docs_only }}
100+
steps:
101+
- uses: actions/checkout@v4
102+
with:
103+
fetch-depth: 50
104+
persist-credentials: false
105+
- name: Detect relevant changes
106+
id: detect
107+
run: |
108+
BASE_REF="${{ github.event.pull_request.base.sha || github.event.before || 'origin/main' }}"
109+
script/ci-changes-detector "$BASE_REF"
110+
shell: bash
111+
- name: Guard docs-only main pushes
112+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
113+
uses: ./.github/actions/ensure-main-docs-safety
114+
with:
115+
docs-only: ${{ steps.detect.outputs.docs_only }}
116+
previous-sha: ${{ github.event.before }}
117+
99118
benchmark:
119+
needs: detect-changes
100120
# Run on: push to main, workflow_dispatch, or PRs with 'benchmark' label.
101121
# The 'full-ci' label is intentionally excluded — it controls test workflows,
102122
# not benchmarks. Use the dedicated 'benchmark' label to trigger perf runs on PRs.
103123
# See https://bencher.dev/docs/how-to/github-actions/#pull-requests for the extra pull_request condition
124+
# Skip docs-only pushes to main to avoid wasting CI resources on non-code changes.
104125
if: |
105-
github.event_name == 'push' ||
106-
github.event_name == 'workflow_dispatch' ||
107-
(
108-
github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository &&
109-
contains(github.event.pull_request.labels.*.name, 'benchmark')
126+
!(
127+
github.event_name == 'push' &&
128+
github.ref == 'refs/heads/main' &&
129+
needs.detect-changes.outputs.docs_only == 'true'
130+
) && (
131+
github.event_name == 'push' ||
132+
github.event_name == 'workflow_dispatch' ||
133+
(
134+
github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository &&
135+
contains(github.event.pull_request.labels.*.name, 'benchmark')
136+
)
110137
)
111138
runs-on: ubuntu-latest
112139
permissions:
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: Check Docs Sidebar
2+
3+
permissions:
4+
contents: read
5+
6+
on:
7+
push:
8+
branches: [main]
9+
paths:
10+
- 'docs/oss/**'
11+
- 'docs/pro/**'
12+
- 'docs/sidebars.ts'
13+
- 'docs/.sidebar-exclusions'
14+
- 'script/check-docs-sidebar'
15+
- '.github/workflows/check-docs-sidebar.yml'
16+
pull_request:
17+
paths:
18+
- 'docs/oss/**'
19+
- 'docs/pro/**'
20+
- 'docs/sidebars.ts'
21+
- 'docs/.sidebar-exclusions'
22+
- 'script/check-docs-sidebar'
23+
- '.github/workflows/check-docs-sidebar.yml'
24+
workflow_dispatch:
25+
26+
jobs:
27+
check-sidebar:
28+
runs-on: ubuntu-latest
29+
steps:
30+
- uses: actions/checkout@v4
31+
with:
32+
fetch-depth: 0
33+
persist-credentials: false
34+
35+
- name: Check new docs have sidebar entries
36+
env:
37+
BASE_REF: ${{ github.event.pull_request.base.sha || github.event.before || 'origin/main' }}
38+
run: script/check-docs-sidebar "$BASE_REF"

.github/workflows/examples.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ name: Generator tests # TODO needs to be duplicated for RoR Pro
33
permissions:
44
contents: read
55

6+
concurrency:
7+
group: ${{ github.event.pull_request.number && format('{0}-pr-{1}', github.workflow, github.event.pull_request.number) || format('{0}-{1}', github.workflow, github.sha) }}
8+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
9+
610
on:
711
push:
812
branches:

.github/workflows/gem-tests.yml

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@ name: Rspec test for gem
33
permissions:
44
contents: read
55

6+
concurrency:
7+
group: ${{ github.event.pull_request.number && format('{0}-pr-{1}', github.workflow, github.event.pull_request.number) || format('{0}-{1}', github.workflow, github.sha) }}
8+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
9+
610
on:
711
push:
812
branches:
913
- 'main'
10-
paths-ignore:
11-
- 'AGENTS_USER_GUIDE.md'
12-
- 'llms.txt'
13-
- 'llms-full.txt'
14+
# Always trigger on main; docs-only detection handles skipping heavy jobs
1415
pull_request:
1516
paths-ignore:
1617
- '**.md'
@@ -85,13 +86,16 @@ jobs:
8586
- id: set-matrix
8687
run: |
8788
# Determine if we should run full matrix (main or full-ci label)
89+
# Each Ruby version / dependency level is split into two shards:
90+
# generators – spec/react_on_rails/generators (heavy filesystem I/O)
91+
# unit – everything else under spec/react_on_rails
8892
if [[ "${{ github.ref }}" == "refs/heads/main" ]] || \
8993
[[ "${{ needs.detect-changes.outputs.has_full_ci_label }}" == "true" ]]; then
90-
# Full matrix: test both latest and minimum supported versions
91-
echo 'matrix={"include":[{"ruby-version":"3.4","dependency-level":"latest"},{"ruby-version":"3.2","dependency-level":"minimum"}]}' >> $GITHUB_OUTPUT
94+
# Full matrix: test both latest and minimum supported versions × 2 shards
95+
echo 'matrix={"include":[{"ruby-version":"3.4","dependency-level":"latest","shard":"generators"},{"ruby-version":"3.4","dependency-level":"latest","shard":"unit"},{"ruby-version":"3.2","dependency-level":"minimum","shard":"generators"},{"ruby-version":"3.2","dependency-level":"minimum","shard":"unit"}]}' >> $GITHUB_OUTPUT
9296
else
93-
# PR matrix: test only latest versions for fast feedback
94-
echo 'matrix={"include":[{"ruby-version":"3.4","dependency-level":"latest"}]}' >> $GITHUB_OUTPUT
97+
# PR matrix: test only latest versions for fast feedback × 2 shards
98+
echo 'matrix={"include":[{"ruby-version":"3.4","dependency-level":"latest","shard":"generators"},{"ruby-version":"3.4","dependency-level":"latest","shard":"unit"}]}' >> $GITHUB_OUTPUT
9599
fi
96100
97101
rspec-package-tests:
@@ -151,14 +155,22 @@ jobs:
151155
run: |
152156
echo "CI_DEPENDENCY_LEVEL=${{ matrix.dependency-level }}" >> $GITHUB_ENV
153157
- name: Run rspec tests
154-
run: cd react_on_rails && bundle exec rspec spec/react_on_rails
158+
env:
159+
SHARD: ${{ matrix.shard }}
160+
run: |
161+
cd react_on_rails
162+
if [[ "$SHARD" = "generators" ]]; then
163+
bundle exec rspec spec/react_on_rails/generators
164+
else
165+
bundle exec rspec spec/react_on_rails --exclude-pattern "**/generators/**"
166+
fi
155167
- name: Store test results
156168
uses: actions/upload-artifact@v4
157169
with:
158-
name: main-rspec-${{ github.run_id }}-${{ github.job }}-ruby${{ matrix.ruby-version }}-${{ matrix.dependency-level }}
170+
name: main-rspec-${{ github.run_id }}-${{ github.job }}-ruby${{ matrix.ruby-version }}-${{ matrix.dependency-level }}-${{ matrix.shard }}
159171
path: ~/rspec
160172
- name: Store artifacts
161173
uses: actions/upload-artifact@v4
162174
with:
163-
name: main-test-log-${{ github.run_id }}-${{ github.job }}-ruby${{ matrix.ruby-version }}-${{ matrix.dependency-level }}
175+
name: main-test-log-${{ github.run_id }}-${{ github.job }}-ruby${{ matrix.ruby-version }}-${{ matrix.dependency-level }}-${{ matrix.shard }}
164176
path: log/test.log

.github/workflows/integration-tests.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@ name: Integration Tests
33
permissions:
44
contents: read
55

6+
concurrency:
7+
group: ${{ github.event.pull_request.number && format('{0}-pr-{1}', github.workflow, github.event.pull_request.number) || format('{0}-{1}', github.workflow, github.sha) }}
8+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
9+
610
on:
711
push:
812
branches:
913
- 'main'
10-
paths-ignore:
11-
- 'AGENTS_USER_GUIDE.md'
12-
- 'llms.txt'
13-
- 'llms-full.txt'
14+
# Always trigger on main; docs-only detection handles skipping heavy jobs
1415
pull_request:
1516
paths-ignore:
1617
- '**.md'

.github/workflows/lint-js-and-ruby.yml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,7 @@ on:
77
push:
88
branches:
99
- 'main'
10-
paths-ignore:
11-
- 'AGENTS_USER_GUIDE.md'
12-
- 'llms.txt'
13-
- 'llms-full.txt'
10+
# Always trigger on main; docs-only detection handles skipping heavy jobs
1411
pull_request:
1512
paths-ignore:
1613
- '**.md'

.github/workflows/package-js-tests.yml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,7 @@ on:
77
push:
88
branches:
99
- 'main'
10-
paths-ignore:
11-
- 'AGENTS_USER_GUIDE.md'
12-
- 'llms.txt'
13-
- 'llms-full.txt'
10+
# Always trigger on main; docs-only detection handles skipping heavy jobs
1411
pull_request:
1512
paths-ignore:
1613
- '**.md'

.github/workflows/playwright.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@ name: Playwright E2E Tests
33
permissions:
44
contents: read
55

6+
concurrency:
7+
group: ${{ github.event.pull_request.number && format('{0}-pr-{1}', github.workflow, github.event.pull_request.number) || format('{0}-{1}', github.workflow, github.sha) }}
8+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
9+
610
on:
711
push:
812
branches: [main]
9-
paths-ignore:
10-
- 'AGENTS_USER_GUIDE.md'
11-
- 'llms.txt'
12-
- 'llms-full.txt'
13+
# Always trigger on main; docs-only detection handles skipping heavy jobs
1314
workflow_dispatch:
1415

1516
jobs:

0 commit comments

Comments
 (0)