Skip to content

Commit 7194ba3

Browse files
committed
feat: add Dependency Dashboard
chore: wip
1 parent f2b97e2 commit 7194ba3

File tree

11 files changed

+1420
-10
lines changed

11 files changed

+1420
-10
lines changed
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
name: Buddy Dashboard Management
2+
3+
on:
4+
schedule:
5+
- cron: '0 9 * * 1,3,5' # Monday, Wednesday, Friday at 9 AM UTC
6+
workflow_dispatch: # Manual triggering
7+
inputs:
8+
pin:
9+
description: Pin the dashboard issue
10+
required: false
11+
default: true
12+
type: boolean
13+
title:
14+
description: Custom dashboard title
15+
required: false
16+
type: string
17+
issue_number:
18+
description: Specific issue number to update
19+
required: false
20+
type: string
21+
verbose:
22+
description: Enable verbose logging
23+
required: false
24+
default: true
25+
type: boolean
26+
dry_run:
27+
description: Dry run (preview only)
28+
required: false
29+
default: false
30+
type: boolean
31+
32+
env:
33+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
34+
35+
permissions:
36+
contents: read
37+
pull-requests: read
38+
issues: write
39+
actions: read
40+
checks: read
41+
statuses: read
42+
43+
jobs:
44+
update-dashboard:
45+
runs-on: ubuntu-latest
46+
47+
steps:
48+
- name: Checkout repository
49+
uses: actions/checkout@v4
50+
with:
51+
token: ${{ secrets.GITHUB_TOKEN }}
52+
53+
- name: Setup Bun
54+
uses: oven-sh/setup-bun@v2
55+
with:
56+
bun-version: latest
57+
58+
- name: Install dependencies
59+
run: bun install
60+
61+
- name: Build buddy-bot
62+
run: bun run build
63+
64+
- name: Display dashboard configuration
65+
run: |
66+
echo "📊 **Buddy Bot Dashboard Management**"
67+
echo "Pin Dashboard: ${{ github.event.inputs.pin || 'true' }}"
68+
echo "Custom Title: ${{ github.event.inputs.title || 'default' }}"
69+
echo "Issue Number: ${{ github.event.inputs.issue_number || 'auto-detect' }}"
70+
echo "Verbose: ${{ github.event.inputs.verbose || 'true' }}"
71+
echo "Dry Run: ${{ github.event.inputs.dry_run || 'false' }}"
72+
echo "Triggered by: ${{ github.event_name }}"
73+
echo "Repository: ${{ github.repository }}"
74+
echo "Branch: ${{ github.ref_name }}"
75+
76+
- name: Update Dependency Dashboard
77+
run: |
78+
PIN="${{ github.event.inputs.pin || 'true' }}"
79+
TITLE="${{ github.event.inputs.title }}"
80+
ISSUE_NUMBER="${{ github.event.inputs.issue_number }}"
81+
VERBOSE="${{ github.event.inputs.verbose || 'true' }}"
82+
DRY_RUN="${{ github.event.inputs.dry_run || 'false' }}"
83+
84+
echo "📊 Updating dependency dashboard..."
85+
echo "Pin: $PIN"
86+
echo "Title: ${TITLE:-default}"
87+
echo "Issue Number: ${ISSUE_NUMBER:-auto-detect}"
88+
echo "Verbose: $VERBOSE"
89+
echo "Dry Run: $DRY_RUN"
90+
echo ""
91+
92+
set -e # Exit on any error
93+
94+
# Build the command
95+
COMMAND="bun buddy dashboard"
96+
97+
if [ "$PIN" = "true" ]; then
98+
COMMAND="$COMMAND --pin"
99+
fi
100+
101+
if [ "$TITLE" != "" ]; then
102+
COMMAND="$COMMAND --title \"$TITLE\""
103+
fi
104+
105+
if [ "$ISSUE_NUMBER" != "" ]; then
106+
COMMAND="$COMMAND --issue-number \"$ISSUE_NUMBER\""
107+
fi
108+
109+
if [ "$VERBOSE" = "true" ]; then
110+
COMMAND="$COMMAND --verbose"
111+
fi
112+
113+
if [ "$DRY_RUN" = "true" ]; then
114+
echo "📋 DRY RUN MODE - Command that would be executed:"
115+
echo "$COMMAND"
116+
echo ""
117+
echo "ℹ️ In dry run mode, dashboard content would be generated but no issue would be created/updated"
118+
119+
# Run scan to show what would be included
120+
echo "🔍 Scanning for dependencies that would be included:"
121+
if [ "$VERBOSE" = "true" ]; then
122+
bun buddy scan --verbose
123+
else
124+
bun buddy scan
125+
fi
126+
else
127+
echo "🚀 Executing dashboard update:"
128+
echo "$COMMAND"
129+
echo ""
130+
eval "$COMMAND"
131+
fi
132+
133+
env:
134+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
135+
136+
- name: Dry run notification
137+
if: ${{ github.event.inputs.dry_run == 'true' }}
138+
run: |
139+
echo "ℹ️ **Dry Run Mode** - Dashboard preview completed"
140+
echo "To actually update the dashboard, run this workflow again with 'Dry run' set to false"
141+
142+
- name: Check dashboard status
143+
if: ${{ github.event.inputs.dry_run != 'true' }}
144+
run: |
145+
echo "✅ Dashboard update completed"
146+
echo "🔗 Check your repository issues for the updated dependency dashboard"
147+
148+
# Try to find and link to the dashboard issue
149+
echo "📊 Looking for dependency dashboard issue..."
150+
151+
# Use GitHub CLI to find the dashboard issue
152+
if command -v gh &> /dev/null; then
153+
DASHBOARD_URL=$(gh issue list --label "dashboard,dependencies" --state open --limit 1 --json url --jq '.[0].url' 2>/dev/null || echo "")
154+
if [ "$DASHBOARD_URL" != "null" ] && [ "$DASHBOARD_URL" != "" ]; then
155+
echo "🎯 Dashboard found: $DASHBOARD_URL"
156+
else
157+
echo "🔍 Dashboard issue not found via CLI, check issues manually"
158+
fi
159+
else
160+
echo "💡 Check your issues tab for the dependency dashboard"
161+
fi
162+
163+
- name: Create dashboard summary
164+
if: always()
165+
run: |
166+
echo "## 📊 Dependency Dashboard Summary" >> $GITHUB_STEP_SUMMARY
167+
echo "" >> $GITHUB_STEP_SUMMARY
168+
echo "- **Pin Dashboard**: ${{ github.event.inputs.pin || 'true' }}" >> $GITHUB_STEP_SUMMARY
169+
echo "- **Custom Title**: ${{ github.event.inputs.title || 'default' }}" >> $GITHUB_STEP_SUMMARY
170+
echo "- **Issue Number**: ${{ github.event.inputs.issue_number || 'auto-detect' }}" >> $GITHUB_STEP_SUMMARY
171+
echo "- **Triggered by**: ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY
172+
echo "- **Dry run**: ${{ github.event.inputs.dry_run || 'false' }}" >> $GITHUB_STEP_SUMMARY
173+
echo "- **Verbose**: ${{ github.event.inputs.verbose || 'true' }}" >> $GITHUB_STEP_SUMMARY
174+
echo "- **Time**: $(date)" >> $GITHUB_STEP_SUMMARY
175+
echo "" >> $GITHUB_STEP_SUMMARY
176+
177+
if [ "${{ github.event_name }}" = "schedule" ]; then
178+
echo "⏰ **Scheduled Update**: This was triggered automatically" >> $GITHUB_STEP_SUMMARY
179+
echo "🔄 **Schedule**: Monday, Wednesday, Friday at 9 AM UTC" >> $GITHUB_STEP_SUMMARY
180+
echo "💡 **Tip**: Use 'Actions' tab to manually trigger with custom settings" >> $GITHUB_STEP_SUMMARY
181+
else
182+
echo "🖱️ **Manual Trigger**: This was triggered manually from the Actions tab" >> $GITHUB_STEP_SUMMARY
183+
echo "⏰ **Auto-Schedule**: This workflow also runs automatically on schedule" >> $GITHUB_STEP_SUMMARY
184+
fi
185+
186+
echo "" >> $GITHUB_STEP_SUMMARY
187+
188+
if [ "${{ github.event.inputs.dry_run }}" = "true" ]; then
189+
echo "📋 **Dry Run**: No changes were made. Dashboard content was previewed only." >> $GITHUB_STEP_SUMMARY
190+
else
191+
echo "✅ **Dashboard Updated**: Check your repository issues for the updated dependency dashboard." >> $GITHUB_STEP_SUMMARY
192+
fi
193+
194+
echo "" >> $GITHUB_STEP_SUMMARY
195+
echo "📊 View detailed logs above for dashboard update results." >> $GITHUB_STEP_SUMMARY

README.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ A modern, fast alternative to Dependabot and Renovate built for the JavaScript a
2020
- 🎯 **Smart Updates**: Configurable update strategies _(major, minor, patch, all)_
2121
- 📦 **Multi-Package Manager**: Supports Bun, npm, yarn, pnpm, pkgx, and Launchpad dependency files
2222
-**GitHub Actions**: Automatically updates workflow dependencies (`actions/checkout@v4`, etc.)
23+
- 📊 **Dependency Dashboard**: Single GitHub issue with overview of all dependencies and open PRs
2324
- 🔍 **Intelligent Scanning**: Uses `bun outdated` and GitHub releases for accurate dependency detection
2425
- 📋 **Flexible Grouping**: Group related packages for cleaner PRs
2526
- 🎨 **Rich PR Format**: Three separate tables (npm, Launchpad/pkgx, GitHub Actions) with detailed metadata
@@ -69,6 +70,9 @@ buddy scan
6970
# Scan with verbose output
7071
buddy scan --verbose
7172

73+
# Create or update dependency dashboard
74+
buddy dashboard --pin
75+
7276
# Check specific packages
7377
buddy scan --packages "react,typescript,@types/node"
7478

@@ -138,6 +142,17 @@ const config: BuddyBotConfig = {
138142
strategy: 'squash', // 'merge', 'squash', or 'rebase'
139143
conditions: ['patch-only'] // Only auto-merge patch updates
140144
}
145+
},
146+
147+
// Dependency dashboard settings
148+
dashboard: {
149+
enabled: true,
150+
title: 'Dependency Dashboard',
151+
pin: true,
152+
labels: ['dependencies', 'dashboard'],
153+
assignees: ['maintainer1'],
154+
showOpenPRs: true,
155+
showDetectedDependencies: true
141156
}
142157
}
143158

@@ -167,6 +182,81 @@ const updates = await buddy.checkPackages(['react', 'typescript'])
167182
if (scanResult.updates.length > 0) {
168183
await buddy.createPullRequests(scanResult)
169184
}
185+
186+
// Create or update dependency dashboard
187+
const dashboardIssue = await buddy.createOrUpdateDashboard()
188+
console.log(`Dashboard updated: ${dashboardIssue.url}`)
189+
```
190+
191+
## Dependency Dashboard
192+
193+
The dependency dashboard provides a centralized view of all your repository's dependencies and open pull requests in a single GitHub issue. Similar to Renovate's dependency dashboard, it gives you complete visibility into your dependency management.
194+
195+
### Key Features
196+
197+
- **📊 Single Overview**: All dependencies and PRs in one place
198+
- **🔄 Interactive Controls**: Force retry/rebase PRs by checking boxes
199+
- **📌 Pinnable Issue**: Keep dashboard at the top of your issues
200+
- **🏷️ Smart Categorization**: Organized by npm, GitHub Actions, and dependency files
201+
- **⚡ Auto-Updates**: Refreshes when dependencies change
202+
203+
### Quick Start
204+
205+
```bash
206+
# Create basic dashboard
207+
buddy-bot dashboard
208+
209+
# Create pinned dashboard with custom title
210+
buddy-bot dashboard --pin --title "My Dependencies"
211+
```
212+
213+
### Automated Dashboard Updates
214+
215+
Buddy Bot includes a pre-built GitHub workflow (`.github/workflows/buddy-bot-dashboard.yml`) that automatically updates your dependency dashboard:
216+
217+
- **📅 Scheduled**: Runs Monday, Wednesday, Friday at 9 AM UTC
218+
- **🖱️ Manual**: Trigger from Actions tab with custom options
219+
- **📌 Auto-Pin**: Keeps dashboard pinned by default
220+
- **🔍 Dry-Run**: Preview mode available
221+
222+
### Example Dashboard Output
223+
224+
The dashboard automatically organizes your dependencies and shows:
225+
226+
```markdown
227+
## Open
228+
229+
The following updates have all been created. To force a retry/rebase of any, click on a checkbox below.
230+
231+
- [ ] <!-- rebase-branch=buddy-bot/update-react-18 -->[chore(deps): update react to v18](../pull/123) (`react`)
232+
- [ ] <!-- rebase-branch=buddy-bot/update-types -->[chore(deps): update @types/node](../pull/124) (`@types/node`)
233+
234+
## Detected dependencies
235+
236+
<details><summary>npm</summary>
237+
<blockquote>
238+
239+
<details><summary>package.json</summary>
240+
241+
- `react ^17.0.0`
242+
- `typescript ^4.9.0`
243+
- `@types/node ^18.0.0`
244+
245+
</details>
246+
</blockquote>
247+
</details>
248+
249+
<details><summary>github-actions</summary>
250+
<blockquote>
251+
252+
<details><summary>.github/workflows/ci.yml</summary>
253+
254+
- `actions/checkout v3`
255+
- `oven-sh/setup-bun v1`
256+
257+
</details>
258+
</blockquote>
259+
</details>
170260
```
171261

172262
## How It Works

bin/cli.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ cli.usage(`[command] [options]
1818
DEPENDENCY MANAGEMENT:
1919
setup 🚀 Interactive setup for automated updates (recommended)
2020
scan 🔍 Scan for dependency updates
21+
dashboard 📊 Create or update dependency dashboard issue
2122
update ⬆️ Update dependencies and create PRs
2223
rebase 🔄 Rebase/retry a pull request with latest updates
2324
check-rebase 🔍 Auto-detect and rebase PRs with checked rebase box
@@ -39,6 +40,7 @@ CONFIGURATION & SETUP:
3940
Examples:
4041
buddy-bot setup # Interactive setup
4142
buddy-bot scan --verbose # Scan for updates
43+
buddy-bot dashboard --pin # Create pinned dashboard
4244
buddy-bot rebase 17 # Rebase PR #17
4345
buddy-bot check-rebase # Auto-rebase checked PRs
4446
buddy-bot info react # Get package info
@@ -297,6 +299,54 @@ cli
297299
}
298300
})
299301

302+
cli
303+
.command('dashboard', 'Create or update dependency dashboard issue')
304+
.option('--verbose, -v', 'Enable verbose logging')
305+
.option('--pin', 'Pin the dashboard issue')
306+
.option('--title <title>', 'Custom dashboard title')
307+
.option('--issue-number <number>', 'Update specific issue number')
308+
.example('buddy-bot dashboard')
309+
.example('buddy-bot dashboard --pin')
310+
.example('buddy-bot dashboard --title "My Dependencies"')
311+
.example('buddy-bot dashboard --issue-number 42')
312+
.action(async (options: CLIOptions & { pin?: boolean, title?: string, issueNumber?: string }) => {
313+
const logger = options.verbose ? Logger.verbose() : Logger.quiet()
314+
315+
try {
316+
logger.info('Creating or updating dependency dashboard...')
317+
318+
// Check if repository is configured
319+
if (!config.repository) {
320+
logger.error('❌ Repository configuration required for dashboard')
321+
logger.info('Configure repository.provider, repository.owner, repository.name in buddy-bot.config.ts')
322+
process.exit(1)
323+
}
324+
325+
// Override config with CLI options
326+
const finalConfig: BuddyBotConfig = {
327+
...config,
328+
verbose: options.verbose ?? config.verbose,
329+
dashboard: {
330+
...config.dashboard,
331+
enabled: true,
332+
pin: options.pin ?? config.dashboard?.pin,
333+
title: options.title ?? config.dashboard?.title,
334+
issueNumber: options.issueNumber ? Number.parseInt(options.issueNumber) : config.dashboard?.issueNumber,
335+
},
336+
}
337+
338+
const buddy = new Buddy(finalConfig)
339+
const issue = await buddy.createOrUpdateDashboard()
340+
341+
logger.success(`✅ Dashboard updated: ${issue.url}`)
342+
logger.info(`📊 Issue #${issue.number}: ${issue.title}`)
343+
}
344+
catch (error) {
345+
logger.error('Dashboard creation failed:', error)
346+
process.exit(1)
347+
}
348+
})
349+
300350
cli
301351
.command('update', 'Update dependencies and create PRs')
302352
.option('--verbose, -v', 'Enable verbose logging')

0 commit comments

Comments
 (0)