Skip to content

feat(changelog): generate the changelog from releases and keep it synced#101

Merged
WomB0ComB0 merged 2 commits into
mainfrom
feat/changelog-automation
Jul 24, 2026
Merged

feat(changelog): generate the changelog from releases and keep it synced#101
WomB0ComB0 merged 2 commits into
mainfrom
feat/changelog-automation

Conversation

@WomB0ComB0

@WomB0ComB0 WomB0ComB0 commented Jul 24, 2026

Copy link
Copy Markdown
Member

Why

The changelog from #100 was a point-in-time snapshot. The next SDK release made it stale with nothing to update it — the exact drift I'd spent the day fixing three instances of. This makes it self-maintaining.

How it works

scripts/build_changelog.py regenerates the version tables between the CHANGELOG:AUTOGEN markers from published GitHub releases across the five SDK repos (npm, PyPI, crates.io, NuGet, vcpkg). It is deterministic — no dates, no randomness — so a run with no new releases produces no diff. --check exits non-zero when the page is out of date. Reads live releases via gh, or a --releases-file JSON dump for offline testing.

automation/changelog-notes.md holds editorial prose keyed by ## YYYY-MM. The generator splices each month's note above that month's tables. This is the core design choice: mechanical data stays automatic, human prose stays human, neither clobbers the other. The two migration callouts (npm scope, Rust rename) moved here from the hand-written page.

.github/workflows/changelog-sync.yml runs the generator weekly and on demand, opening a PR via the same bot account and DOCS_REPO_PR_TOKEN as the existing api-docs sync.

Two judgment calls worth reviewing

Scope supersession. A naive regeneration listed both @resq-sw/* and @resq-systems/* in July, because the rename happened mid-month — putting the abandoned scope's table directly under a "stop using it" note. The generator now drops an old-scope package from a month's table only when its new-scope counterpart shipped that same month. So July shows only @resq-systems; May and April keep @resq-sw, which was genuinely current then. Real history preserved, dead-scope noise removed.

No PR-check job. My first draft had one. It would run --check, which hits the live releases API — so any PR opened after a new release would fail, even an unrelated one. Removed. The scheduled run is the mechanism; review the PR it opens.

Second bug fixed: the api-docs TypeScript trigger

Same root cause as #99. api-docs.typescript.yml triggered only on @resq-sw/*@v* tags, so the TypeScript SDK doc sync stopped firing entirely when packages moved to @resq-systems. Now matches both scopes.

Verification

  • Generator reproduces the committed page exactly; --check returns 0 when current and 1 on a simulated new release
  • Output byte-identical across two runs (deterministic)
  • Every version in the page cross-checked against real release tags — npm, crates, the pypi resq-mcp series, .NET, vcpkg
  • changelog.mdx compiles under @mdx-js/mdx
  • Locale parity 0 gaps (automation/ now excluded as tooling; changelog.mdx stays exempt)
  • ruff check / ruff format --check clean on both scripts

Not done — flagged for follow-up

api-docs.typescript.yml still hardcodes the @resq-sw scope in its generated output (the PR body and README it writes, ~lines 447 and 598) rather than reading the scope from package.json. Those labels will be wrong for @resq-systems packages. Left because that template runs typedoc against the resq-software/npm monorepo, which I can't execute or test here — an untested functional change to another repo's generation logic is riskier than flagging it.

Test plan

  • Run changelog sync via workflow_dispatch; confirm it opens no PR (already current) — proves the no-op path
  • Confirm DOCS_REPO_PR_TOKEN is present in this repo's secrets (the api-docs sync uses it, so it should be)
  • Next npm/crates release: confirm the weekly run opens a PR updating only the tables
  • Add a throwaway ## 2026-08 note, run the generator, confirm it splices above the tables and compiles

Summary by CodeRabbit

  • New Features

    • Added an automatically generated SDK changelog with release tables and editorial notes.
    • Added weekly and on-demand changelog synchronization that creates a pull request when updates are available.
    • Added support for documentation synchronization across both legacy and current package scopes.
  • Documentation

    • Documented changelog generation, formatting requirements, and local validation commands.
    • Added release notes covering recent SDK and CLI updates.
  • Maintenance

    • Improved translation parity checks by excluding non-translatable content directories.

The changelog shipped in #100 was a point-in-time snapshot; the next SDK
release made it stale with nothing to update it. This makes it self-maintaining.

- scripts/build_changelog.py regenerates the version tables between the
  CHANGELOG:AUTOGEN markers from published GitHub releases across the five SDK
  repos. Deterministic (no dates/random), so no-release runs produce no diff.
  --check exits non-zero when out of date. Reads live releases via gh, or a
  --releases-file for offline testing.
- automation/changelog-notes.md holds editorial prose keyed by month; the
  generator splices it above that month's tables. Mechanical data stays
  automatic, human prose stays human, neither clobbers the other. The two
  migration callouts (npm scope, Rust rename) moved here from the hand-written
  page.
- Scope supersession: within a month, an @resq-sw package is dropped from the
  table only when its @ResQ-Systems counterpart shipped too. July shows only
  the new scope; May/April keep @resq-sw, which was current then.
- .github/workflows/changelog-sync.yml runs it weekly and on demand, opening a
  PR via the same bot account and DOCS_REPO_PR_TOKEN as the api-docs sync.
  No PR-check job: --check hits live releases and would fail unrelated PRs
  opened after a release.

Also fixes a second breakage from the scope rename: the api-docs.typescript
template still triggered only on @resq-sw/*@v* tags, so the TypeScript SDK doc
sync stopped firing when packages moved to @ResQ-Systems. Now matches both.

parity excludes automation/ (tooling, never translated); changelog.mdx stays
exempt via .i18n-exempt. Verified: generator reproduces the page, --check
detects drift, every version cross-checked against real release tags, MDX
compiles, parity 0 gaps, ruff clean.

Follow-up (not done here, runs against the npm monorepo I can't test):
api-docs.typescript still hardcodes the @resq-sw scope in its generated PR
body and README output (lines ~447, ~598) — those labels will be wrong for
@ResQ-Systems packages.
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@github-actions github-actions Bot added area:ci GitHub Actions, workflows, CI area:content MDX/MD documentation content area:meta Repo meta — docs.json, README, etc. labels Jul 24, 2026
@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@WomB0ComB0, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 51 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fca1b059-9af7-4aa0-8b45-621816d92e82

📥 Commits

Reviewing files that changed from the base of the PR and between 3f57464 and 442c5c8.

📒 Files selected for processing (3)
  • .github/workflows/changelog-sync.yml
  • README.md
  • scripts/build_changelog.py
📝 Walkthrough

Walkthrough

Adds a release-driven changelog generator, editorial monthly notes, regenerated changelog content, scheduled synchronization workflow, package-scope tag documentation, and expanded translation-parity exclusions.

Changes

Changelog automation

Layer / File(s) Summary
Release parsing and changelog rendering
scripts/build_changelog.py, automation/changelog-notes.md, changelog.mdx
The generator loads GitHub or offline release data, parses and groups versions by month, applies scope supersession, inserts editorial notes, and rewrites the marked changelog region.
Workflow and process documentation
.github/workflows/changelog-sync.yml, README.md, automation/source-repo-templates/api-docs.typescript.yml
A weekly or manually triggered workflow creates a changelog PR when output changes; documentation covers local generation and both TypeScript package scopes.

Translation parity exclusions

Layer / File(s) Summary
Exclude non-translatable directories
scripts/i18n_parity.py
Parity checks now exclude snippets, sdks, and automation directories.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Scheduler
  participant ChangelogSync
  participant BuildChangelog
  participant GitHubReleases
  participant Changelog
  participant PullRequest
  Scheduler->>ChangelogSync: trigger weekly or manually
  ChangelogSync->>BuildChangelog: execute generator
  BuildChangelog->>GitHubReleases: fetch release data
  GitHubReleases-->>BuildChangelog: return releases
  BuildChangelog->>Changelog: update AUTOGEN region
  ChangelogSync->>PullRequest: create PR when changelog.mdx changes
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: generating and syncing the changelog from release data.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/changelog-automation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
automation/changelog-notes.md (1)

3-15: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use direct, active contributor guidance.

Rewrite the instruction copy in active second-person voice rather than describing the process impersonally.

  • automation/changelog-notes.md#L3-L15: address the reader directly when explaining how to add and format notes.
  • changelog.mdx#L13-L15: tell readers how to regenerate tables and where to place editorial notes.
  • README.md#L210-L213: directly instruct readers how to add month-keyed notes.

As per coding guidelines, use active voice and second person ("you") in documentation writing.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@automation/changelog-notes.md` around lines 3 - 15, Rewrite the documentation
guidance in active second-person voice. In automation/changelog-notes.md lines
3-15, directly tell contributors how to add and format month-keyed notes; in
changelog.mdx lines 13-15, directly explain how to regenerate tables and where
to place editorial notes; and in README.md lines 210-213, directly instruct
readers how to add month-keyed notes. Preserve the existing requirements and
examples while consistently addressing the reader as “you.”

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/changelog-sync.yml:
- Line 34: Update the actions/checkout step in the scheduled workflow to
reference the reviewed immutable full commit SHA instead of the mutable v7 tag,
matching the existing SHA-pinning convention for other actions.

In `@README.md`:
- Around line 205-208: Update the README guidance around changelog.mdx to state
that only the region between the CHANGELOG:AUTOGEN markers is generated and
overwritten by scripts/build_changelog.py; clarify that content outside those
markers is preserved and may be edited manually.

In `@scripts/build_changelog.py`:
- Around line 79-88: Validate release tags against the complete expected format
in each parsing branch before returning package and version values, rejecting
tags with unexpected content rather than capturing arbitrary text. In
version_table(), escape all dynamic package, version, and tag-derived values
before inserting them into generated MDX, including backticks, pipes, and JSX
delimiters, while preserving valid release-tag rendering.

---

Nitpick comments:
In `@automation/changelog-notes.md`:
- Around line 3-15: Rewrite the documentation guidance in active second-person
voice. In automation/changelog-notes.md lines 3-15, directly tell contributors
how to add and format month-keyed notes; in changelog.mdx lines 13-15, directly
explain how to regenerate tables and where to place editorial notes; and in
README.md lines 210-213, directly instruct readers how to add month-keyed notes.
Preserve the existing requirements and examples while consistently addressing
the reader as “you.”
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d1cf6530-6153-48dc-bd90-0b6c9ce470da

📥 Commits

Reviewing files that changed from the base of the PR and between 5e2528f and 3f57464.

📒 Files selected for processing (7)
  • .github/workflows/changelog-sync.yml
  • README.md
  • automation/changelog-notes.md
  • automation/source-repo-templates/api-docs.typescript.yml
  • changelog.mdx
  • scripts/build_changelog.py
  • scripts/i18n_parity.py

Comment thread .github/workflows/changelog-sync.yml Outdated
Comment thread README.md Outdated
Comment thread scripts/build_changelog.py Outdated
All three from CodeRabbit review on #101.

- build_changelog.py: package names and versions come from git tags and land
  directly in MDX table cells and JSX. Reject any that contain characters
  outside [@\w./+-] — backticks, pipes, braces, angle brackets — which could
  corrupt the table or inject MDX into the auto-opened PR. Every real ResQ tag
  passes (304 releases unchanged); a crafted tag is skipped with a warning.
- changelog-sync.yml: pin actions/checkout to the commit SHA already used by
  the api-docs templates, so upstream tag movement can't alter workflow code.
- README: clarify that only the region between the AUTOGEN markers is
  generated; the intro above is hand-maintained.
@WomB0ComB0
WomB0ComB0 merged commit 8bb2646 into main Jul 24, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:ci GitHub Actions, workflows, CI area:content MDX/MD documentation content area:meta Repo meta — docs.json, README, etc.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants