From d392b56ee3d8bc1cfe656f64c87f7bb41c6647f9 Mon Sep 17 00:00:00 2001 From: Aviv Keller Date: Sun, 13 Jul 2025 16:55:43 -0400 Subject: [PATCH 1/6] fix(icr): fix remaining issues with ICR script --- .github/workflows/inactive-collaborator-report.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/inactive-collaborator-report.yml b/.github/workflows/inactive-collaborator-report.yml index a28bc44..9dd8f87 100644 --- a/.github/workflows/inactive-collaborator-report.yml +++ b/.github/workflows/inactive-collaborator-report.yml @@ -28,5 +28,5 @@ jobs: uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 with: script: | - const { default: report } = await import("${{github.workspace}}/.github/scripts/inactive-collaborators-report.mjs"); + const { default: report } = await import("${{github.workspace}}/.github/scripts/inactive-collaborator-report.mjs"); report(github, context); From 026379a1c23c743d47b478b1778313cc8a0d87c1 Mon Sep 17 00:00:00 2001 From: Aviv Keller Date: Sun, 13 Jul 2025 16:56:57 -0400 Subject: [PATCH 2/6] Rename inactive-collaborator-report.js to inactive-collaborator-report.mjs --- ...ve-collaborator-report.js => inactive-collaborator-report.mjs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/scripts/{inactive-collaborator-report.js => inactive-collaborator-report.mjs} (100%) diff --git a/.github/scripts/inactive-collaborator-report.js b/.github/scripts/inactive-collaborator-report.mjs similarity index 100% rename from .github/scripts/inactive-collaborator-report.js rename to .github/scripts/inactive-collaborator-report.mjs From 1df2ed06e8b3fa7a3fbb92c2ec5b489fe0d2c058 Mon Sep 17 00:00:00 2001 From: Aviv Keller Date: Sun, 13 Jul 2025 16:59:33 -0400 Subject: [PATCH 3/6] Update inactive-collaborator-report.mjs --- .github/scripts/inactive-collaborator-report.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/inactive-collaborator-report.mjs b/.github/scripts/inactive-collaborator-report.mjs index 39dc0e7..36bb61f 100644 --- a/.github/scripts/inactive-collaborator-report.mjs +++ b/.github/scripts/inactive-collaborator-report.mjs @@ -42,7 +42,7 @@ async function parseCollaborators() { const line = lines[i]; if (line.startsWith("#")) break; - const match = line.match(/^\s*-\s*\[([^\]]+)\]/); + const match = line.match(/^\s*-\s*@\[([^\]]+)\]/); if (match) collaborators.push(match[1]); } From c58cb0ffe3e83068a771b25718cc3b36745a2b06 Mon Sep 17 00:00:00 2001 From: Aviv Keller Date: Sun, 13 Jul 2025 17:02:23 -0400 Subject: [PATCH 4/6] add debug logging --- .../scripts/inactive-collaborator-report.mjs | 65 ++++++++++++++++--- 1 file changed, 57 insertions(+), 8 deletions(-) diff --git a/.github/scripts/inactive-collaborator-report.mjs b/.github/scripts/inactive-collaborator-report.mjs index 36bb61f..6d3ae52 100644 --- a/.github/scripts/inactive-collaborator-report.mjs +++ b/.github/scripts/inactive-collaborator-report.mjs @@ -12,11 +12,14 @@ const CONFIG = { const getDateMonthsAgo = (months = CONFIG.INACTIVE_MONTHS) => { const date = new Date(); date.setMonth(date.getMonth() - months); - return date.toISOString().split("T")[0]; + const result = date.toISOString().split("T")[0]; + console.log(`getDateMonthsAgo(${months}): ${result}`); + return result; }; // Check if there's already an open issue async function hasOpenIssue(github, context) { + console.log("Checking for existing open issues..."); const { owner, repo } = context.repo; const { data: issues } = await github.rest.issues.listForRepo({ owner, @@ -26,34 +29,52 @@ async function hasOpenIssue(github, context) { per_page: 1, }); - return issues.length > 0; + const hasIssue = issues.length > 0; + console.log(`Found ${issues.length} open issues with label "${CONFIG.ISSUE_LABELS[1]}"`); + return hasIssue; } // Parse collaborator usernames from governance file async function parseCollaborators() { + console.log(`Reading collaborators from ${CONFIG.FILE}...`); const content = await readFile(CONFIG.FILE, "utf8"); const lines = content.split("\n"); const collaborators = []; const startIndex = lines.findIndex((l) => l.startsWith(CONFIG.HEADER)) + 1; - if (startIndex <= 0) return collaborators; + console.log(`Header found at line ${startIndex - 1}, starting parse at line ${startIndex}`); + + if (startIndex <= 0) { + console.log("Header not found, returning empty collaborators array"); + return collaborators; + } for (let i = startIndex; i < lines.length; i++) { const line = lines[i]; - if (line.startsWith("#")) break; + if (line.startsWith("#")) { + console.log(`Reached next section at line ${i}, stopping parse`); + break; + } const match = line.match(/^\s*-\s*@\[([^\]]+)\]/); - if (match) collaborators.push(match[1]); + if (match) { + collaborators.push(match[1]); + console.log(`Found collaborator: ${match[1]}`); + } } + console.log(`Total collaborators found: ${collaborators.length}`); return collaborators; } // Check if users have been active since cutoff date async function getInactiveUsers(github, usernames, repo, cutoffDate) { + console.log(`Checking activity for ${usernames.length} users since ${cutoffDate}...`); const inactiveUsers = []; for (const username of usernames) { + console.log(`Checking activity for ${username}...`); + // Check commits const { data: commits } = await github.rest.search.commits({ q: `author:${username} repo:${repo} committer-date:>=${cutoffDate}`, @@ -66,21 +87,32 @@ async function getInactiveUsers(github, usernames, repo, cutoffDate) { per_page: 1, }); + console.log(`${username}: ${commits.total_count} commits, ${issues.total_count} issues/PRs`); + // User is inactive if they have no commits AND no issues/PRs if (commits.total_count === 0 && issues.total_count === 0) { inactiveUsers.push(username); + console.log(`${username} is inactive`); + } else { + console.log(`${username} is active`); } } + console.log(`Total inactive users: ${inactiveUsers.length}`); return inactiveUsers; } // Generate report for inactive members function formatReport(inactiveMembers, cutoffDate) { - if (!inactiveMembers.length) return null; + console.log(`Formatting report for ${inactiveMembers.length} inactive members...`); + + if (!inactiveMembers.length) { + console.log("No inactive members found, skipping report generation"); + return null; + } const today = getDateMonthsAgo(0); - return `# Inactive Collaborators Report + const report = `# Inactive Collaborators Report Last updated: ${today} Checking for inactivity since: ${cutoffDate} @@ -94,11 +126,18 @@ ${inactiveMembers.map((m) => `| @${m} |`).join("\n")} ## What happens next? @nodejs/nodejs-website should review this list and contact inactive collaborators to confirm their continued interest in participating in the project.`; + + console.log("Report generated successfully"); + return report; } async function createIssue(github, context, report) { - if (!report) return; + if (!report) { + console.log("No report to create issue from"); + return; + } + console.log("Creating new issue..."); const { owner, repo } = context.repo; await github.rest.issues.create({ owner, @@ -107,17 +146,26 @@ async function createIssue(github, context, report) { body: report, labels: CONFIG.ISSUE_LABELS, }); + console.log("Issue created successfully"); } export default async function (github, context) { + console.log("Starting inactive collaborator check..."); + // Check for existing open issue first - exit early if one exists if (await hasOpenIssue(github, context)) { + console.log("Open issue already exists, exiting early"); return; } const cutoffDate = getDateMonthsAgo(); const collaborators = await parseCollaborators(); + if (collaborators.length === 0) { + console.log("No collaborators found, exiting"); + return; + } + const inactiveMembers = await getInactiveUsers( github, collaborators, @@ -127,4 +175,5 @@ export default async function (github, context) { const report = formatReport(inactiveMembers, cutoffDate); await createIssue(github, context, report); + console.log("Inactive collaborator check completed"); } From 2e27ea01bda2113703ee57d4bc471acc4c22405b Mon Sep 17 00:00:00 2001 From: Aviv Keller Date: Sun, 13 Jul 2025 17:04:00 -0400 Subject: [PATCH 5/6] Update inactive-collaborator-report.mjs --- .github/scripts/inactive-collaborator-report.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/scripts/inactive-collaborator-report.mjs b/.github/scripts/inactive-collaborator-report.mjs index 6d3ae52..ff6e3c8 100644 --- a/.github/scripts/inactive-collaborator-report.mjs +++ b/.github/scripts/inactive-collaborator-report.mjs @@ -56,9 +56,9 @@ async function parseCollaborators() { break; } - const match = line.match(/^\s*-\s*@\[([^\]]+)\]/); + const match = line.match(/^\s*-\s*\[([^\]]+)\]/); if (match) { - collaborators.push(match[1]); + collaborators.push(match[1].slice(1)); console.log(`Found collaborator: ${match[1]}`); } } From 26bafa800d80e62e03d11cc2b6ffbe7570dfeebb Mon Sep 17 00:00:00 2001 From: Aviv Keller Date: Sun, 13 Jul 2025 17:07:38 -0400 Subject: [PATCH 6/6] Use `commenter` --- .github/scripts/inactive-collaborator-report.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/inactive-collaborator-report.mjs b/.github/scripts/inactive-collaborator-report.mjs index ff6e3c8..9b32a8b 100644 --- a/.github/scripts/inactive-collaborator-report.mjs +++ b/.github/scripts/inactive-collaborator-report.mjs @@ -83,7 +83,7 @@ async function getInactiveUsers(github, usernames, repo, cutoffDate) { // Check issues and PRs const { data: issues } = await github.rest.search.issuesAndPullRequests({ - q: `involves:${username} repo:${repo} updated:>=${cutoffDate}`, + q: `commenter:${username} repo:${repo} updated:>=${cutoffDate}`, per_page: 1, });