|
| 1 | +--- |
| 2 | +argument-hint: [tag|revision-range|latest] |
| 3 | +description: Generate DittoChat SDK release notes from git commits or tags, and create changeset for NPM packages |
| 4 | +--- |
| 5 | + |
| 6 | +# DittoChat Release Notes & Changeset Command |
| 7 | + |
| 8 | +Generate comprehensive release notes for DittoChat SDK releases by analyzing git history, then create the changeset file for NPM publishing. |
| 9 | + |
| 10 | +## Context |
| 11 | + |
| 12 | +This repository has two NPM packages (JavaScript/TypeScript only): |
| 13 | + |
| 14 | +- `@dittolive/ditto-chat-core` (located at `sdks/js/ditto-chat-core/`) |
| 15 | +- `@dittolive/ditto-chat-ui` (located at `sdks/js/ditto-chat-ui/`) |
| 16 | + |
| 17 | +This command uses Changesets for automated NPM package versioning and publishing. |
| 18 | + |
| 19 | +--- |
| 20 | + |
| 21 | +## Parsing the Argument: $1 |
| 22 | + |
| 23 | +The command accepts three input formats: |
| 24 | + |
| 25 | +### 1. Specific Package Tag (e.g., `@dittolive/ditto-chat-ui@0.1.2`) |
| 26 | + |
| 27 | +- Use `git show <tag>` to get the commit SHA |
| 28 | +- Find the previous tag for the same package using: |
| 29 | + ```bash |
| 30 | + git tag -l "@dittolive/ditto-chat-ui@*" --sort=-version:refname | head -n 2 |
| 31 | + ``` |
| 32 | +- Build revision range: `<previous-tag>...<current-tag>` |
| 33 | + |
| 34 | +### 2. Git Revision Range (e.g., `abc123...def456`) |
| 35 | + |
| 36 | +- Validate that both commits exist with `git rev-parse` |
| 37 | +- Use the range directly |
| 38 | +- Build GitHub compare URL: `https://github.com/getditto/DittoChat/compare/<range>` |
| 39 | + |
| 40 | +### 3. "latest" or No Argument |
| 41 | + |
| 42 | +- Find the most recent merged "Version Packages" PR or check recent commits on main |
| 43 | +- Use `git log` to find commits since last release tags |
| 44 | +- For each package with changes, determine the affected range |
| 45 | + |
| 46 | +--- |
| 47 | + |
| 48 | +## Step 1: Reading Commits and Gathering Context |
| 49 | + |
| 50 | +### Extract Commits in Reverse Order (Oldest First) |
| 51 | + |
| 52 | +```bash |
| 53 | +git log --oneline --reverse --format="%h|||%s|||%an|||%ae" <revision-range> |
| 54 | +``` |
| 55 | + |
| 56 | +### Gather Author Information |
| 57 | + |
| 58 | +- Collect unique authors (full name, email) |
| 59 | +- Create a list for acknowledgments (alphabetically sorted) |
| 60 | + |
| 61 | +### Check for Changesets (if applicable) |
| 62 | + |
| 63 | +```bash |
| 64 | +git log <revision-range> --name-only --format="commit: %H" | grep ".changeset" |
| 65 | +``` |
| 66 | + |
| 67 | +- If changesets exist in the range, read them for context |
| 68 | +- Use changeset descriptions as additional source material |
| 69 | + |
| 70 | +### Extract PR References |
| 71 | + |
| 72 | +```bash |
| 73 | +git log <revision-range> --format="%h %s" | grep -oE "#[0-9]+" |
| 74 | +``` |
| 75 | + |
| 76 | +- Note PR numbers for reference |
| 77 | +- Can use `gh pr view <number>` for additional context if needed |
| 78 | + |
| 79 | +### Determine Which Packages Are Affected |
| 80 | + |
| 81 | +- Check if commits modified files in `sdks/js/ditto-chat-core/` |
| 82 | +- Check if commits modified files in `sdks/js/ditto-chat-ui/` |
| 83 | +- Determine if this is a single-package or dual-package release |
| 84 | + |
| 85 | +--- |
| 86 | + |
| 87 | +## Step 2: Change Categories |
| 88 | + |
| 89 | +Classify each commit into EXACTLY ONE category. Categories are package-specific: |
| 90 | + |
| 91 | +### For `@dittolive/ditto-chat-core` changes: |
| 92 | + |
| 93 | +- **Core Functionality** - Chat operations, message handling, room management |
| 94 | +- **State Management** - Store updates, data synchronization |
| 95 | +- **Presence & Typing** - User status, typing indicators |
| 96 | +- **Reactions & Mentions** - Emoji reactions, @mentions |
| 97 | +- **Attachments** - File handling, image uploads |
| 98 | +- **RBAC & Permissions** - Access control, authorization |
| 99 | +- **API Changes** - Hook signatures, export changes (note if breaking) |
| 100 | +- **Performance** - Optimization, efficiency improvements |
| 101 | +- **Bug Fixes** - Defect resolutions |
| 102 | +- **Types & Interfaces** - TypeScript type updates |
| 103 | +- **Tests** - Test additions or modifications |
| 104 | +- **Documentation** - README, comments, JSDoc updates |
| 105 | +- **Dependencies** - Dependency updates |
| 106 | +- **Internal/Refactoring** - Non-user-facing changes |
| 107 | + |
| 108 | +### For `@dittolive/ditto-chat-ui` changes: |
| 109 | + |
| 110 | +- **UI Components** - New or updated React components |
| 111 | +- **Styling & Theming** - CSS, Tailwind, theme customization |
| 112 | +- **Layout & Responsive** - Layout changes, mobile optimization |
| 113 | +- **Accessibility** - A11y improvements, ARIA labels |
| 114 | +- **User Interactions** - Click handlers, keyboard nav, gestures |
| 115 | +- **Visual Feedback** - Loading states, animations, transitions |
| 116 | +- **Dark Mode** - Dark mode specific changes |
| 117 | +- **API Changes** - Component props, exports (note if breaking) |
| 118 | +- **Bug Fixes** - UI defect resolutions |
| 119 | +- **Dependencies** - UI dependency updates (Radix, React, etc.) |
| 120 | +- **Tests** - Component tests |
| 121 | +- **Documentation** - Storybook, component docs |
| 122 | +- **Internal/Refactoring** - Non-user-facing changes |
| 123 | + |
| 124 | +**CRITICAL RULES**: |
| 125 | + |
| 126 | +- Each commit goes to EXACTLY ONE category |
| 127 | +- Breaking changes MUST be marked with "BREAKING:" prefix |
| 128 | +- If a commit affects both packages, mention both contexts but categorize based on primary impact |
| 129 | + |
| 130 | +--- |
| 131 | + |
| 132 | +## Step 3: Writing Change Entries |
| 133 | + |
| 134 | +For each commit, generate a change entry following these rules: |
| 135 | + |
| 136 | +1. **Strip Conventional Commit Prefixes** - Remove `feat:`, `fix:`, `chore:`, `docs:`, etc. |
| 137 | +2. **Use Consistent Tense** - Past tense ("Added", "Fixed", "Updated", "Refactored") |
| 138 | +3. **Be Specific** - Mention the component/hook/feature affected |
| 139 | +4. **Keep It Concise** - One sentence per change |
| 140 | +5. **Include PR Reference** - Add `(#123)` if PR number is available |
| 141 | +6. **Highlight Breaking Changes** - Prefix with "BREAKING:" if applicable |
| 142 | +7. **Edit for Clarity** - If commit message is unclear, check commit contents or PR for context |
| 143 | +8. **Never Hallucinate** - If you can't determine what a commit does, ask the user for clarification |
| 144 | + |
| 145 | +**Good Examples**: |
| 146 | + |
| 147 | +- "Fixed attachment rendering error on initial load (#95)" |
| 148 | +- "BREAKING: Updated `useDittoChat` hook signature to accept config object" |
| 149 | +- "Added Radix UI components for dialogs and dropdowns" |
| 150 | +- "Refactored theme provider for better reusability (#105)" |
| 151 | + |
| 152 | +**Bad Examples**: |
| 153 | + |
| 154 | +- "chore: update stuff" (too vague, has prefix) |
| 155 | +- "Fixed bug" (not specific enough) |
| 156 | +- "Changes" (meaningless) |
| 157 | + |
| 158 | +--- |
| 159 | + |
| 160 | +## Step 4: Generate Release Notes |
| 161 | + |
| 162 | +### For Single Package Release: |
| 163 | + |
| 164 | +```markdown |
| 165 | +# Release Notes: <package-name> v<version> |
| 166 | + |
| 167 | +**Release Date**: <date> |
| 168 | +**Compare**: https://github.com/getditto/DittoChat/compare/<range> |
| 169 | + |
| 170 | +## Summary |
| 171 | + |
| 172 | +<1-2 sentence overview of the release - what's the main theme or goal?> |
| 173 | + |
| 174 | +## Changes |
| 175 | + |
| 176 | +### <Category 1> |
| 177 | + |
| 178 | +- Change entry 1 (#PR) |
| 179 | +- Change entry 2 |
| 180 | + |
| 181 | +### <Category 2> |
| 182 | + |
| 183 | +- Change entry 1 (#PR) |
| 184 | + |
| 185 | +## Contributors |
| 186 | + |
| 187 | +Thank you to the following contributors: |
| 188 | + |
| 189 | +- @username (Full Name) |
| 190 | +- @username2 (Full Name) |
| 191 | + |
| 192 | +## Installation |
| 193 | + |
| 194 | +\`\`\`bash |
| 195 | +npm install <package-name>@<version> |
| 196 | +\`\`\` |
| 197 | + |
| 198 | +--- |
| 199 | + |
| 200 | +📦 Generated with Claude Code |
| 201 | +``` |
| 202 | + |
| 203 | +### For Multi-Package Release: |
| 204 | + |
| 205 | +```markdown |
| 206 | +# Release Notes: DittoChat SDK |
| 207 | + |
| 208 | +**Release Date**: <date> |
| 209 | + |
| 210 | +## @dittolive/ditto-chat-core v<version> |
| 211 | + |
| 212 | +**Compare**: https://github.com/getditto/DittoChat/compare/<range> |
| 213 | + |
| 214 | +### Summary |
| 215 | + |
| 216 | +<1-2 sentence overview> |
| 217 | + |
| 218 | +### Changes |
| 219 | + |
| 220 | +#### <Category> |
| 221 | + |
| 222 | +- Change 1 |
| 223 | +- Change 2 |
| 224 | + |
| 225 | +--- |
| 226 | + |
| 227 | +## @dittolive/ditto-chat-ui v<version> |
| 228 | + |
| 229 | +**Compare**: https://github.com/getditto/DittoChat/compare/<range> |
| 230 | + |
| 231 | +### Summary |
| 232 | + |
| 233 | +<1-2 sentence overview> |
| 234 | + |
| 235 | +### Changes |
| 236 | + |
| 237 | +#### <Category> |
| 238 | + |
| 239 | +- Change 1 |
| 240 | +- Change 2 |
| 241 | + |
| 242 | +--- |
| 243 | + |
| 244 | +## Contributors |
| 245 | + |
| 246 | +Thank you to all contributors: |
| 247 | + |
| 248 | +- @username (Full Name) |
| 249 | +- @username2 (Full Name) |
| 250 | + |
| 251 | +## Installation |
| 252 | + |
| 253 | +\`\`\`bash |
| 254 | +npm install @dittolive/ditto-chat-core@<version> |
| 255 | +npm install @dittolive/ditto-chat-ui@<version> |
| 256 | +\`\`\` |
| 257 | + |
| 258 | +--- |
| 259 | + |
| 260 | +📦 Generated with Claude Code |
| 261 | +``` |
| 262 | + |
| 263 | +Present the release notes in a code block for easy copying. |
| 264 | + |
| 265 | +--- |
| 266 | + |
| 267 | +## Step 5: Create the Changeset File |
| 268 | + |
| 269 | +After generating and presenting the release notes, create the changeset: |
| 270 | + |
| 271 | +1. **Ask for confirmation on the version bump type**: |
| 272 | + - Based on the analysis, suggest the bump type (patch/minor/major) |
| 273 | + - "patch" (0.1.2 → 0.1.3) - Bug fixes, small changes |
| 274 | + - "minor" (0.1.2 → 0.2.0) - New features, non-breaking changes |
| 275 | + - "major" (0.1.2 → 1.0.0) - Breaking changes |
| 276 | + - If there are ANY breaking changes, it MUST be major |
| 277 | + |
| 278 | +2. **Generate the changeset filename**: |
| 279 | + - Use random two-word format (adjective-noun-verb pattern) |
| 280 | + - Example: `fluffy-sites-remain.md`, `modern-dragons-sink.md` |
| 281 | + |
| 282 | +3. **Create the changeset file** in `.changeset/` directory: |
| 283 | + |
| 284 | +For single package: |
| 285 | + |
| 286 | +```markdown |
| 287 | +--- |
| 288 | +'@dittolive/ditto-chat-core': minor |
| 289 | +--- |
| 290 | + |
| 291 | +<Use the summary from release notes, or a concise version> |
| 292 | +``` |
| 293 | + |
| 294 | +For both packages: |
| 295 | + |
| 296 | +```markdown |
| 297 | +--- |
| 298 | +'@dittolive/ditto-chat-core': minor |
| 299 | +'@dittolive/ditto-chat-ui': minor |
| 300 | +--- |
| 301 | + |
| 302 | +<Use the summary from release notes, or a concise version> |
| 303 | +``` |
| 304 | + |
| 305 | +4. **Confirm creation**: |
| 306 | + |
| 307 | +``` |
| 308 | +✅ Changeset created at .changeset/<filename>.md |
| 309 | +``` |
| 310 | + |
| 311 | +--- |
| 312 | + |
| 313 | +## Step 6: Next Steps |
| 314 | + |
| 315 | +After creating the changeset, provide these instructions: |
| 316 | + |
| 317 | +``` |
| 318 | +Next steps: |
| 319 | +1. Review the release notes above and edit if needed |
| 320 | +2. Commit the changeset file with your code changes |
| 321 | +3. Create/update your PR with both code changes and the changeset |
| 322 | +4. After PR merges to main, GitHub Actions will auto-create a "Version Packages" PR |
| 323 | +5. Review and merge the "Version Packages" PR to publish to NPM |
| 324 | +6. Create a GitHub Release with the release notes above |
| 325 | +``` |
| 326 | + |
| 327 | +**Optional Actions**: |
| 328 | + |
| 329 | +- Offer to save release notes to a file (e.g., `RELEASE_NOTES_v<version>.md`) |
| 330 | +- Suggest posting to relevant Slack channels (if applicable) |
| 331 | + |
| 332 | +--- |
| 333 | + |
| 334 | +## Error Handling |
| 335 | + |
| 336 | +- **If tag doesn't exist**: List recent tags with `git tag -l --sort=-version:refname | head -20` and ask for clarification |
| 337 | +- **If range is invalid**: Suggest using `git log --oneline -20` to find commits |
| 338 | +- **If no commits in range**: Inform user and exit gracefully |
| 339 | +- **If unable to categorize a commit**: Ask user for guidance on that specific commit |
| 340 | +- **If both packages affected but unclear which**: Ask user to clarify |
| 341 | + |
| 342 | +--- |
| 343 | + |
| 344 | +## Important Notes |
| 345 | + |
| 346 | +- **JavaScript/NPM Only** - This command only affects the two JavaScript packages, not other parts of the repo |
| 347 | +- **No Hallucination** - If something is unclear, ASK rather than guessing |
| 348 | +- **Breaking Changes Critical** - Always highlight and clearly mark breaking changes |
| 349 | +- **One Commit = One Category** - Never duplicate entries across categories |
| 350 | +- **Consistent Voice** - Maintain past tense throughout all entries |
| 351 | +- **Leverage Changesets** - If changesets already exist in the range, use them as primary source |
| 352 | + |
| 353 | +--- |
| 354 | + |
| 355 | +Now proceed with analyzing the git history and generating release notes for the user. |
0 commit comments