diff --git a/create-node-meeting-artifacts.mjs b/create-node-meeting-artifacts.mjs index c88d956..acdc427 100644 --- a/create-node-meeting-artifacts.mjs +++ b/create-node-meeting-artifacts.mjs @@ -51,10 +51,7 @@ const gitHubAgendaIssues = await github.getAgendaIssues( ); // Step 10: Parse meeting agenda from GitHub issues -const meetingAgenda = meetings.generateMeetingAgenda( - gitHubAgendaIssues, - meetingConfig -); +const meetingAgenda = meetings.generateMeetingAgenda(gitHubAgendaIssues); // Step 11: Create HackMD document with meeting notes const hackmdNote = await hackmd.createMeetingNotesDocument( diff --git a/package-lock.json b/package-lock.json index 3fc3ab9..e9ef128 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "dedent": "^1.6.0" }, "bin": { - "create-meeting": "bin/create-meeting" + "create-meeting": "create-node-meeting-artifacts.mjs" }, "devDependencies": { "@eslint/js": "^9.33.0", diff --git a/src/github.mjs b/src/github.mjs index b075c5d..ec828b9 100644 --- a/src/github.mjs +++ b/src/github.mjs @@ -42,41 +42,39 @@ export const createGitHubIssue = async ( return response.data; }; +/** + * Sorts issues by repository + * @param {Array} issues The issues to sort + * @returns {Promise<{ [key: string]: Array }>} Sorted issues + */ +export const sortIssuesByRepo = issues => + issues.reduce((obj, issue) => { + (obj[issue.repository_url.split('/').slice(-2).join('/')] ||= []).push( + issue + ); + return obj; + }, {}); + /** * Fetches GitHub issues from all repositories in an organization with a specific label * @param {import('@octokit/rest').Octokit} githubClient - Authenticated GitHub API client * @param {import('./types.d.ts').AppConfig} config - Application configuration * @param {import('./types.d.ts').MeetingConfig} meetingConfig - Meeting configuration - * @returns {Promise<{ repoName: string, issues: Array }> } Formatted markdown string of issues + * @returns {Promise<{ [key: string]: Array }>} Meeting agenda */ export const getAgendaIssues = async ( - { paginate, rest }, + githubClient, { meetingGroup }, { properties } ) => { const githubOrg = properties.USER ?? DEFAULT_CONFIG.githubOrg; const agendaTag = properties.AGENDA_TAG ?? `${meetingGroup}-agenda`; - // Get all public repositories in the organization - const repos = await paginate(rest.repos.listForOrg, { - org: githubOrg, - type: 'public', - per_page: 100, - }); - - // Fetch issues and PRs from all repositories concurrently - const issuePromises = repos.map(async repo => { - const items = await paginate(rest.issues.listForRepo, { - owner: githubOrg, - repo: repo.name, - labels: agendaTag, - state: 'open', - per_page: 100, - }); - - // Include both issues and PRs for agenda items - return { repoName: repo.name, issues: items }; + // Get all issues/PRs in the organization + const issues = await githubClient.paginate('GET /search/issues', { + q: `is:open label:${agendaTag} org:${githubOrg}`, + advanced_search: true, }); - return Promise.all(issuePromises); + return sortIssuesByRepo(issues); }; diff --git a/src/meeting.mjs b/src/meeting.mjs index 60a401f..c56f042 100644 --- a/src/meeting.mjs +++ b/src/meeting.mjs @@ -56,21 +56,16 @@ export const generateMeetingTitle = (config, meetingConfig, meetingDate) => { /** * Generates the meeting agenda from the list of agenda issues - * @param {Array<{ repoName: string, issues: Array }>} agendaIssues - List of agenda issues - * @param {import('./types.d.ts').MeetingConfig} meetingConfig - Meeting configuration + * @param {Array<{ [key: string]: Array }>} agendaIssues - List of agenda issues * @returns {Promise} Formatted meeting agenda */ -export const generateMeetingAgenda = (agendaIssues, meetingConfig) => { - const props = meetingConfig.properties; - - const githubOrg = props.USER ?? DEFAULT_CONFIG.githubOrg; - +export const generateMeetingAgenda = agendaIssues => { // Format issues as markdown let agendaMarkdown = ''; - agendaIssues.forEach(({ repoName, issues }) => { + Object.entries(agendaIssues).forEach(([repoName, issues]) => { if (issues.length > 0) { - agendaMarkdown += `### ${githubOrg}/${repoName}\n\n`; + agendaMarkdown += `### ${repoName}\n\n`; issues.forEach(issue => { // Escape markdown characters in title