Skip to content

Commit a232b9e

Browse files
committed
Merge remote-tracking branch 'origin/main' into jg-codex/63-release-oidc
* origin/main: Add compatibility matrix and canary signal (#83) Document runtime versioning policy and live backlog pointers (#79) Add Flight client error path coverage (#78) Document release dist-tag policy and artifact parity checks (#75) Allow artifact verifier to accept covering root peer ranges (#95) Add release artifact verification gate (#77) Apply React 19.0.7 RSC reply-decode DoS fixes (CVE-2026-23869, CVE-2026-23870) to vendored runtime (#86) Harden dependency and Claude automation (#76) Make PR skill workflows discoverable (#88) Extract and own the webpack RSC plugin as TypeScript source (#87) Add packed-tarball E2E pipeline suite: webpack+rspack → Flight → SSR HTML → hydration (#85) Docs: Option 5 stock npm runtime go/no-go decision (#55 spike) (#80) # Conflicts: # docs/releasing.md
2 parents 2fcafaa + 5ce7134 commit a232b9e

66 files changed

Lines changed: 6119 additions & 494 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/skills/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ models the skills point to.
99
Invoke a skill with its `$name` (e.g. `$pr-batch`, `$plan-pr-batch`, `$adversarial-pr-review`) or the
1010
matching Claude Code slash command.
1111

12+
For the maintainer-facing guide to choosing and running these skills, see
13+
[`internal/contributor-info/agent-pr-batch-skills.md`](../../internal/contributor-info/agent-pr-batch-skills.md).
14+
For the workflow adoption and retargeting checklist, see
15+
[`internal/contributor-info/agent-workflow-adoption.md`](../../internal/contributor-info/agent-workflow-adoption.md).
16+
1217
## Adaptation status
1318

1419
The originals assume a Ruby/Rails monorepo (rspec, rubocop, rake, shakapacker, a Pro tier, a

.github/dependabot.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: npm
4+
directory: /
5+
schedule:
6+
interval: weekly
7+
groups:
8+
root-dev-minor-patch:
9+
dependency-type: development
10+
patterns:
11+
- '*'
12+
update-types:
13+
- minor
14+
- patch
15+
16+
- package-ecosystem: npm
17+
directory: /scripts/react-upgrade
18+
schedule:
19+
interval: weekly
20+
groups:
21+
react-upgrade-minor-patch:
22+
patterns:
23+
- '*'
24+
update-types:
25+
- minor
26+
- patch
27+
28+
- package-ecosystem: github-actions
29+
directory: /
30+
schedule:
31+
interval: weekly
32+
groups:
33+
github-actions:
34+
patterns:
35+
- '*'
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Verify package artifacts
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- main
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
verify-artifacts:
14+
runs-on: ubuntu-latest
15+
timeout-minutes: 15
16+
steps:
17+
# Pinned immutable actions/checkout release SHA verified via git ls-remote.
18+
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd
19+
- name: Use Node.js
20+
# Pinned immutable actions/setup-node release SHA verified via git ls-remote.
21+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
22+
with:
23+
node-version: '20.x'
24+
cache: yarn
25+
- name: Install packages using yarn
26+
run: yarn --frozen-lockfile
27+
- name: Verify package artifacts
28+
run: yarn verify:artifacts

.github/workflows/claude-code-review.yml

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ on:
66

77
jobs:
88
claude-review:
9+
if: |
10+
!(
11+
startsWith(github.event.pull_request.title, 'Release react-on-rails-rsc ') ||
12+
startsWith(github.event.pull_request.title, 'Stamp CHANGELOG and package version for ') ||
13+
(
14+
startsWith(github.event.pull_request.title, 'Prepare ') &&
15+
endsWith(github.event.pull_request.title, ' changelog')
16+
)
17+
)
918
runs-on: ubuntu-latest
1019
permissions:
1120
contents: read
@@ -19,9 +28,24 @@ jobs:
1928
with:
2029
fetch-depth: 1
2130

31+
- name: Detect Claude review workflow changes
32+
id: claude-workflow-changes
33+
env:
34+
GH_TOKEN: ${{ github.token }}
35+
PR_NUMBER: ${{ github.event.pull_request.number }}
36+
REPO: ${{ github.repository }}
37+
run: |
38+
changed_files="$(gh api "repos/${REPO}/pulls/${PR_NUMBER}/files" --paginate --jq '.[].filename')"
39+
if printf '%s\n' "$changed_files" | grep -Fx '.github/workflows/claude-code-review.yml'; then
40+
echo "changed=true" >> "$GITHUB_OUTPUT"
41+
else
42+
echo "changed=false" >> "$GITHUB_OUTPUT"
43+
fi
44+
2245
- name: Run Claude Code Review
46+
if: steps.claude-workflow-changes.outputs.changed != 'true'
2347
id: claude-review
24-
uses: anthropics/claude-code-action@v1
48+
uses: anthropics/claude-code-action@0cb4f3e5e764d2e00407d29b6bf0aa9df0976d88 # v1
2549
with:
2650
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
2751
prompt: |

.github/workflows/claude.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ jobs:
3434

3535
- name: Run Claude Code
3636
id: claude
37-
uses: anthropics/claude-code-action@v1
37+
uses: anthropics/claude-code-action@0cb4f3e5e764d2e00407d29b6bf0aa9df0976d88 # v1
3838
with:
3939
github_token: ${{ github.token }}
4040
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
@@ -52,4 +52,3 @@ jobs:
5252
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
5353
# or https://code.claude.com/docs/en/cli-reference for available options
5454
# claude_args: '--allowed-tools Bash(gh pr:*)'
55-
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
name: Compatibility matrix
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- main
8+
schedule:
9+
- cron: '23 10 * * 1'
10+
workflow_dispatch:
11+
12+
permissions:
13+
contents: read
14+
15+
concurrency:
16+
group: compatibility-matrix-${{ github.event.pull_request.number || github.ref }}
17+
cancel-in-progress: true
18+
19+
jobs:
20+
compatibility:
21+
if: github.event_name != 'schedule'
22+
name: ${{ matrix.label }}
23+
runs-on: ubuntu-latest
24+
timeout-minutes: 30
25+
strategy:
26+
fail-fast: false
27+
matrix:
28+
include:
29+
- label: React 19.0.4 / webpack 5.59.0 + rspack 1.x / Node 20
30+
node-version: '20.x'
31+
react-version: '19.0.4'
32+
react-dom-version: '19.0.4'
33+
types-react-version: '19.0.4'
34+
types-react-dom-version: '19.0.4'
35+
webpack-version: '5.59.0'
36+
rspack-version: '1.x'
37+
node-options: --openssl-legacy-provider
38+
- label: React 19.0.4 / webpack latest 5.x + rspack 1.x / Node 22
39+
node-version: '22.x'
40+
react-version: '19.0.4'
41+
react-dom-version: '19.0.4'
42+
types-react-version: '19.0.4'
43+
types-react-dom-version: '19.0.4'
44+
webpack-version: '^5.0.0'
45+
rspack-version: '1.x'
46+
- label: React 19.2.x / webpack 5.59.0 + rspack 1.x / Node 22
47+
node-version: '22.x'
48+
react-version: '~19.2.0'
49+
react-dom-version: '~19.2.0'
50+
types-react-version: '~19.2.0'
51+
types-react-dom-version: '~19.2.0'
52+
webpack-version: '5.59.0'
53+
rspack-version: '1.x'
54+
node-options: --openssl-legacy-provider
55+
- label: React 19.2.x / webpack latest 5.x + rspack 1.x / Node 20
56+
node-version: '20.x'
57+
react-version: '~19.2.0'
58+
react-dom-version: '~19.2.0'
59+
types-react-version: '~19.2.0'
60+
types-react-dom-version: '~19.2.0'
61+
webpack-version: '^5.0.0'
62+
rspack-version: '1.x'
63+
64+
steps:
65+
# Pinned immutable actions/checkout@v5 release SHA verified via git ls-remote.
66+
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd
67+
- name: Use Node.js
68+
# Pinned immutable actions/setup-node@v4 release SHA verified via git ls-remote.
69+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
70+
with:
71+
node-version: ${{ matrix.node-version }}
72+
cache: yarn
73+
- name: Install matrix packages without changing yarn.lock
74+
env:
75+
COMPAT_LABEL: ${{ matrix.label }}
76+
COMPAT_REACT: ${{ matrix.react-version }}
77+
COMPAT_REACT_DOM: ${{ matrix.react-dom-version }}
78+
COMPAT_REACT_SERVER_DOM_WEBPACK: ${{ matrix.react-version }}
79+
COMPAT_TYPES_REACT: ${{ matrix.types-react-version }}
80+
COMPAT_TYPES_REACT_DOM: ${{ matrix.types-react-dom-version }}
81+
COMPAT_WEBPACK: ${{ matrix.webpack-version }}
82+
COMPAT_RSPACK: ${{ matrix.rspack-version }}
83+
run: node scripts/prepare-compatibility-install.cjs
84+
- name: Build package artifacts
85+
env:
86+
NODE_OPTIONS: ${{ matrix.node-options || '' }}
87+
run: yarn build
88+
- name: Run unit and integration tests
89+
env:
90+
NODE_OPTIONS: ${{ matrix.node-options || '' }}
91+
run: yarn test
92+
- name: Record matrix result
93+
if: always()
94+
run: |
95+
{
96+
echo "### Test command"
97+
echo
98+
echo "- Command: \`yarn build && yarn test\`"
99+
echo "- Result: \`${{ job.status }}\`"
100+
} >> "$GITHUB_STEP_SUMMARY"
101+
102+
canary:
103+
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
104+
name: React canary signal
105+
runs-on: ubuntu-latest
106+
timeout-minutes: 30
107+
continue-on-error: true
108+
steps:
109+
# Pinned immutable actions/checkout@v5 release SHA verified via git ls-remote.
110+
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd
111+
- name: Use Node.js
112+
# Pinned immutable actions/setup-node@v4 release SHA verified via git ls-remote.
113+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
114+
with:
115+
node-version: '22.x'
116+
cache: yarn
117+
- name: Install canary packages without changing yarn.lock
118+
env:
119+
COMPAT_LABEL: React canary / webpack latest 5.x / rspack latest 1.x / Node 22
120+
COMPAT_REACT: canary
121+
COMPAT_REACT_DOM: canary
122+
COMPAT_REACT_SERVER_DOM_WEBPACK: canary
123+
COMPAT_WEBPACK: '^5.0.0'
124+
COMPAT_RSPACK: 1.x
125+
# COMPAT_TYPES_REACT / COMPAT_TYPES_REACT_DOM intentionally omitted:
126+
# canary @types packages are not reliably published; stable types remain.
127+
run: node scripts/prepare-compatibility-install.cjs
128+
- name: Build package artifacts
129+
run: yarn build
130+
- name: Run canary unit and integration tests
131+
run: yarn test
132+
- name: Record canary result
133+
if: always()
134+
run: |
135+
{
136+
echo "### Canary signal"
137+
echo
138+
echo "- Command: \`yarn test\`"
139+
echo "- Result: \`${{ job.status }}\`"
140+
echo "- This scheduled canary is signal-only; failures do not block required compatibility checks."
141+
} >> "$GITHUB_STEP_SUMMARY"

.github/workflows/e2e-tests.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: Run E2E pipeline tests
2+
on: [pull_request]
3+
4+
jobs:
5+
e2e-tests:
6+
runs-on: ubuntu-latest
7+
steps:
8+
- uses: actions/checkout@v5
9+
- name: Use Node.js
10+
uses: actions/setup-node@v4
11+
with:
12+
node-version: '20.x'
13+
- name: Install packages using yarn
14+
run: yarn
15+
# Packs the npm tarball, installs it into a disposable consumer
16+
# project, and runs the webpack+rspack -> Flight -> SSR -> hydration
17+
# pipeline suite (scripts/e2e/run.sh).
18+
- run: yarn test:e2e

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22

33
All notable changes to this package will be documented in this file.
44

5+
## [Unreleased]
6+
7+
### Changed
8+
- Ported the webpack RSC plugin from the vendored built JavaScript artifact (`src/react-server-dom-webpack/cjs/react-server-dom-webpack-plugin.js`) to first-class TypeScript source at `src/webpack/RSCWebpackPlugin.ts`, preserving full behavior parity (server manifest emission, CSS/JS chunk scanning, runtime-chunk filtering, dependency-type chunk-group manifest construction with eager-import fallback, duplicate-package runtime detection, and hot-update CSS exclusion). The `./WebpackPlugin`, `./WebpackLoader`, and `./RSCReferenceDiscoveryPlugin` exports are unchanged; the vendored plugin file remains in the package but is no longer used by any export path. ([#87])
9+
10+
### Fixed
11+
- Updated the vendored `react-server-dom-webpack` runtime from the React 19.0.4 security level to 19.0.7, applying the upstream React Server Components reply-decoding denial-of-service fixes for CVE-2026-23869 (GHSA-479c-33wc-g2pg) and CVE-2026-23870 (GHSA-rv78-f8rc-xrxh) while preserving the in-repo Flight CSS hint behavior. Note: the upstream CVE-2026-23869 fix changes the reply wire format for nested `FormData`, so client and server must both run the patched runtime (both are shipped together in this package); pairing with a pre-19.0.5 `react-server-dom-webpack` on the other side silently drops nested `FormData` entries. ([#86])
12+
513
## [19.0.5-rc.7] - 2026-06-09
614

715
### Added
@@ -80,3 +88,5 @@ All notable changes to this package will be documented in this file.
8088
[19.0.5-rc.1]: https://github.com/shakacode/react_on_rails_rsc/releases/tag/19.0.5-rc.1
8189

8290
[#52]: https://github.com/shakacode/react_on_rails_rsc/pull/52
91+
[#86]: https://github.com/shakacode/react_on_rails_rsc/pull/86
92+
[#87]: https://github.com/shakacode/react_on_rails_rsc/pull/87

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,30 @@ This package provides internal tooling for React Server Components integration:
1717
- Webpack loader for bundling server components
1818
- Client/server utilities for RSC rendering
1919

20+
## Versioning
21+
22+
The package `major.minor` tracks the React runtime line it ships or requires.
23+
See [`docs/versioning.md`](docs/versioning.md) for peer dependency,
24+
prerelease, dist-tag, and runtime-strategy policy.
25+
2026
## Releasing
2127

2228
Release this package from `main` using the changelog-driven workflow in
2329
[`docs/releasing.md`](docs/releasing.md). Run `yarn release:dry-run` before
2430
`yarn release`.
2531

32+
## Compatibility Policy
33+
34+
The package peer dependencies are the current source of truth for supported
35+
React and webpack ranges. CI also runs a focused compatibility matrix covering
36+
React 19.0.4 and 19.2.x, Node.js 20 and 22, webpack 5.59.0 and latest 5.x, and
37+
rspack latest 1.x. A weekly React canary job is signal-only and is allowed to
38+
fail while upstream canary APIs move; review its GitHub Actions summary for
39+
early warnings.
40+
41+
A formal versioning policy is tracked in
42+
[#70](https://github.com/shakacode/react_on_rails_rsc/issues/70).
43+
2644
## Support
2745

2846
For questions about React Server Components:

0 commit comments

Comments
 (0)