-
-
Notifications
You must be signed in to change notification settings - Fork 44
Expand file tree
/
Copy pathgithub.mjs
More file actions
98 lines (85 loc) · 3.16 KB
/
github.mjs
File metadata and controls
98 lines (85 loc) · 3.16 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
92
93
94
95
96
97
98
import { Octokit } from '@octokit/rest';
import { DEFAULT_CONFIG } from './constants.mjs';
/**
* Creates a GitHub API client
* @param {import('./types.d.ts').AppConfig} config - Application configuration
* @returns {import('@octokit/rest').Octokit} Configured GitHub API client
*/
export const createGitHubClient = ({ githubToken: auth, verbose }) =>
new Octokit({ auth, log: verbose ? console : undefined });
/**
* Creates GitHub issue with meeting information and Google Doc link
* @param {import('@octokit/rest').Octokit} githubClient - Authenticated GitHub API client
* @param {import('./types.d.ts').MeetingConfig} meetingConfig - Meeting configuration object
* @param {string} title - Issue title
* @param {string} content - Issue content
* @returns {Promise<GitHubIssue>} Created issue data
*/
export const createGitHubIssue = async (
{ rest },
{ properties },
title,
content
) => {
const githubOrg = properties.USER ?? DEFAULT_CONFIG.githubOrg;
const issueLabel = properties.ISSUE_LABEL
? [properties.ISSUE_LABEL]
: undefined;
// Create the GitHub issue with meeting information
const response = await rest.issues.create({
owner: githubOrg,
repo: properties.REPO,
title,
body: content,
labels: issueLabel,
});
return response.data;
};
/**
* Sorts issues by repository
* @param {Array<GitHubIssue>} issues The issues to sort
* @returns {Promise<{ [key: string]: Array<GitHubIssue> }>} Sorted issues
*/
export const sortIssuesByRepo = issues =>
issues.reduce((obj, issue) => {
(obj[issue.repository_url.split('/').slice(-2).join('/')] ||= []).push(
issue
);
return obj;
}, {});
/**
* Fetches GitHub issue from a repo with a given title
* @param {import('@octokit/rest').Octokit} githubClient - Authenticated GitHub API client
* @param {string} title - The title to find
* @param {import('./types.d.ts').MeetingConfig} meetingConfig - Meeting configuration
*/
export const findIssueByTitle = async (githubClient, title, { properties }) => {
const githubOrg = properties.USER ?? DEFAULT_CONFIG.githubOrg;
const issues = await githubClient.request('GET /search/issues', {
q: `in:title repo:"${githubOrg}/${properties.REPO}" "${title}"`,
advanced_search: true,
per_page: 1,
});
return issues.data.items[0];
};
/**
* 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<{ [key: string]: Array<GitHubIssue> }>} Meeting agenda
*/
export const getAgendaIssues = async (
githubClient,
{ meetingGroup },
{ properties }
) => {
const githubOrg = properties.USER ?? DEFAULT_CONFIG.githubOrg;
const agendaTag = properties.AGENDA_TAG ?? `${meetingGroup}-agenda`;
// 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 sortIssuesByRepo(issues);
};