shakapacker 9.6.0 → 9.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.claude/commands/address-review.md +206 -0
- data/.claude/commands/update-changelog.md +86 -49
- data/.github/workflows/claude-code-review.yml +1 -1
- data/CHANGELOG.md +24 -1
- data/README.md +2 -0
- data/Rakefile +5 -0
- data/docs/node_package_api.md +70 -0
- data/docs/releasing.md +25 -18
- data/docs/rspack.md +25 -1
- data/lib/shakapacker/env.rb +17 -3
- data/lib/shakapacker/runner.rb +2 -1
- data/lib/shakapacker/version.rb +1 -1
- data/package/configExporter/cli.ts +11 -0
- data/package/plugins/webpack.ts +6 -1
- data/package.json +5 -5
- data/test/package/bundlerUtils.rspack.test.js +46 -3
- data/test/package/configExporter.test.js +32 -0
- data/test/package/plugins/webpackSubresourceIntegrity.test.js +89 -0
- data/test/package/rspack/index.test.js +43 -1
- data/yarn.lock +92 -225
- metadata +6 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 518eb8673a021c5e18507ebc14ba593128288ddb9f735390581bd998d1f33715
|
|
4
|
+
data.tar.gz: 3c2c532321d8c79e4374fbbe0854319d6ebd89df33557e21a4ce6e4ec322cc7c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 26414fbf14fe2d835262ee5a6d2b46a9e50c76eee0391a0d859b60ee60f8899a87fa0e8c9d39aa651a8eadecb37639cd9684e775dd2004a55f83bb1f8aa4647e
|
|
7
|
+
data.tar.gz: 13f248afecdaa3ef579a20f7abf7ed592db788c2e5aa6b119a4940429b1e3c6f0bae263b985abe78e6ed0217116c6eeb9483c252f3a38bddd33e1c6e4533cc2c
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Fetch GitHub PR review comments, triage them, create todos for must-fix items, reply to comments, and resolve addressed threads
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Fetch review comments from a GitHub PR in this repository, triage them, and create a todo list only for items worth addressing.
|
|
6
|
+
|
|
7
|
+
# Instructions
|
|
8
|
+
|
|
9
|
+
## Step 1: Determine the Repository
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner)
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
If this command fails, ensure `gh` CLI is installed and authenticated (`gh auth status`).
|
|
16
|
+
|
|
17
|
+
## Step 2: Parse User Input
|
|
18
|
+
|
|
19
|
+
Extract the PR number and optional review/comment ID from the user's message:
|
|
20
|
+
|
|
21
|
+
**Supported formats:**
|
|
22
|
+
|
|
23
|
+
- PR number only: `12345`
|
|
24
|
+
- PR URL: `https://github.com/org/repo/pull/12345`
|
|
25
|
+
- Specific PR review: `https://github.com/org/repo/pull/12345#pullrequestreview-123456789`
|
|
26
|
+
- Specific issue comment: `https://github.com/org/repo/pull/12345#issuecomment-123456789`
|
|
27
|
+
|
|
28
|
+
**URL parsing:**
|
|
29
|
+
|
|
30
|
+
- Extract org/repo from URL path: `github.com/{org}/{repo}/pull/{PR_NUMBER}`
|
|
31
|
+
- Extract fragment ID after `#` (e.g., `pullrequestreview-123456789` → `123456789`)
|
|
32
|
+
- If a full GitHub URL is provided, use the org/repo from the URL instead of the current repo
|
|
33
|
+
|
|
34
|
+
## Step 3: Fetch Review Comments
|
|
35
|
+
|
|
36
|
+
**If a specific issue comment ID is provided (`#issuecomment-...`):**
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
gh api repos/${REPO}/issues/comments/{COMMENT_ID} | jq '{body: .body, user: .user.login, html_url: .html_url}'
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**If a specific review ID is provided (`#pullrequestreview-...`):**
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
gh api repos/${REPO}/pulls/{PR_NUMBER}/reviews/{REVIEW_ID}/comments | jq '[.[] | {id: .id, path: .path, body: .body, line: .line, start_line: .start_line, user: .user.login}]'
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**If only PR number is provided (fetch all PR review comments):**
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
gh api repos/${REPO}/pulls/{PR_NUMBER}/comments | jq '[.[] | {id: .id, path: .path, body: .body, line: .line, start_line: .start_line, user: .user.login, in_reply_to_id: .in_reply_to_id}]'
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Filtering comments:**
|
|
55
|
+
|
|
56
|
+
- Skip comments where `in_reply_to_id` is set (these are replies, not top-level comments)
|
|
57
|
+
- Do not skip bot-generated comments by default. Many actionable review comments in this repository come from bots.
|
|
58
|
+
- Deduplicate repeated bot comments and skip bot status posts, summaries, and acknowledgments that do not require a code or documentation change
|
|
59
|
+
- Treat as actionable by default only: correctness bugs, regressions, missing tests, and clear inconsistencies with adjacent code
|
|
60
|
+
- Treat as non-actionable by default: style nits, speculative suggestions, changelog wording, duplicate bot comments, and "could consider" feedback unless the user explicitly asks for polish work
|
|
61
|
+
- Focus on actionable feedback, not acknowledgments or thank-you messages
|
|
62
|
+
|
|
63
|
+
**Error handling:**
|
|
64
|
+
|
|
65
|
+
- If the API returns 404, the PR/comment doesn't exist - inform the user
|
|
66
|
+
- If the API returns 403, check authentication with `gh auth status`
|
|
67
|
+
- If the response is empty, inform the user no review comments were found
|
|
68
|
+
|
|
69
|
+
## Step 4: Triage Comments
|
|
70
|
+
|
|
71
|
+
Before creating any todos, classify every review comment into one of three categories:
|
|
72
|
+
|
|
73
|
+
- `MUST-FIX`: correctness bugs, regressions, security issues, missing tests that could hide a real bug, and clear inconsistencies with adjacent code that would likely block merge
|
|
74
|
+
- `DISCUSS`: reasonable suggestions that expand scope, architectural opinions that are not clearly right or wrong, and comments where the reviewer claim may be correct but needs a user decision
|
|
75
|
+
- `SKIPPED`: style preferences, documentation nits, comment requests, test-shape preferences, speculative suggestions, changelog wording, duplicate comments, status posts, summaries, and factually incorrect suggestions
|
|
76
|
+
|
|
77
|
+
Triage rules:
|
|
78
|
+
|
|
79
|
+
- Deduplicate overlapping comments before classifying them. Keep one representative item for the underlying issue.
|
|
80
|
+
- Verify factual claims locally before classifying a comment as `MUST-FIX`.
|
|
81
|
+
- If a claim appears wrong, classify it as `SKIPPED` and note briefly why.
|
|
82
|
+
- 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.
|
|
83
|
+
|
|
84
|
+
## Step 5: Create Todo List
|
|
85
|
+
|
|
86
|
+
Create a todo list with TodoWrite containing **only the `MUST-FIX` items**:
|
|
87
|
+
|
|
88
|
+
- One todo per must-fix comment or deduplicated issue
|
|
89
|
+
- For file-specific comments: `"{file}:{line} - {comment_summary} (@{username})"` (content)
|
|
90
|
+
- For general comments: Parse the comment body and extract the must-fix action
|
|
91
|
+
- Format activeForm: `"Addressing {brief description}"`
|
|
92
|
+
- All todos should start with status: `"pending"`
|
|
93
|
+
|
|
94
|
+
## Step 6: Present Triage to User
|
|
95
|
+
|
|
96
|
+
Present the triage to the user - **DO NOT automatically start addressing items**:
|
|
97
|
+
|
|
98
|
+
- `MUST-FIX ({count})`: list the todos created
|
|
99
|
+
- `DISCUSS ({count})`: list items needing user choice, with a short reason
|
|
100
|
+
- `SKIPPED ({count})`: list skipped comments with a short reason, including duplicates and factually incorrect suggestions
|
|
101
|
+
- Wait for the user to tell you which items to address
|
|
102
|
+
- Always offer an explicit optional follow-up to post rationale replies on selected `SKIPPED` or declined `DISCUSS` items
|
|
103
|
+
- Never post those rationale replies unless the user explicitly selects which items to reply to
|
|
104
|
+
- Ask two things when relevant:
|
|
105
|
+
- Which items to address in code/tests/docs
|
|
106
|
+
- Which skipped/declined items (if any) should receive a rationale reply
|
|
107
|
+
|
|
108
|
+
## Step 7: Address Items, Reply, and Resolve
|
|
109
|
+
|
|
110
|
+
When addressing items, after completing each selected todo item, reply to the original review comment explaining how it was addressed.
|
|
111
|
+
If the user selects skipped/declined items for rationale replies, post those replies too.
|
|
112
|
+
|
|
113
|
+
**For issue comments (general PR comments):**
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
gh api repos/${REPO}/issues/{PR_NUMBER}/comments -X POST -f body="<response>"
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**For PR review comments (file-specific, replying to a thread):**
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
gh api repos/${REPO}/pulls/{PR_NUMBER}/comments/{COMMENT_ID}/replies -X POST -f body="<response>"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**For standalone review comments (not in a thread):**
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
gh api repos/${REPO}/pulls/{PR_NUMBER}/comments -X POST -f body="<response>" -f commit_id="<COMMIT_SHA>" -f path="<FILE_PATH>" -f line=<LINE_NUMBER> -f side="RIGHT"
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Note: `side` is required when using `line`. Use `"RIGHT"` for the PR commit side (most common) or `"LEFT"` for the base commit side.
|
|
132
|
+
|
|
133
|
+
The response should briefly explain:
|
|
134
|
+
|
|
135
|
+
- What was changed
|
|
136
|
+
- Which commit(s) contain the fix
|
|
137
|
+
- Any relevant details or decisions made
|
|
138
|
+
|
|
139
|
+
After posting the reply, resolve the review thread when all of the following are true:
|
|
140
|
+
|
|
141
|
+
- The comment belongs to a review thread and you have the thread ID
|
|
142
|
+
- The concern was actually addressed in code, tests, or documentation, or it was explicitly declined with a clear explanation approved by the user
|
|
143
|
+
- The thread is not already resolved
|
|
144
|
+
|
|
145
|
+
Use GitHub GraphQL to resolve the thread:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
gh api graphql -f query='mutation($threadId:ID!) { resolveReviewThread(input:{threadId:$threadId}) { thread { id isResolved } } }' -f threadId="<THREAD_ID>"
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Do not resolve a thread if the fix is still pending, if you are unsure whether the reviewer concern is satisfied, or if the user asked to leave the thread open.
|
|
152
|
+
|
|
153
|
+
If the user explicitly asks to close out a `DISCUSS` or `SKIPPED` item, reply with the rationale and resolve the thread only when the conversation is actually complete.
|
|
154
|
+
|
|
155
|
+
# Example Usage
|
|
156
|
+
|
|
157
|
+
```text
|
|
158
|
+
/address-review https://github.com/org/repo/pull/12345#pullrequestreview-123456789
|
|
159
|
+
/address-review https://github.com/org/repo/pull/12345#issuecomment-123456789
|
|
160
|
+
/address-review 12345
|
|
161
|
+
/address-review https://github.com/org/repo/pull/12345
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
# Example Output
|
|
165
|
+
|
|
166
|
+
After fetching and triaging comments, present them like this:
|
|
167
|
+
|
|
168
|
+
```text
|
|
169
|
+
Found 5 review comments. Triage:
|
|
170
|
+
|
|
171
|
+
MUST-FIX (1):
|
|
172
|
+
1. ⬜ src/helper.rb:45 - Missing nil guard causes a crash on empty input (@reviewer1)
|
|
173
|
+
|
|
174
|
+
DISCUSS (1):
|
|
175
|
+
2. src/config.rb:12 - Extract this to a shared config constant (@reviewer1)
|
|
176
|
+
Reason: reasonable suggestion, but it expands scope
|
|
177
|
+
|
|
178
|
+
SKIPPED (3):
|
|
179
|
+
3. src/helper.rb:50 - "Consider adding a comment" (@claude[bot]) - documentation nit
|
|
180
|
+
4. src/helper.rb:45 - Same nil guard issue (@greptile-apps[bot]) - duplicate of #1
|
|
181
|
+
5. spec/helper_spec.rb:20 - "Consolidate assertions" (@claude[bot]) - test style preference
|
|
182
|
+
|
|
183
|
+
Which items would you like me to address? (e.g., "1", "1,2", or "all must-fix")
|
|
184
|
+
Optional: I can also post rationale replies for skipped/declined items (e.g., "reply 3,5" or "reply all skipped").
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
# Important Notes
|
|
188
|
+
|
|
189
|
+
- Automatically detect the repository using `gh repo view` for the current working directory
|
|
190
|
+
- If a GitHub URL is provided, extract the org/repo from the URL
|
|
191
|
+
- Include file path and line number in each todo for easy navigation (when available)
|
|
192
|
+
- Include the reviewer's username in the todo text
|
|
193
|
+
- If a comment doesn't have a specific line number, note it as "general comment"
|
|
194
|
+
- **NEVER automatically address all review comments** - always wait for user direction
|
|
195
|
+
- When given a specific review URL, no need to ask for more information
|
|
196
|
+
- **ALWAYS reply to comments after addressing them** to close the feedback loop
|
|
197
|
+
- After triage, always offer to post rationale replies for selected `SKIPPED`/declined items, but only post them with explicit user approval
|
|
198
|
+
- Resolve the review thread after replying when the concern is actually addressed and a thread ID is available
|
|
199
|
+
- Default to real issues only. Do not spend a review cycle on optional polish unless the user explicitly asks for it
|
|
200
|
+
- Triage comments before creating todos. Only `MUST-FIX` items should become todos by default
|
|
201
|
+
- For large review comments (like detailed code reviews), parse and extract the actionable items into separate todos
|
|
202
|
+
|
|
203
|
+
# Known Limitations
|
|
204
|
+
|
|
205
|
+
- Rate limiting: GitHub API has rate limits; if you hit them, wait a few minutes
|
|
206
|
+
- Private repos: Requires appropriate `gh` authentication scope
|
|
@@ -7,9 +7,10 @@ You are helping to add an entry to the CHANGELOG.md file for the Shakapacker pro
|
|
|
7
7
|
This command accepts an optional argument: `$ARGUMENTS`
|
|
8
8
|
|
|
9
9
|
- **No argument** (`/update-changelog`): Add entries to `[Unreleased]` without stamping a version header. Use this during development.
|
|
10
|
-
- **`release`** (`/update-changelog release`): Add entries and stamp a version header. Auto-compute the next version based on changes (breaking → major, added features → minor, fixes → patch). Then `rake
|
|
10
|
+
- **`release`** (`/update-changelog release`): Add entries and stamp a version header. Auto-compute the next version based on changes (breaking → major, added features → minor, fixes → patch). Then `rake release` (with no args) will pick up this version automatically.
|
|
11
11
|
- **`rc`** (`/update-changelog rc`): Same as `release`, but stamps an RC prerelease version (e.g., `v9.7.0-rc.0`). Auto-increments the RC index if prior RCs exist for the same base version.
|
|
12
12
|
- **`beta`** (`/update-changelog beta`): Same as `rc`, but stamps a beta prerelease version (e.g., `v9.7.0-beta.0`).
|
|
13
|
+
- **Explicit version** (`/update-changelog 9.7.0-rc.10` or `/update-changelog v9.7.0-rc.10`): Add entries and stamp the exact version provided. Skips auto-computation — use this when you already know the target version. The version string must use npm semver format with optional `-rc.N` or `-beta.N` suffix (e.g., `9.7.0-rc.10`, `9.7.0`). A `v` prefix is optional and will be added automatically if missing. If passed in RubyGems dot format (e.g., `9.7.0.rc.10` or `9.7.0.beta.2`), convert to npm semver dash format (`v9.7.0-rc.10` or `v9.7.0-beta.2`) for the changelog header.
|
|
13
14
|
|
|
14
15
|
## When to Use This
|
|
15
16
|
|
|
@@ -25,7 +26,7 @@ This command serves three use cases at different points in the release lifecycle
|
|
|
25
26
|
- Run `/update-changelog release` (or `rc` or `beta`) to add entries AND stamp the version header
|
|
26
27
|
- The version is auto-computed from changelog content (see "Auto-Computing the Next Version" below)
|
|
27
28
|
- Commit and push CHANGELOG.md
|
|
28
|
-
- Then run `rake
|
|
29
|
+
- Then run `rake release` (no args needed — it reads the version from CHANGELOG.md)
|
|
29
30
|
- The release task automatically creates a GitHub release from the changelog section
|
|
30
31
|
|
|
31
32
|
**After a release you forgot to update the changelog for** — Catch-up mode:
|
|
@@ -35,7 +36,7 @@ This command serves three use cases at different points in the release lifecycle
|
|
|
35
36
|
|
|
36
37
|
### Why changelog comes BEFORE the release
|
|
37
38
|
|
|
38
|
-
- `
|
|
39
|
+
- `release` automatically creates a GitHub release if a changelog section exists — no separate `sync_github_release` step needed
|
|
39
40
|
- The release task warns if no changelog section is found for the target version
|
|
40
41
|
- A premature version header (if release fails) is harmless — you'll release eventually
|
|
41
42
|
- A missing changelog after release means GitHub release must be created manually
|
|
@@ -57,12 +58,12 @@ When stamping a version header (`release`, `rc`, or `beta`), compute the next ve
|
|
|
57
58
|
|
|
58
59
|
3. **Compute the version**:
|
|
59
60
|
- For `release`: Apply the bump to the latest stable tag (e.g., `9.5.0` + minor → `9.6.0`)
|
|
60
|
-
- For `rc`: Apply the bump, then find the next RC index (e.g., if `v9.6.0-rc.0` tag exists → `v9.6.0-rc.1`)
|
|
61
|
+
- For `rc`: Apply the bump, then find the next RC index based **only on git tags** (e.g., if `v9.6.0-rc.0` tag exists → `v9.6.0-rc.1`). **Do NOT use changelog headers** to determine the next index — a version header in the changelog is a draft that may not have been released yet. Only git tags represent shipped versions.
|
|
61
62
|
- For `beta`: Same as RC but with beta suffix
|
|
62
63
|
|
|
63
64
|
4. **Verify**: Check that the computed version is newer than ALL existing tags (stable and prerelease). If not, ask the user what to do.
|
|
64
65
|
|
|
65
|
-
5. **Show the computed version to the user
|
|
66
|
+
5. **Show the computed version to the user and ask for confirmation** before stamping the header. If the bump type is ambiguous (e.g., changes could reasonably be classified as patch vs minor, or the changelog headings don't clearly signal the bump level), explain your reasoning for the suggested bump and ask the user to confirm or override before proceeding.
|
|
66
67
|
|
|
67
68
|
## Critical Requirements
|
|
68
69
|
|
|
@@ -168,6 +169,8 @@ This will:
|
|
|
168
169
|
|
|
169
170
|
After adding an entry to the `## [Unreleased]` section, ensure the version diff links at the bottom of the file are correct.
|
|
170
171
|
|
|
172
|
+
**IMPORTANT**: Compare links at the bottom MUST use the `v` prefix to match git tags (e.g., `.../compare/v9.2.0...v9.3.0`). This is consistent with Shakapacker's changelog headers which also include the `v` prefix (e.g., `## [v9.3.0]`).
|
|
173
|
+
|
|
171
174
|
The format at the bottom should be:
|
|
172
175
|
|
|
173
176
|
```markdown
|
|
@@ -186,59 +189,89 @@ When a new version is released:
|
|
|
186
189
|
|
|
187
190
|
### For Regular Changelog Updates
|
|
188
191
|
|
|
189
|
-
1
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
3. **Check
|
|
203
|
-
-
|
|
204
|
-
-
|
|
205
|
-
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
-
|
|
226
|
-
-
|
|
227
|
-
|
|
228
|
-
|
|
192
|
+
#### Step 1: Fetch and read current state
|
|
193
|
+
|
|
194
|
+
- **CRITICAL**: Run `git fetch origin main --tags` to ensure you have the latest commits AND tags
|
|
195
|
+
- The workspace may be behind origin/main, causing you to miss recently merged PRs
|
|
196
|
+
- After fetching, use `origin/main` for all comparisons, NOT local `main` branch
|
|
197
|
+
- Read the current CHANGELOG.md to understand the existing structure
|
|
198
|
+
|
|
199
|
+
#### Step 2: Reconcile tags with changelog sections (DO THIS FIRST)
|
|
200
|
+
|
|
201
|
+
**This step catches missing version sections and is the #1 source of errors when skipped.**
|
|
202
|
+
|
|
203
|
+
1. Get the latest git tag: `git tag -l 'v*' --sort=-v:refname | head -5`
|
|
204
|
+
2. Get the most recent version header in CHANGELOG.md (the first `## [vVERSION]` after `## [Unreleased]`)
|
|
205
|
+
3. **Compare them.** If the latest git tag does NOT appear anywhere in the changelog version headers, there are tagged releases missing from the changelog. **Important**: Don't just compare against the _top_ changelog header — a version header may exist _above_ the latest tag if it was stamped as a draft before tagging. Check whether the tag's version appears in _any_ `## [vX.Y.Z]` header. For example:
|
|
206
|
+
- Latest tag: `v9.6.0-rc.4`, and no `## [v9.6.0-rc.4]` header exists anywhere in CHANGELOG.md
|
|
207
|
+
- **Result: `v9.6.0-rc.4` is missing and needs its own section**
|
|
208
|
+
- But if `## [v9.7.0-rc.0]` is the top header (a draft, not yet tagged) and `## [v9.6.0-rc.4]` exists below it, then nothing is missing — the top header is simply a pre-release draft
|
|
209
|
+
|
|
210
|
+
4. For EACH missing tagged version (there may be multiple):
|
|
211
|
+
a. Find commits in that tag vs the previous tag: `git log --oneline PREV_TAG..MISSING_TAG`
|
|
212
|
+
b. Extract PR numbers and fetch details for user-visible changes
|
|
213
|
+
c. Check which entries currently in `## [Unreleased]` actually belong to this tagged version (compare PR numbers against the commit list)
|
|
214
|
+
d. **Create a new version section** immediately before the previous version section
|
|
215
|
+
e. **Move** matching entries from Unreleased into the new section
|
|
216
|
+
f. **Add** any new entries for PRs in that tag that aren't in the changelog at all
|
|
217
|
+
g. **Update version diff links** at the bottom of the file
|
|
218
|
+
|
|
219
|
+
5. Get the tag date with: `git log -1 --format="%Y-%m-%d" TAG_NAME`
|
|
220
|
+
|
|
221
|
+
#### Step 3: Add new entries for post-tag commits
|
|
222
|
+
|
|
223
|
+
1. Run `git log --oneline LATEST_TAG..origin/main` to find commits after the latest tag (LATEST_TAG is the most recent git tag, i.e., the same one identified in Step 2)
|
|
224
|
+
2. **Extract ALL PR numbers** from commit messages: `git log --oneline LATEST_TAG..origin/main | grep -oE "#[0-9]+" | sort -u`
|
|
225
|
+
3. If Step 2 found no missing tagged versions, verify no tag is ahead of main: `git log --oneline origin/main..LATEST_TAG` should be empty. If not, entries in "Unreleased" may belong to that tagged version — Step 2 should have caught this, so re-check.
|
|
226
|
+
4. For each PR number, check if it's already in CHANGELOG.md: `grep "PR #XXX" CHANGELOG.md`
|
|
227
|
+
5. For PRs not yet in the changelog:
|
|
228
|
+
- Get PR details: `gh pr view NUMBER --json title,body,author --repo shakacode/shakapacker`
|
|
229
|
+
- **Never ask the user for PR details** — get them from git history or the GitHub API
|
|
230
|
+
- Validate that the change is user-visible (per the criteria above). Skip CI, lint, refactoring, test-only changes.
|
|
231
|
+
- Add the entry to `## [Unreleased]` under the appropriate category heading
|
|
232
|
+
|
|
233
|
+
#### Step 4: Stamp version header (only when a version mode or explicit version is given)
|
|
234
|
+
|
|
235
|
+
If the user passed `release`, `rc`, `beta`, or an explicit version string as an argument:
|
|
236
|
+
|
|
237
|
+
1. Auto-compute the next version (see "Auto-Computing the Next Version" above), or use the explicit version provided
|
|
238
|
+
2. Insert the version header immediately after `## [Unreleased]`
|
|
239
|
+
3. For `rc`/`beta` or an explicit prerelease version (e.g., `9.7.0-rc.10`): collapse prior prerelease sections of the same base version into the new section
|
|
240
|
+
4. Update version diff links at the bottom of the file
|
|
241
|
+
5. **Verify** the computed version looks correct
|
|
242
|
+
|
|
243
|
+
If no argument was passed, skip this step — entries stay in `## [Unreleased]`.
|
|
244
|
+
|
|
245
|
+
#### Step 5: Verify and finalize
|
|
246
|
+
|
|
247
|
+
1. **Verify formatting**:
|
|
229
248
|
- Bold description with period
|
|
230
|
-
- Proper PR link
|
|
249
|
+
- Proper PR link (with `#` prefix for Shakapacker)
|
|
231
250
|
- Proper author link
|
|
232
251
|
- Consistent with existing entries
|
|
233
252
|
- File ends with a newline character
|
|
234
|
-
|
|
235
|
-
|
|
253
|
+
- **No duplicate section headings** (e.g., don't create two `### Fixed` sections — merge entries into the existing heading)
|
|
254
|
+
2. **Verify version sections are in order** (Unreleased → newest tag → older tags)
|
|
255
|
+
3. **Verify version diff links** at the bottom of the file are correct (compare links MUST use the `v` prefix to match git tags)
|
|
256
|
+
4. **Run linting** after making changes:
|
|
236
257
|
|
|
237
258
|
```bash
|
|
238
259
|
yarn lint
|
|
239
260
|
```
|
|
240
261
|
|
|
241
|
-
|
|
262
|
+
5. **Show the user** a summary of what was done:
|
|
263
|
+
- Which version sections were created
|
|
264
|
+
- Which entries were moved from Unreleased
|
|
265
|
+
- Which new entries were added
|
|
266
|
+
- Which PRs were skipped (and why)
|
|
267
|
+
6. If in `release`/`rc`/`beta` mode or explicit-version mode, **automatically commit, push, and open a PR**:
|
|
268
|
+
- Verify the working tree only has `CHANGELOG.md` changes; if there are other uncommitted changes, warn the user and stop
|
|
269
|
+
- Verify the current branch is `main` (`git branch --show-current`); if not, warn the user and stop
|
|
270
|
+
- Create a feature branch (e.g., `changelog-v9.6.0-rc.1`)
|
|
271
|
+
- Stage only `CHANGELOG.md` (`git add CHANGELOG.md`) and commit with message `Update CHANGELOG.md for vX.Y.Z` (using the stamped version)
|
|
272
|
+
- Push and open a PR with the changelog diff as the body
|
|
273
|
+
- If the push or PR creation fails, the CHANGELOG is already stamped locally — fix the issue and retry manually
|
|
274
|
+
- Remind the user to run `bundle exec rake release` (no args) after merge to publish and auto-create the GitHub release
|
|
242
275
|
|
|
243
276
|
### For Prerelease Versions (RC and Beta)
|
|
244
277
|
|
|
@@ -259,10 +292,14 @@ When the user passes `rc` or `beta` as an argument (or when creating a prereleas
|
|
|
259
292
|
4. **Always collapse prior prereleases into the current prerelease** (this is the default behavior):
|
|
260
293
|
- Combine all prior prerelease changelog entries into the new prerelease version section
|
|
261
294
|
- Remove previous prerelease version sections (e.g., remove `## [v9.6.0-rc.0]` when creating `## [v9.6.0-rc.1]`)
|
|
295
|
+
- When collapsing, **consolidate duplicate category headings** — if both the Unreleased section and a prior prerelease section have `### Fixed`, merge all entries under a single `### Fixed` heading
|
|
296
|
+
- **Remove orphaned version diff links** at the bottom of the file for collapsed prerelease sections
|
|
262
297
|
- Add any new user-visible changes from commits since the last prerelease
|
|
263
298
|
- Update version diff links to point from the last stable version to the new prerelease
|
|
264
299
|
- This keeps the changelog clean with a single prerelease section that accumulates all changes since the last stable release
|
|
265
300
|
|
|
301
|
+
**Note**: The new version header must be inserted **immediately after `## [Unreleased]`** (see Step 4). This ensures correct ordering of version headers.
|
|
302
|
+
|
|
266
303
|
### For Prerelease to Stable Version Release
|
|
267
304
|
|
|
268
305
|
When releasing from prerelease to a stable version (e.g., v9.6.0-rc.1 → v9.6.0):
|
data/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,27 @@
|
|
|
9
9
|
|
|
10
10
|
## [Unreleased]
|
|
11
11
|
|
|
12
|
+
## [v9.7.0] - March 15, 2026
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- **Added rspack v2 support**. [PR #975](https://github.com/shakacode/shakapacker/pull/975) by [justin808](https://github.com/justin808). Peer dependencies now accept both rspack v1 and v2 (`^1.0.0 || ^2.0.0-0`). No source code changes were needed — all existing APIs work identically in v2. Note that rspack v2 requires Node.js 20.19.0+.
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- **Fixed config exporter path traversal and annotation format validation**. [PR #914](https://github.com/shakacode/shakapacker/pull/914) by [justin808](https://github.com/justin808). Added `safeResolvePath` security check to prevent path traversal in export save paths, and enforced YAML format when using annotations with build exports.
|
|
21
|
+
- **Fixed `webpack-subresource-integrity` v5 named export handling**. [PR #978](https://github.com/shakacode/shakapacker/pull/978) by [justin808](https://github.com/justin808). Supports both the default export (older versions) and the named `SubresourceIntegrityPlugin` export (v5.1+), preventing runtime breakage when upgrading the plugin. Fixes [#972](https://github.com/shakacode/shakapacker/issues/972).
|
|
22
|
+
|
|
23
|
+
## [v9.6.1] - March 8, 2026
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
|
|
27
|
+
- **Fixed `Env#current` crashing when Rails is not loaded**. [PR #963](https://github.com/shakacode/shakapacker/pull/963) by [ihabadham](https://github.com/ihabadham). Added `defined?(Rails)` guard to `Shakapacker::Env#current` so it falls back to `RAILS_ENV`/`RACK_ENV` environment variables when called from non-Rails Ruby processes (e.g., `bin/dev` scripts). Previously, this would raise a `NameError` and silently fall back to `"production"`.
|
|
28
|
+
|
|
29
|
+
### Documentation
|
|
30
|
+
|
|
31
|
+
- **Added Node package API documentation**. [PR #900](https://github.com/shakacode/shakapacker/pull/900) by [justin808](https://github.com/justin808). New guide (`docs/node_package_api.md`) documenting the JavaScript API exports, configuration objects, import entrypoints for webpack and rspack, and built-in third-party support resources.
|
|
32
|
+
|
|
12
33
|
## [v9.6.0] - March 7, 2026
|
|
13
34
|
|
|
14
35
|
### Security
|
|
@@ -866,7 +887,9 @@ Note: [Rubygem is 6.3.0.pre.rc.1](https://rubygems.org/gems/shakapacker/versions
|
|
|
866
887
|
|
|
867
888
|
See [CHANGELOG.md in rails/webpacker (up to v5.4.3)](https://github.com/rails/webpacker/blob/master/CHANGELOG.md)
|
|
868
889
|
|
|
869
|
-
[Unreleased]: https://github.com/shakacode/shakapacker/compare/v9.
|
|
890
|
+
[Unreleased]: https://github.com/shakacode/shakapacker/compare/v9.7.0...main
|
|
891
|
+
[v9.7.0]: https://github.com/shakacode/shakapacker/compare/v9.6.1...v9.7.0
|
|
892
|
+
[v9.6.1]: https://github.com/shakacode/shakapacker/compare/v9.6.0...v9.6.1
|
|
870
893
|
[v9.6.0]: https://github.com/shakacode/shakapacker/compare/v9.5.0...v9.6.0
|
|
871
894
|
[v9.5.0]: https://github.com/shakacode/shakapacker/compare/v9.4.0...v9.5.0
|
|
872
895
|
[v9.4.0]: https://github.com/shakacode/shakapacker/compare/v9.3.4...v9.4.0
|
data/README.md
CHANGED
|
@@ -317,6 +317,8 @@ At its core, Shakapacker's essential function is to:
|
|
|
317
317
|
|
|
318
318
|
**📖 For a comprehensive guide to all configuration options, see the [Configuration Guide](./docs/configuration.md)**
|
|
319
319
|
|
|
320
|
+
**📦 For Node package exports and config object docs, see the [Node Package API Guide](./docs/node_package_api.md)**
|
|
321
|
+
|
|
320
322
|
This includes documentation for:
|
|
321
323
|
|
|
322
324
|
- All `config/shakapacker.yml` options (including `assets_bundler_config_path`)
|
data/Rakefile
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
require "bundler/gem_tasks"
|
|
3
3
|
require "pathname"
|
|
4
4
|
|
|
5
|
+
# Remove Bundler's default `release` task — it bypasses the custom release flow
|
|
6
|
+
# (CHANGELOG version detection, npm publish, GitHub release sync, etc.).
|
|
7
|
+
# The custom `release` task in rakelib/release.rake replaces it.
|
|
8
|
+
Rake::Task[:release].clear
|
|
9
|
+
|
|
5
10
|
desc "Run all specs"
|
|
6
11
|
task test: ["run_spec:all_specs"]
|
|
7
12
|
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Node Package API
|
|
2
|
+
|
|
3
|
+
Shakapacker ships a Node package that exposes configuration and helper utilities
|
|
4
|
+
for both webpack and rspack.
|
|
5
|
+
|
|
6
|
+
## Import Paths
|
|
7
|
+
|
|
8
|
+
```js
|
|
9
|
+
// Webpack entrypoint
|
|
10
|
+
const shakapacker = require("shakapacker")
|
|
11
|
+
|
|
12
|
+
// Rspack entrypoint
|
|
13
|
+
const rspack = require("shakapacker/rspack")
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Webpack Exports (`shakapacker`)
|
|
17
|
+
|
|
18
|
+
| Export | Type | Description |
|
|
19
|
+
| --------------------------------------------------------- | --------- | ------------------------------------------------------------ |
|
|
20
|
+
| `config` | object | Parsed `config/shakapacker.yml` plus computed fields |
|
|
21
|
+
| `devServer` | object | Dev server configuration |
|
|
22
|
+
| `generateWebpackConfig(extraConfig?)` | function | Generates final webpack config and merges optional overrides |
|
|
23
|
+
| `baseConfig` | object | Base config object from `package/environments/base` |
|
|
24
|
+
| `env` | object | Environment metadata (`railsEnv`, `nodeEnv`, booleans) |
|
|
25
|
+
| `rules` | array | Loader rules for current bundler |
|
|
26
|
+
| `moduleExists(name)` | function | Returns whether module can be resolved |
|
|
27
|
+
| `canProcess(rule, fn)` | function | Runs callback only if loader dependency is available |
|
|
28
|
+
| `inliningCss` | boolean | Whether CSS should be inlined in current dev-server mode |
|
|
29
|
+
| `merge`, `mergeWithCustomize`, `mergeWithRules`, `unique` | functions | Re-exported from `webpack-merge` |
|
|
30
|
+
|
|
31
|
+
## Rspack Exports (`shakapacker/rspack`)
|
|
32
|
+
|
|
33
|
+
| Export | Type | Description |
|
|
34
|
+
| --------------------------------------------------------- | --------- | ----------------------------------------------------------- |
|
|
35
|
+
| `config` | object | Parsed `config/shakapacker.yml` plus computed fields |
|
|
36
|
+
| `devServer` | object | Dev server configuration |
|
|
37
|
+
| `generateRspackConfig(extraConfig?)` | function | Generates final rspack config and merges optional overrides |
|
|
38
|
+
| `baseConfig` | object | Base config object |
|
|
39
|
+
| `env` | object | Environment metadata (`railsEnv`, `nodeEnv`, booleans) |
|
|
40
|
+
| `rules` | array | Rspack loader rules |
|
|
41
|
+
| `moduleExists(name)` | function | Returns whether module can be resolved |
|
|
42
|
+
| `canProcess(rule, fn)` | function | Runs callback only if loader dependency is available |
|
|
43
|
+
| `inliningCss` | boolean | Whether CSS should be inlined in current dev-server mode |
|
|
44
|
+
| `merge`, `mergeWithCustomize`, `mergeWithRules`, `unique` | functions | Re-exported from `webpack-merge` |
|
|
45
|
+
|
|
46
|
+
## `config` Object
|
|
47
|
+
|
|
48
|
+
`config` includes:
|
|
49
|
+
|
|
50
|
+
- Raw values from `config/shakapacker.yml` (`source_path`, `public_output_path`, `javascript_transpiler`, etc.)
|
|
51
|
+
- Computed absolute paths (`outputPath`, `publicPath`, `manifestPath`, `publicPathWithoutCDN`)
|
|
52
|
+
- Optional sections like `dev_server` and `integrity`
|
|
53
|
+
|
|
54
|
+
For the full key list and types, see:
|
|
55
|
+
|
|
56
|
+
- [`package/types.ts`](../package/types.ts)
|
|
57
|
+
- [Configuration Guide](./configuration.md)
|
|
58
|
+
|
|
59
|
+
## Built-in Third-Party Support
|
|
60
|
+
|
|
61
|
+
Installer defaults include support for:
|
|
62
|
+
|
|
63
|
+
- Bundlers: webpack, rspack
|
|
64
|
+
- JavaScript transpilers: SWC (default), Babel, esbuild
|
|
65
|
+
- Common style/tooling loaders: css, sass, less, stylus, file/raw rules
|
|
66
|
+
- Common optimization/plugins for webpack/rspack production builds
|
|
67
|
+
|
|
68
|
+
Dependency presets used by the installer are defined in:
|
|
69
|
+
|
|
70
|
+
- [`lib/install/package.json`](../lib/install/package.json)
|