-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathgenerate-report.js
More file actions
91 lines (80 loc) · 3.35 KB
/
Copy pathgenerate-report.js
File metadata and controls
91 lines (80 loc) · 3.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import { readFile, writeFile, mkdir } from 'fs/promises';
const data = JSON.parse(await readFile('dist/dashboard-data.json', 'utf-8'));
function formatFactors(factors) {
return Object.entries(factors)
.filter(([, v]) => v > 0)
.map(([k, v]) => `${k}: ${v}`)
.join(' | ');
}
const { stats, actionItems, organizations, missingMirrors, generatedAt } = data;
const orgCount = Object.keys(organizations).length;
// Collect stale PRs and issues
const stalePRs = [];
const staleIssues = [];
for (const [orgName, org] of Object.entries(organizations)) {
for (const repo of org.repositories) {
for (const pr of repo.pullRequests) {
if (pr.staleLevel === 'warning' || pr.staleLevel === 'critical') {
stalePRs.push({ ...pr, repo: repo.name, org: orgName });
}
}
for (const issue of repo.issues) {
if (issue.staleLevel === 'critical') {
staleIssues.push({ ...issue, repo: repo.name, org: orgName });
}
}
}
}
stalePRs.sort((a, b) => b.ageDays - a.ageDays);
staleIssues.sort((a, b) => b.ageDays - a.ageDays);
// Build report
let report = `# Mage-OS Project Health Report
Generated: ${new Date(generatedAt).toUTCString()}
## Summary
- **${stats.totalRepos}** active repositories across ${orgCount} organizations
- **${stats.totalIssues}** open issues (${stats.staleIssues} stale >90d)
- **${stats.totalPRs}** open PRs (${stats.stalePRs} stale >30d)
`;
// Action items
if (actionItems.length > 0) {
report += `\n## Top Action Items\n`;
for (const [i, item] of actionItems.slice(0, 10).entries()) {
const typeLabel = item.type === 'pr' ? 'PR' : 'Issue';
const authorStr = item.author ? ` by ${item.author}` : '';
const reviewStr = item.reviewStatus ? ` [${item.reviewStatus}]` : '';
report += `${i + 1}. **[${typeLabel}: ${item.title}](${item.url})** in \`${item.repo}\` (${item.org}) — Score: ${item.priorityScore}/100${authorStr}${reviewStr}\n`;
report += ` ${formatFactors(item.priorityFactors)}\n`;
}
}
// Stale PRs
if (stalePRs.length > 0) {
report += `\n## Stale PRs (>30 days)\n`;
report += `| PR | Repository | Age | Author | Review Status |\n`;
report += `|----|------------|-----|--------|---------------|\n`;
for (const pr of stalePRs.slice(0, 20)) {
report += `| [${pr.title}](${pr.url}) | ${pr.repo} (${pr.org}) | ${pr.ageDays}d | ${pr.author || '-'} | ${pr.reviewStatus} |\n`;
}
if (stalePRs.length > 20) {
report += `\n*...and ${stalePRs.length - 20} more stale PRs*\n`;
}
}
// Stale issues
if (staleIssues.length > 0) {
report += `\n## Stale Issues (>90 days)\n`;
report += `| Issue | Repository | Age |\n`;
report += `|-------|------------|-----|\n`;
for (const issue of staleIssues.slice(0, 20)) {
report += `| [${issue.title}](${issue.url}) | ${issue.repo} (${issue.org}) | ${issue.ageDays}d |\n`;
}
if (staleIssues.length > 20) {
report += `\n*...and ${staleIssues.length - 20} more stale issues*\n`;
}
}
// Missing mirrors
if (missingMirrors.length > 0) {
report += `\n## Missing Mirrors\n`;
report += `${missingMirrors.length} Magento repositories without Mage-OS mirrors.\n`;
}
await mkdir('dist', { recursive: true });
await writeFile('dist/report.md', report);
console.log('Report generated: dist/report.md');