improve: implement CodeRabbit review suggestions
- Consolidate fs imports into single import statement - Harden table parsing with better column detection and filtering - Improve numeric extraction to handle commas and edge cases - Add comprehensive error handling for file writes - Add stdout logging for better debugging and transparency - Add file existence logging with emojis for clarity
This commit is contained in:
158
.github/scripts/parse-metrics.mjs
vendored
158
.github/scripts/parse-metrics.mjs
vendored
@@ -1,72 +1,124 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { readFileSync, existsSync } from 'fs';
|
||||
import { writeFileSync } from 'fs';
|
||||
import { readFileSync, existsSync, writeFileSync } from 'fs';
|
||||
|
||||
function parseMetricsTable(content, metricName) {
|
||||
const lines = content.split('\n');
|
||||
const lines = content.split('\n');
|
||||
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i].trim();
|
||||
if (line.includes(metricName)) {
|
||||
// Split by | and get the value column (usually index 2)
|
||||
const columns = line.split('|').map(col => col.trim());
|
||||
if (columns.length >= 3) {
|
||||
return columns[2] || 'N/A';
|
||||
}
|
||||
}
|
||||
}
|
||||
return 'N/A';
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i].trim();
|
||||
if (line.includes(metricName)) {
|
||||
// Split by | and get the value column, filtering empty strings
|
||||
const columns = line
|
||||
.split('|')
|
||||
.map((col) => col.trim())
|
||||
.filter((col) => col.length > 0);
|
||||
// Look for the value in columns 1-3 (accounting for different table formats)
|
||||
for (let j = 1; j < Math.min(columns.length, 4); j++) {
|
||||
const value = columns[j];
|
||||
if (value && value !== '---' && value !== metricName) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 'N/A';
|
||||
}
|
||||
|
||||
function parseCountMetric(content, metricName) {
|
||||
const result = parseMetricsTable(content, metricName);
|
||||
// Try to extract just the number if it's a valid number
|
||||
const number = parseInt(result);
|
||||
return isNaN(number) ? 0 : number;
|
||||
const result = parseMetricsTable(content, metricName);
|
||||
// Extract number from string, handling commas and spaces
|
||||
const numberMatch = result.toString().match(/[\d,]+/);
|
||||
if (numberMatch) {
|
||||
const number = parseInt(numberMatch[0].replace(/,/g, ''));
|
||||
return isNaN(number) ? 0 : number;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function main() {
|
||||
const metrics = {
|
||||
issues_created: 0,
|
||||
issues_closed: 0,
|
||||
prs_created: 0,
|
||||
prs_merged: 0,
|
||||
issue_avg_first_response: 'N/A',
|
||||
issue_avg_time_to_close: 'N/A',
|
||||
pr_avg_first_response: 'N/A',
|
||||
pr_avg_merge_time: 'N/A'
|
||||
};
|
||||
const metrics = {
|
||||
issues_created: 0,
|
||||
issues_closed: 0,
|
||||
prs_created: 0,
|
||||
prs_merged: 0,
|
||||
issue_avg_first_response: 'N/A',
|
||||
issue_avg_time_to_close: 'N/A',
|
||||
pr_avg_first_response: 'N/A',
|
||||
pr_avg_merge_time: 'N/A'
|
||||
};
|
||||
|
||||
// Parse issue metrics
|
||||
if (existsSync('issue_metrics.md')) {
|
||||
const issueContent = readFileSync('issue_metrics.md', 'utf8');
|
||||
// Parse issue metrics
|
||||
if (existsSync('issue_metrics.md')) {
|
||||
console.log('📄 Found issue_metrics.md, parsing...');
|
||||
const issueContent = readFileSync('issue_metrics.md', 'utf8');
|
||||
|
||||
metrics.issues_created = parseCountMetric(issueContent, 'Total number of items created');
|
||||
metrics.issues_closed = parseCountMetric(issueContent, 'Number of items closed');
|
||||
metrics.issue_avg_first_response = parseMetricsTable(issueContent, 'Time to first response');
|
||||
metrics.issue_avg_time_to_close = parseMetricsTable(issueContent, 'Time to close');
|
||||
}
|
||||
metrics.issues_created = parseCountMetric(
|
||||
issueContent,
|
||||
'Total number of items created'
|
||||
);
|
||||
metrics.issues_closed = parseCountMetric(
|
||||
issueContent,
|
||||
'Number of items closed'
|
||||
);
|
||||
metrics.issue_avg_first_response = parseMetricsTable(
|
||||
issueContent,
|
||||
'Time to first response'
|
||||
);
|
||||
metrics.issue_avg_time_to_close = parseMetricsTable(
|
||||
issueContent,
|
||||
'Time to close'
|
||||
);
|
||||
} else {
|
||||
console.log('⚠️ No issue_metrics.md found');
|
||||
}
|
||||
|
||||
// Parse PR metrics
|
||||
if (existsSync('pr_metrics.md')) {
|
||||
const prContent = readFileSync('pr_metrics.md', 'utf8');
|
||||
// Parse PR metrics
|
||||
if (existsSync('pr_metrics.md')) {
|
||||
console.log('📄 Found pr_metrics.md, parsing...');
|
||||
const prContent = readFileSync('pr_metrics.md', 'utf8');
|
||||
|
||||
metrics.prs_created = parseCountMetric(prContent, 'Total number of items created');
|
||||
metrics.prs_merged = parseCountMetric(prContent, 'Number of items closed');
|
||||
metrics.pr_avg_first_response = parseMetricsTable(prContent, 'Time to first response');
|
||||
metrics.pr_avg_merge_time = parseMetricsTable(prContent, 'Time to close');
|
||||
}
|
||||
metrics.prs_created = parseCountMetric(
|
||||
prContent,
|
||||
'Total number of items created'
|
||||
);
|
||||
metrics.prs_merged = parseCountMetric(prContent, 'Number of items closed');
|
||||
metrics.pr_avg_first_response = parseMetricsTable(
|
||||
prContent,
|
||||
'Time to first response'
|
||||
);
|
||||
metrics.pr_avg_merge_time = parseMetricsTable(prContent, 'Time to close');
|
||||
} else {
|
||||
console.log('⚠️ No pr_metrics.md found');
|
||||
}
|
||||
|
||||
// Output for GitHub Actions
|
||||
const output = Object.entries(metrics)
|
||||
.map(([key, value]) => `${key}=${value}`)
|
||||
.join('\n');
|
||||
// Output for GitHub Actions
|
||||
const output = Object.entries(metrics)
|
||||
.map(([key, value]) => `${key}=${value}`)
|
||||
.join('\n');
|
||||
|
||||
// Write to GITHUB_OUTPUT if in GitHub Actions
|
||||
if (process.env.GITHUB_OUTPUT) {
|
||||
writeFileSync(process.env.GITHUB_OUTPUT, output + '\n', { flag: 'a' });
|
||||
}
|
||||
// Always output to stdout for debugging
|
||||
console.log('\n=== FINAL METRICS ===');
|
||||
Object.entries(metrics).forEach(([key, value]) => {
|
||||
console.log(`${key}: ${value}`);
|
||||
});
|
||||
|
||||
// Write to GITHUB_OUTPUT if in GitHub Actions
|
||||
if (process.env.GITHUB_OUTPUT) {
|
||||
try {
|
||||
writeFileSync(process.env.GITHUB_OUTPUT, output + '\n', { flag: 'a' });
|
||||
console.log(
|
||||
`\nSuccessfully wrote metrics to ${process.env.GITHUB_OUTPUT}`
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(`Failed to write to GITHUB_OUTPUT: ${error.message}`);
|
||||
process.exit(1);
|
||||
}
|
||||
} else {
|
||||
console.log(
|
||||
'\nNo GITHUB_OUTPUT environment variable found, skipping file write'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
main();
|
||||
|
||||
Reference in New Issue
Block a user