Skip to content

Commit 7edd828

Browse files
committed
chore: improve handling of large pr bodies
1 parent 97efa37 commit 7edd828

File tree

2 files changed

+75
-46
lines changed

2 files changed

+75
-46
lines changed

src/buddy.ts

Lines changed: 60 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -422,63 +422,77 @@ export class Buddy {
422422

423423
// Handle package.json updates - only for actual package.json files, not dependency or GitHub Actions files
424424
const packageJsonUpdates = updates.filter(update =>
425-
update.file === 'package.json'
425+
update.file.endsWith('package.json')
426426
&& !update.file.includes('.yaml')
427427
&& !update.file.includes('.yml')
428428
&& !update.file.includes('.github/workflows/'),
429429
)
430-
if (packageJsonUpdates.length > 0) {
431-
const packageJsonPath = 'package.json'
432430

433-
// Read current package.json content as string to preserve formatting
434-
let packageJsonContent = fs.readFileSync(packageJsonPath, 'utf-8')
435-
436-
// Parse to understand structure
437-
const packageJson = JSON.parse(packageJsonContent)
438-
439-
// Apply updates using string replacement to preserve formatting
440-
for (const update of packageJsonUpdates) {
441-
let packageFound = false
442-
443-
// Clean package name (remove dependency type info like "(dev)")
444-
const cleanPackageName = update.name.replace(/\s*\(dev\)$/, '').replace(/\s*\(peer\)$/, '').replace(/\s*\(optional\)$/, '')
445-
446-
// Try to find and update the package in each dependency section
447-
const dependencySections = ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies']
448-
449-
for (const section of dependencySections) {
450-
if (packageJson[section] && packageJson[section][cleanPackageName]) {
451-
const currentVersionInFile = packageJson[section][cleanPackageName]
452-
453-
// Extract the original version prefix (^, ~, >=, etc.) or lack thereof
454-
const versionPrefixMatch = currentVersionInFile.match(/^(\D*)/)
455-
const originalPrefix = versionPrefixMatch ? versionPrefixMatch[1] : ''
431+
// Group package.json updates by file
432+
const updatesByPackageFile = new Map<string, PackageUpdate[]>()
433+
for (const update of packageJsonUpdates) {
434+
if (!updatesByPackageFile.has(update.file)) {
435+
updatesByPackageFile.set(update.file, [])
436+
}
437+
updatesByPackageFile.get(update.file)!.push(update)
438+
}
456439

457-
// Create regex to find the exact line with this package and version
458-
// This handles various formatting styles like: "package": "version", "package":"version", etc.
459-
const packageRegex = new RegExp(
460-
`("${cleanPackageName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}"\\s*:\\s*")([^"]+)(")`,
461-
'g',
462-
)
440+
// Process each package.json file
441+
for (const [packageJsonPath, packageUpdates] of updatesByPackageFile) {
442+
try {
443+
// Read current package.json content as string to preserve formatting
444+
let packageJsonContent = fs.readFileSync(packageJsonPath, 'utf-8')
445+
446+
// Parse to understand structure
447+
const packageJson = JSON.parse(packageJsonContent)
448+
449+
// Apply updates using string replacement to preserve formatting
450+
for (const update of packageUpdates) {
451+
let packageFound = false
452+
453+
// Clean package name (remove dependency type info like "(dev)")
454+
const cleanPackageName = update.name.replace(/\s*\(dev\)$/, '').replace(/\s*\(peer\)$/, '').replace(/\s*\(optional\)$/, '')
455+
456+
// Try to find and update the package in each dependency section
457+
const dependencySections = ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies']
458+
459+
for (const section of dependencySections) {
460+
if (packageJson[section] && packageJson[section][cleanPackageName]) {
461+
const currentVersionInFile = packageJson[section][cleanPackageName]
462+
463+
// Extract the original version prefix (^, ~, >=, etc.) or lack thereof
464+
const versionPrefixMatch = currentVersionInFile.match(/^(\D*)/)
465+
const originalPrefix = versionPrefixMatch ? versionPrefixMatch[1] : ''
466+
467+
// Create regex to find the exact line with this package and version
468+
// This handles various formatting styles like: "package": "version", "package":"version", etc.
469+
const packageRegex = new RegExp(
470+
`("${cleanPackageName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}"\\s*:\\s*")([^"]+)(")`,
471+
'g',
472+
)
473+
474+
// Preserve the original prefix when updating to new version
475+
const newVersion = `${originalPrefix}${update.newVersion}`
476+
packageJsonContent = packageJsonContent.replace(packageRegex, `$1${newVersion}$3`)
477+
packageFound = true
478+
break
479+
}
480+
}
463481

464-
// Preserve the original prefix when updating to new version
465-
const newVersion = `${originalPrefix}${update.newVersion}`
466-
packageJsonContent = packageJsonContent.replace(packageRegex, `$1${newVersion}$3`)
467-
packageFound = true
468-
break
482+
if (!packageFound) {
483+
console.warn(`Package ${cleanPackageName} not found in ${packageJsonPath}`)
469484
}
470485
}
471486

472-
if (!packageFound) {
473-
console.warn(`Package ${cleanPackageName} not found in package.json`)
474-
}
487+
fileUpdates.push({
488+
path: packageJsonPath,
489+
content: packageJsonContent,
490+
type: 'update' as const,
491+
})
492+
}
493+
catch (error) {
494+
console.warn(`Failed to update ${packageJsonPath}:`, error)
475495
}
476-
477-
fileUpdates.push({
478-
path: packageJsonPath,
479-
content: packageJsonContent,
480-
type: 'update' as const,
481-
})
482496
}
483497

484498
// Handle dependency file updates (deps.yaml, dependencies.yaml, etc.)

src/pr/pr-generator.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,21 @@ export class PullRequestGenerator {
469469
body += `---\n\n`
470470
body += `This PR was generated by [Buddy](https://github.com/stacksjs/buddy-bot) 🤖`
471471

472+
// Ensure PR body doesn't exceed GitHub's 65,536 character limit
473+
const MAX_BODY_LENGTH = 60000 // Leave some buffer
474+
if (body.length > MAX_BODY_LENGTH) {
475+
const truncatedBody = body.substring(0, MAX_BODY_LENGTH)
476+
const lastDetailsEnd = truncatedBody.lastIndexOf('</details>')
477+
if (lastDetailsEnd > 0) {
478+
// Truncate at the last complete details section
479+
body = `${truncatedBody.substring(0, lastDetailsEnd + 10)}\n\n---\n\n**Note**: This PR body was truncated due to GitHub's character limit. View the full details in the individual commits.\n\n`
480+
}
481+
else {
482+
body = `${truncatedBody}\n\n---\n\n**Note**: This PR body was truncated due to GitHub's character limit.\n\n`
483+
}
484+
body += `This PR was generated by [Buddy](https://github.com/stacksjs/buddy-bot) 🤖`
485+
}
486+
472487
return body
473488
}
474489

0 commit comments

Comments
 (0)