From c86158c9115ff6b803376df0620f7411aba423c4 Mon Sep 17 00:00:00 2001 From: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com> Date: Mon, 22 Sep 2025 15:21:14 +0200 Subject: [PATCH] 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 --- .github/scripts/parse-metrics.mjs | 158 ++++++++++++++++++++---------- 1 file changed, 105 insertions(+), 53 deletions(-) diff --git a/.github/scripts/parse-metrics.mjs b/.github/scripts/parse-metrics.mjs index f0353ea4..dd95375b 100644 --- a/.github/scripts/parse-metrics.mjs +++ b/.github/scripts/parse-metrics.mjs @@ -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(); \ No newline at end of file +main();