Skip to content

feat: derive batch PR titles and commit messages from changelog entries#41

Merged
gjtorikian merged 3 commits into
mainfrom
feat/descriptive-batch-pr-titles
Jun 25, 2026
Merged

feat: derive batch PR titles and commit messages from changelog entries#41
gjtorikian merged 3 commits into
mainfrom
feat/descriptive-batch-pr-titles

Conversation

@gjtorikian

Copy link
Copy Markdown
Collaborator

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.mjs now 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)!, else featfeat(generated), else fix/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).
  • With zero entries it falls back to the previous 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/fix rollup ordering, a regex assertion that every produced title keeps a valid conventional prefix, the new catch-all message, and a --dry-run end-to-end asserting the gh pr create title is entry-derived.
  • Full npm test: 41 pass, 0 fail.

🤖 Generated with Claude Code

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-apps

greptile-apps Bot commented Jun 25, 2026

Copy link
Copy Markdown

Greptile Summary

This PR makes generated SDK batch PRs and commits more descriptive. The main changes are:

  • PR titles now come from classified changelog entries when available.
  • Malformed or empty entries fall back to the old batch title.
  • Catch-all generated commits now include the affected services.
  • Tests cover title rollups, fallback behavior, dry-run output, and commit messages.
  • Development dependencies were bumped.

Confidence Score: 3/5

The title and commit-message behavior is covered, but the dependency override can affect the Postman generation runtime path.

  • The changed script behavior is focused and covered by targeted tests for entry-derived titles, fallback titles, rollup prefixes, dry-run output, and catch-all commit messages.
  • The package override changes dependency resolution beyond the script being modified, which can affect a transitive converter used by the Postman generation command.
  • The remaining risk is isolated to dependency resolution around js-yaml and openapi-to-postmanv2 rather than the PR title derivation logic.

package.json

T-Rex T-Rex Logs

What T-Rex did

  • The base run of the batch-pr-title tests was executed and showed the old generic dry-run title coverage along with the 13-test suite passing.
  • The head run of the same focused test file was executed and showed 19 passing tests, including descriptive dry-run title derivation and new catch-all commit message assertions.
  • A base direct probe was executed to inspect title generation and export behavior, showing that the generic fallback title was produced and catchAllMessage was not exported.
  • A head direct probe was executed to inspect the updated title and commit-message coverage, revealing multiple generated tag variants (feat(generated), feat(generated)!, fix(generated), (+N more)), zero-entry and malformed fallbacks, and the generated chore line 'chore(generated): regenerate shared files for Vault, SSO'.

View all artifacts

T-Rex Ran code and verified through T-Rex

Prompt To Fix All With AI
Fix 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

Comment thread scripts/open-batch-pr.mjs Outdated
Comment thread scripts/open-batch-pr.mjs
gjtorikian and others added 2 commits June 25, 2026 14:27
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>
@gjtorikian gjtorikian merged commit b8952c5 into main Jun 25, 2026
3 checks passed
@gjtorikian gjtorikian deleted the feat/descriptive-batch-pr-titles branch June 25, 2026 18:39
Comment thread package.json
},
"overrides": {
"js-yaml": "^4.1.1",
"js-yaml": "^5.1.0",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 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.

gjtorikian added a commit that referenced this pull request Jun 25, 2026
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant