1 | import { |
2 | setState, |
3 | getState, |
4 | } from "https://deno.land/x/[email protected]/mod.ts"; |
5 | import { Octokit } from "npm:@octokit/[email protected]"; |
6 |
|
7 | const MAX_ITEMS = 500; |
8 | const PAGE_SIZE = 50; |
9 |
|
10 | |
11 | * @returns A list of issues in ascending order of creation date. |
12 | * |
13 | * The maximum number of returned items is 500 and therefore you'll miss |
14 | * the issues that are older than the 500th one. Please choose your |
15 | * scheduling accordingly. |
16 | */ |
17 | type Github = { |
18 | token: string; |
19 | }; |
20 | export async function main(auth: Github, owner: string, repo: string) { |
21 | const octokit = new Octokit({ |
22 | auth: auth.token, |
23 | }); |
24 | const newIssues: Issue[] = []; |
25 | const lastUpdate = await getState(); |
26 |
|
27 | let runLoop = true; |
28 | let page = 1; |
29 | do { |
30 | const result = await octokit.issues.listForRepo({ |
31 | owner, |
32 | repo, |
33 | filter: "all", |
34 | state: "open", |
35 | sort: "created", |
36 | direction: "desc", |
37 | per_page: PAGE_SIZE, |
38 | page: page++, |
39 | }); |
40 | const issues = result.data.filter((i) => i && !i.pull_request); |
41 |
|
42 | for (let i = 0; i < issues.length; i++) { |
43 | const issue = issues[i]; |
44 | if (new Date(issue.created_at).getTime() <= lastUpdate) { |
45 | runLoop = false; |
46 | break; |
47 | } |
48 | newIssues.push({ |
49 | title: issue.title, |
50 | url: issue.html_url, |
51 | created_at: issue.created_at, |
52 | user: { |
53 | login: issue.user?.login, |
54 | url: issue.user?.html_url, |
55 | }, |
56 | labels: <string[]>( |
57 | issue.labels |
58 | .map((l) => (typeof l === "string" ? l : l.name)) |
59 | .filter(Boolean) |
60 | ), |
61 | }); |
62 | if (newIssues.length >= MAX_ITEMS) { |
63 | runLoop = false; |
64 | break; |
65 | } |
66 | } |
67 |
|
68 | if (result.data.length < PAGE_SIZE) { |
69 | break; |
70 | } |
71 | } while (runLoop); |
72 |
|
73 | if (newIssues.length) { |
74 | await setState(new Date(newIssues[0].created_at).getTime()); |
75 | } |
76 | return newIssues.reverse(); |
77 | } |
78 |
|
79 | interface Issue { |
80 | title: string; |
81 | url: string; |
82 | created_at: string; |
83 | user: { |
84 | login?: string; |
85 | url?: string; |
86 | }; |
87 | labels: string[]; |
88 | } |
89 |
|