Skip to content

Commit 04e4000

Browse files
committed
chore: improve dashboard creation & maintenance
chore: wip
1 parent fc63a14 commit 04e4000

File tree

3 files changed

+128
-14
lines changed

3 files changed

+128
-14
lines changed

.github/workflows/buddy-bot.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,31 @@ jobs:
369369
echo "Repository: ${{ github.repository }}"
370370
echo "Branch: ${{ github.ref_name }}"
371371
372+
- name: Pre-flight dashboard check
373+
if: ${{ github.event.inputs.dry_run != 'true' }}
374+
run: |
375+
echo "🔍 Pre-flight check: Looking for existing dashboard issues..."
376+
377+
# Check for existing dashboard issues to prevent duplicates
378+
if command -v gh &> /dev/null; then
379+
EXISTING_DASHBOARDS=$(gh issue list --label "dashboard,dependencies" --state open --json number,title,url --jq length 2>/dev/null || echo "0")
380+
echo "Found $EXISTING_DASHBOARDS existing dashboard issue(s)"
381+
382+
if [ "$EXISTING_DASHBOARDS" -gt 1 ]; then
383+
echo "⚠️ WARNING: Multiple dashboard issues detected!"
384+
gh issue list --label "dashboard,dependencies" --state open --json number,title,url --jq '.[] | " - #\(.number): \(.title) - \(.url)"' 2>/dev/null || true
385+
echo ""
386+
echo "🔧 Buddy Bot will attempt to update the most recent one and may close duplicates"
387+
elif [ "$EXISTING_DASHBOARDS" -eq 1 ]; then
388+
DASHBOARD_INFO=$(gh issue list --label "dashboard,dependencies" --state open --json number,title,url --jq '.[0] | "#\(.number): \(.title) - \(.url)"' 2>/dev/null || echo "Found 1 dashboard")
389+
echo "✅ Found existing dashboard: $DASHBOARD_INFO"
390+
else
391+
echo "ℹ️ No existing dashboard found - a new one will be created"
392+
fi
393+
else
394+
echo "⚠️ GitHub CLI not available - cannot perform pre-flight check"
395+
fi
396+
372397
- name: Update Dependency Dashboard
373398
run: |
374399
PIN="${{ github.event.inputs.pin || 'true' }}"

src/buddy.ts

Lines changed: 78 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,17 +1141,38 @@ export class Buddy {
11411141
labels: dashboardConfig.labels || ['dependencies', 'dashboard'],
11421142
assignees: dashboardConfig.assignees,
11431143
})
1144+
1145+
this.logger.success(`✅ Successfully updated dashboard issue #${issue.number}`)
11441146
}
11451147
else {
11461148
this.logger.info('Creating new dashboard issue')
11471149

1148-
// Create new dashboard
1149-
issue = await gitProvider.createIssue({
1150-
title: dashboardConfig.title || title,
1151-
body,
1152-
labels: dashboardConfig.labels || ['dependencies', 'dashboard'],
1153-
assignees: dashboardConfig.assignees,
1154-
})
1150+
// Double-check for race condition: search again right before creating
1151+
// This helps prevent duplicates if multiple workflow runs are happening simultaneously
1152+
this.logger.info('Performing final check for existing dashboards before creation...')
1153+
const raceCheckIssue = await this.findExistingDashboard(gitProvider, dashboardConfig.issueNumber)
1154+
1155+
if (raceCheckIssue) {
1156+
this.logger.info(`Race condition detected! Found existing dashboard #${raceCheckIssue.number} during final check`)
1157+
// Update the found issue instead of creating a new one
1158+
issue = await gitProvider.updateIssue(raceCheckIssue.number, {
1159+
title: dashboardConfig.title || title,
1160+
body,
1161+
labels: dashboardConfig.labels || ['dependencies', 'dashboard'],
1162+
assignees: dashboardConfig.assignees,
1163+
})
1164+
this.logger.success(`✅ Updated existing dashboard issue #${issue.number} (race condition avoided)`)
1165+
}
1166+
else {
1167+
// Safe to create new dashboard
1168+
issue = await gitProvider.createIssue({
1169+
title: dashboardConfig.title || title,
1170+
body,
1171+
labels: dashboardConfig.labels || ['dependencies', 'dashboard'],
1172+
assignees: dashboardConfig.assignees,
1173+
})
1174+
this.logger.success(`✅ Successfully created new dashboard issue #${issue.number}`)
1175+
}
11551176
}
11561177

11571178
this.logger.success(`✅ Dashboard updated: ${issue.url}`)
@@ -1227,19 +1248,62 @@ export class Buddy {
12271248
*/
12281249
private async findExistingDashboard(gitProvider: GitHubProvider, issueNumber?: number): Promise<Issue | null> {
12291250
try {
1251+
this.logger.info('Searching for existing dashboard issue...')
1252+
12301253
// If issue number is provided, try to get that specific issue
12311254
if (issueNumber) {
1255+
this.logger.info(`Looking for specific dashboard issue #${issueNumber}`)
12321256
const issues = await gitProvider.getIssues('open')
1233-
return issues.find(issue => issue.number === issueNumber) || null
1257+
const specificIssue = issues.find(issue => issue.number === issueNumber)
1258+
if (specificIssue) {
1259+
this.logger.info(`Found specified dashboard issue #${specificIssue.number}: ${specificIssue.title}`)
1260+
return specificIssue
1261+
}
1262+
else {
1263+
this.logger.warn(`Specified dashboard issue #${issueNumber} not found`)
1264+
return null
1265+
}
12341266
}
12351267

1236-
// Otherwise, search for existing dashboard by title and labels
1268+
// Get all open issues
12371269
const issues = await gitProvider.getIssues('open')
1238-
return issues.find(issue =>
1239-
(issue.title.toLowerCase().includes('dependency dashboard')
1240-
|| issue.labels.includes('dashboard'))
1241-
&& issue.labels.includes('dependencies'),
1242-
) || null
1270+
this.logger.info(`Found ${issues.length} open issues to search through`)
1271+
1272+
// Search for existing dashboard with multiple criteria for better matching
1273+
for (const issue of issues) {
1274+
const hasRequiredLabels = issue.labels.includes('dashboard') && issue.labels.includes('dependencies')
1275+
const titleMatches = issue.title.toLowerCase().includes('dependency dashboard')
1276+
const bodyHasMarker = issue.body.includes('This issue lists Buddy Bot updates and detected dependencies')
1277+
1278+
// Be more strict: require both proper labels AND (title match OR body marker)
1279+
if (hasRequiredLabels && (titleMatches || bodyHasMarker)) {
1280+
this.logger.info(`Found existing dashboard issue #${issue.number}: ${issue.title}`)
1281+
this.logger.info(` - Labels: ${issue.labels.join(', ')}`)
1282+
this.logger.info(` - Title matches: ${titleMatches}`)
1283+
this.logger.info(` - Body has marker: ${bodyHasMarker}`)
1284+
return issue
1285+
}
1286+
}
1287+
1288+
// If no exact match found, log what we found for debugging
1289+
const dashboardLabeled = issues.filter(issue => issue.labels.includes('dashboard'))
1290+
const dependenciesLabeled = issues.filter(issue => issue.labels.includes('dependencies'))
1291+
const titleMatches = issues.filter(issue => issue.title.toLowerCase().includes('dependency dashboard'))
1292+
1293+
this.logger.info(`Dashboard search results:`)
1294+
this.logger.info(` - Issues with 'dashboard' label: ${dashboardLabeled.length}`)
1295+
this.logger.info(` - Issues with 'dependencies' label: ${dependenciesLabeled.length}`)
1296+
this.logger.info(` - Issues with 'dependency dashboard' in title: ${titleMatches.length}`)
1297+
1298+
if (dashboardLabeled.length > 0) {
1299+
this.logger.info(`Issues with 'dashboard' label:`)
1300+
for (const issue of dashboardLabeled) {
1301+
this.logger.info(` - #${issue.number}: ${issue.title} (labels: ${issue.labels.join(', ')})`)
1302+
}
1303+
}
1304+
1305+
this.logger.info('No existing dashboard issue found')
1306+
return null
12431307
}
12441308
catch (error) {
12451309
this.logger.warn(`Failed to search for existing dashboard: ${error}`)

src/setup.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,6 +1453,31 @@ ${generateComposerSetupSteps()}
14531453
echo "Repository: \${{ github.repository }}"
14541454
echo "Branch: \${{ github.ref_name }}"
14551455
1456+
- name: Pre-flight dashboard check
1457+
if: \${{ github.event.inputs.dry_run != 'true' }}
1458+
run: |
1459+
echo "🔍 Pre-flight check: Looking for existing dashboard issues..."
1460+
1461+
# Check for existing dashboard issues to prevent duplicates
1462+
if command -v gh &> /dev/null; then
1463+
EXISTING_DASHBOARDS=\$(gh issue list --label "dashboard,dependencies" --state open --json number,title,url --jq length 2>/dev/null || echo "0")
1464+
echo "Found \$EXISTING_DASHBOARDS existing dashboard issue(s)"
1465+
1466+
if [ "\$EXISTING_DASHBOARDS" -gt 1 ]; then
1467+
echo "⚠️ WARNING: Multiple dashboard issues detected!"
1468+
gh issue list --label "dashboard,dependencies" --state open --json number,title,url --jq '.[] | " - #\\(.number): \\(.title) - \\(.url)"' 2>/dev/null || true
1469+
echo ""
1470+
echo "🔧 Buddy Bot will attempt to update the most recent one and may close duplicates"
1471+
elif [ "\$EXISTING_DASHBOARDS" -eq 1 ]; then
1472+
DASHBOARD_INFO=\$(gh issue list --label "dashboard,dependencies" --state open --json number,title,url --jq '.[0] | "#\\(.number): \\(.title) - \\(.url)"' 2>/dev/null || echo "Found 1 dashboard")
1473+
echo "✅ Found existing dashboard: \$DASHBOARD_INFO"
1474+
else
1475+
echo "ℹ️ No existing dashboard found - a new one will be created"
1476+
fi
1477+
else
1478+
echo "⚠️ GitHub CLI not available - cannot perform pre-flight check"
1479+
fi
1480+
14561481
- name: Update Dependency Dashboard
14571482
run: |
14581483
PIN="\${{ github.event.inputs.pin || 'true' }}"

0 commit comments

Comments
 (0)