feat: derive batch PR titles and commit messages from changelog entries#41
Conversation
Every generated SDK PR shared the same uninformative title "feat(generated): <service> (batch <id>)". Derive the title from the classify entries instead (e.g. "feat(generated): Added roles to organization membership models (+N more)"), keeping a valid conventional-commit prefix so each SDK repo's PR-title lint still passes; fall back to the old services/batch form when there are no entries. The catch-all commit message is now "chore(generated): regenerate shared files for <services>". Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Greptile SummaryThis PR makes generated SDK batch PRs and commits more descriptive. The main changes are:
Confidence Score: 3/5The title and commit-message behavior is covered, but the dependency override can affect the Postman generation runtime path.
package.json
What T-Rex did
Prompt To Fix All With AIFix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
package.json:58
**Transitive YAML Version Breakage**
Changing the `js-yaml` override to `^5.1.0` forces transitive consumers onto the new major version too. The Postman generation path uses `openapi-to-postmanv2@6.1.0`, which declares its own `js-yaml` dependency in the lockfile; if that converter relies on the v4 package shape or APIs, `npm run generate:postman` can fail at runtime even though this repo's direct `yaml.load()` call still type-checks.
Reviews (3): Last reviewed commit: "chore: update deps" | Re-trigger Greptile |
Two review findings, both in the new title logic: - chore-only batches: rollupPrefix returned chore(generated) while the changelog override (rollupForEntries) rolls chore-only up to fix, so the PR title and release-note type diverged. rollupPrefix now mirrors rollupForEntries exactly (feat! / feat / else fix) and never returns chore. - malformed entries: prTitle did `orderedEntries(entries)[0].summary`, which threw when entries had no recognized prefix and emitted a literal `undefined` when the lead entry lacked a summary. It now falls back to the services/batch title in both cases (the fallback's whole purpose). Adds regression tests for chore-only rollup, unrecognized-prefix fallback, and missing-summary fallback. 42 tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| }, | ||
| "overrides": { | ||
| "js-yaml": "^4.1.1", | ||
| "js-yaml": "^5.1.0", |
There was a problem hiding this comment.
Transitive YAML Version Breakage
Changing the js-yaml override to ^5.1.0 forces transitive consumers onto the new major version too. The Postman generation path uses openapi-to-postmanv2@6.1.0, which declares its own js-yaml dependency in the lockfile; if that converter relies on the v4 package shape or APIs, npm run generate:postman can fail at runtime even though this repo's direct yaml.load() call still type-checks.
Prompt To Fix With AI
This is a comment left during a code review.
Path: package.json
Line: 58
Comment:
**Transitive YAML Version Breakage**
Changing the `js-yaml` override to `^5.1.0` forces transitive consumers onto the new major version too. The Postman generation path uses `openapi-to-postmanv2@6.1.0`, which declares its own `js-yaml` dependency in the lockfile; if that converter relies on the v4 package shape or APIs, `npm run generate:postman` can fail at runtime even though this repo's direct `yaml.load()` call still type-checks.
How can I resolve this? If you propose a fix, please make it concise.PR #41's dep update bumped the js-yaml override from ^4.1.1 to ^5.1.0. js-yaml 5.x dropped the `types` named export, which @redocly/openapi-core (via @workos/oagen) imports, so the override forced every SDK generation job to fail at module load with "does not provide an export named 'types'". Our only direct use (scripts/postman/generate.ts) is yaml.load via default import, which works on either major, so there's no reason to be on 5.x. 4.2.0 stays past the vulnerable 3.x range that the override originally guarded against. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
Every generated SDK PR in a batch shared the same contentless title —
feat(generated): OrganizationMembership (batch e471ddef)— language-independent and saying nothing about what changed.scripts/open-batch-pr.mjsnow derives the title from the classify entries (the same summaries that go into the release-note fragment), e.g.feat(generated): Added roles to organization membership models (+2 more):rollupPrefix()mirrors the changelog rollup (feat!→feat(generated)!, elsefeat→feat(generated), elsefix/chore), so the title keeps a valid conventional-commit prefix and the SDK repos'lint_pr_title/ "Validate PR title" check still passes.entriesSummary()uses the lead entry's summary plus(+N more).feat(generated): <services> (batch <id>)form.The catch-all commit message is now
chore(generated): regenerate shared files for <services>(the per-entry commits already used the descriptive entry headlines).Test plan
node --test scripts/__tests__/open-batch-pr.spec.mjs— updated + new cases: single entry, multiple entries with(+N more), zero-entries fallback,feat!/feat/fixrollup ordering, a regex assertion that every produced title keeps a valid conventional prefix, the new catch-all message, and a--dry-runend-to-end asserting thegh pr createtitle is entry-derived.npm test: 41 pass, 0 fail.🤖 Generated with Claude Code