-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathissues.ts
121 lines (102 loc) · 3.71 KB
/
issues.ts
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import { Octokit } from '@octokit/rest';
import { type RestEndpointMethodTypes } from '@octokit/rest';
export type Issue = RestEndpointMethodTypes['issues']['listForRepo']['response']['data'][0];
export type Label = Issue['labels'][0];
type Repo = {
owner: string;
repo: string;
};
export const odHackRegex = /od\s*hack/i;
const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });
const fetchIssuesForProject = async (owner: string, repo: string) => {
try {
const issues = await octokit.issues.listForRepo({
owner,
repo,
state: 'open',
assignee: 'none',
});
return issues.data.filter(issue => !issue.pull_request && !issue.assignee && (
// Check if the issue has the 'odhack' label
issue.labels.map(label => typeof label == 'string' ? label : label.name).some(label => odHackRegex.test(label ?? '')) ||
// Or if the issue title contains 'odhack'
odHackRegex.test(issue.title ?? '')
));
} catch (error) {
console.error('Error fetching issues:', error);
return [];
}
};
// Function to parse GitHub URL
function parseGitHubUrl(url: string): { owner: string; repo: string } | null {
try {
const parsedUrl = new URL(url);
const [owner, repo] = parsedUrl.pathname.split('/').filter(Boolean);
if (owner && repo) {
return { owner, repo };
}
} catch (e) {
console.error("Invalid URL:", e);
}
return null;
}
import { promises as fs } from 'fs';
import getRepoUrls from './onlydust';
// Function to load and process the repos.json file
async function loadAndProcessRepos(urls: string[]): Promise<Repo[]> {
try {
// Process each URL
const repos: Repo[] = urls.map(url => {
const parsed = parseGitHubUrl(url);
if (parsed) {
return parsed;
} else {
console.warn(`Invalid URL: ${url}`);
return null;
}
}).filter((repo): repo is Repo => repo !== null); // Remove null values and assert type
return repos;
} catch (error) {
console.error('Error reading or processing file:', error);
return [];
}
}
const urls = await getRepoUrls();
const repos = await loadAndProcessRepos(urls);
export const fetchAllIssues = async (): Promise<Map<string, Issue[]>> => {
const allIssues = new Map<string, Issue[]>();
for (const { owner, repo } of repos) {
console.debug(`Fetching issues for ${owner}/${repo}`)
const issues = await fetchIssuesForProject(owner, repo);
if (issues.length == 0) {
console.debug(`No issues found for ${owner}/${repo}`);
continue;
}
allIssues.set(`${owner}/${repo}`, issues);
await new Promise(resolve => setTimeout(resolve, 1000)); // Delay of 1 second
}
return allIssues;
};
export const labelName = (label: Label): string|undefined => typeof label === 'string' ? label : label?.name;
export const findLatestIssueTS = (issues: Map<string, Issue[]>): number => {
let latestTS = 0;
for (const [, value] of issues.entries()) {
for (const issue of value) {
const ts = Date.parse(issue.updated_at);
if (ts > latestTS) {
latestTS = ts;
}
}
}
return latestTS;
}
export const findIssuesAfterTS = (issues: Map<string, Issue[]>, ts: number): Map<string, Issue[]> => {
const newIssues = new Map<string, Issue[]>();
for (const [key, value] of issues.entries()) {
const newIssuesForProject = value.filter(issue => Date.parse(issue.updated_at) > ts);
if (newIssuesForProject.length > 0) {
newIssues.set(key, newIssuesForProject);
}
}
return newIssues;
}