Pull Request Generation
Buddy automatically creates professional, well-formatted pull requests that match industry standards set by tools like Renovate. Each PR includes detailed information, release notes, and interactive features.
PR Format & Structure
Professional Layout
Buddy generates PRs with three separate dependency tables based on the types of updates found:
npm Dependencies Table
Full table with confidence badges and detailed metrics:
markdown
### npm Dependencies
| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [react](https://react.dev) | `^18.2.0` → `^18.3.1` | 📅 | 📈 | ✅ | 🔒 |
| [lodash](https://lodash.com) | `^4.17.20` → `^4.17.21` | 📅 | 📈 | ✅ | 🔒 |
Launchpad/pkgx Dependencies Table
Simplified table focusing on package updates and file locations:
markdown
### Launchpad/pkgx Dependencies
| Package | Change | File | Status |
|---|---|---|---|
| [bun.com](https://bun.sh) | `^1.2.16` → `^1.2.19` | deps.yaml | ✅ Available |
| node | `^20.0.0` → `^20.5.0` | dependencies.yaml | ✅ Available |
GitHub Actions Table
Workflow automation updates with direct repository links:
markdown
### GitHub Actions
| Action | Change | File | Status |
|---|---|---|---|
| [actions/checkout](https://github.com/actions/checkout) | `v4` → `v4.2.2` | ci.yml | ✅ Available |
| [oven-sh/setup-bun](https://github.com/oven-sh/setup-bun) | `v2` → `v2.0.2` | release.yml | ✅ Available |
Complete Example
markdown
# chore(deps): update dependencies
This PR contains the following updates:
### npm Dependencies
| Package | Change | Age | Adoption | Passing | Confidence |
[... full table with badges ...]
### Launchpad/pkgx Dependencies
| Package | Change | File | Status |
[... simplified table ...]
### GitHub Actions
| Action | Change | File | Status |
[... workflow updates ...]
---
### Release Notes
[Detailed release notes for each dependency type...]
---
### 📊 Package Statistics
[Statistics tailored to each dependency type...]
---
This PR was generated by [Buddy](https://github.com/stacksjs/buddy-bot) 🤖
Key Features
- 📊 Confidence Metrics: Age, adoption, and compatibility scores
- 🔗 Source Links: Direct links to repositories and changelogs
- 📈 Download Stats: Weekly download numbers for popularity context
- 📝 Release Notes: Automatically fetched from GitHub releases
- ♻️ Rebase Support: Interactive checkbox for PR updates
Dynamic Labeling
Buddy automatically applies contextual labels based on update content:
Core Labels
dependencies
: Applied to all dependency update PRspatch
/minor
/major
: Based on semantic version changessecurity
: Auto-detected for security-related packagesbulk-update
: For PRs with 5+ package updates
Configuration
typescript
// buddy-bot.config.ts
export default {
pullRequest: {
labels: [
'dependencies', // Always included
'automated', // Custom label
'needs-review', // Custom workflow label
]
}
}
Smart Label Detection
typescript
// Automatically detected labels
const securityPackages = [
'helmet',
'express-rate-limit',
'cors',
'bcrypt',
'jsonwebtoken'
]
// Applied when detected in updates
if (hasSecurityPackage) {
labels.add('security')
}
Assignees & Reviewers
Configuration
typescript
export default {
pullRequest: {
reviewers: ['team-lead', 'senior-dev'],
assignees: ['project-maintainer'],
labels: ['dependencies', 'auto-merge-candidate']
}
}
Automatic Assignment
- Reviewers: Automatically requested for PR review
- Assignees: Assigned ownership of the PR
- Teams: Support for GitHub team assignments
Duplicate Detection & Updates
Smart PR Management
Buddy prevents duplicate PRs by:
- Title Similarity: Detects similar PR titles
- Branch Pattern: Recognizes
buddy-bot/*
branches - Content Analysis: Compares package lists in PR bodies
- Author Filtering: Only checks PRs from automation
Update Behavior
typescript
const existingPR = existingPRs.find(pr =>
(pr.title === prTitle
|| pr.head.startsWith(branchPattern)
|| this.isSimilarPRTitle(pr.title, prTitle))
&& (pr.author === 'github-actions[bot]'
|| pr.author.includes('buddy')
|| pr.head.startsWith('buddy-bot/')),
)
if (existingPR) {
// Update existing PR instead of creating new one
await gitProvider.updatePullRequest(existingPR.number, {
title: prTitle,
body: prBody,
labels: dynamicLabels,
assignees: this.config.pullRequest?.assignees,
})
}
Rebase Functionality
Interactive Rebase
PRs include a rebase checkbox for manual triggers:
markdown
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box
---
CLI Commands
bash
# Manually rebase a specific PR
buddy-bot rebase 17
# Auto-detect and rebase checked PRs
buddy-bot check-rebase
# Force rebase even if up-to-date
buddy-bot rebase 17 --force
Rebase Process
- Checkbox Detection: Scans PR body for checked rebase box
- Content Analysis: Extracts current package updates
- Fresh Scan: Gets latest available versions
- In-Place Update: Updates existing PR (preserves PR number)
- Notification: Unchecks box and notifies completion
Package.json Formatting
Preserves Original Format
Buddy maintains your exact JSON formatting:
javascript
// Before (your format)
const beforeFormat = {
files: ['README.md', 'bin', 'dist'],
dependencies: {
cac: '6.7.13'
}
}
// After (format preserved)
const afterFormat = {
files: ['README.md', 'bin', 'dist'],
dependencies: {
cac: '6.7.14'
}
}
Version Prefix Preservation
- Without caret:
"react": "18.2.0"
→"react": "18.3.1"
- With caret:
"react": "^18.2.0"
→"react": "^18.3.1"
- With tilde:
"react": "~18.2.0"
→"react": "~18.3.1"
Release Notes Integration
Automatic Fetching
Buddy automatically fetches release notes from:
- GitHub Releases: Official release notes from repositories
- Changelog Files: CHANGELOG.md, HISTORY.md, etc.
- Package Registry: npm registry metadata
- Repository Links: Direct links to compare views
Content Processing
typescript
interface ReleaseNotesOptions {
packageName: string
fromVersion: string
toVersion: string
}
interface ReleaseNotesResult {
content: string
source: string
}
async function fetchReleaseNotes(
options: ReleaseNotesOptions
): Promise<ReleaseNotesResult> {
// 1. Try GitHub releases API
const releases = await github.repos.listReleases()
// 2. Fallback to changelog files
const changelog = await fetchChangelog(repoUrl)
// 3. Extract relevant sections
return extractVersionNotes(changelog, options.fromVersion, options.toVersion)
}
Branch Management
Naming Convention
typescript
const branchName = `buddy-bot/update-${group.name.toLowerCase().replace(/\s+/g, '-')}-${timestamp}`
// Examples:
// buddy-bot/update-non-major-dependencies-1704123456789
// buddy-bot/update-react-ecosystem-1704123456789
// buddy-bot/update-security-patches-1704123456789
Branch Lifecycle
- Creation: New branch from base branch (main/develop)
- Commits: Package.json updates with descriptive messages
- PR Creation: Automated PR creation with full metadata
- Updates: In-place updates preserve branch and PR number
- Cleanup: Automatic cleanup after merge/close
Customization Options
PR Title Format
typescript
export default {
pullRequest: {
titleFormat: 'chore(deps): {updateType} {packages}',
// Results in: "chore(deps): update dependencies react, typescript"
}
}
Body Template
typescript
export default {
pullRequest: {
bodyTemplate: `
# 🤖 Automated Dependency Update
{updateTable}
## 📋 Changes
{releaseNotes}
## 🔧 Configuration
This update was generated with strategy: {strategy}
`
}
}
Commit Message Format
typescript
export default {
pullRequest: {
commitMessageFormat: 'chore(deps): update {packages}',
// Results in: "chore(deps): update react to v18.3.1"
}
}
Best Practices
PR Organization
- Group Related Updates: Keep ecosystem packages together
- Separate Major Updates: Create individual PRs for breaking changes
- Batch Patch Updates: Combine small patch updates
- Label Strategically: Use labels for workflow automation
Review Process
- Automated Checks: Let CI validate updates first
- Review Major Updates: Always review breaking changes manually
- Test Thoroughly: Run full test suites on update branches
- Monitor Performance: Watch for performance regressions
Merge Strategy
typescript
export default {
pullRequest: {
autoMerge: {
enabled: true,
strategy: 'squash',
conditions: ['patch-only', 'ci-passing']
}
}
}
GitHub Integration
Required Permissions
yaml
permissions:
contents: write # Create branches and commits
pull-requests: write # Create and update PRs
issues: write # Assign users and add labels
actions: read # Read workflow status
API vs CLI
Buddy uses a dual approach:
- GitHub CLI (Primary): More reliable for permissions
- GitHub API (Fallback): Direct API calls when CLI fails
typescript
try {
return await this.createPullRequestWithCLI(options)
}
catch (error) {
console.warn('GitHub CLI failed, trying API...', error)
return await this.createPullRequestWithAPI(options)
}