comfy-pr 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/README.md +225 -0
  3. package/next-env.d.ts +5 -0
  4. package/package.json +115 -0
  5. package/src/CMNodes.ts +60 -0
  6. package/src/CNRepos.ts +72 -0
  7. package/src/CRNodes.ts +26 -0
  8. package/src/CRPulls.ts +4 -0
  9. package/src/FORK_OWNER.ts +5 -0
  10. package/src/FORK_PREFIX.ts +5 -0
  11. package/src/FollowRules.ts +25 -0
  12. package/src/GIT_USEREMAIL.ts +5 -0
  13. package/src/GIT_USERNAME.ts +9 -0
  14. package/src/GithubIssueComments.ts +3 -0
  15. package/src/PushedBranch.ts +3 -0
  16. package/src/Totals.ts +9 -0
  17. package/src/TrackingPRs.ts +12 -0
  18. package/src/WorkerInstances.ts +89 -0
  19. package/src/analyzePullsStatus.ts +115 -0
  20. package/src/analyzeTotals.test.ts +5 -0
  21. package/src/analyzeTotals.ts +114 -0
  22. package/src/checkComfyActivated.ts +39 -0
  23. package/src/cli.test.ts +0 -0
  24. package/src/cli.ts +40 -0
  25. package/src/clone_modify_push_Branches.ts +21 -0
  26. package/src/createComfyRegistryPRsFromCandidates.ts +55 -0
  27. package/src/createComfyRegistryPullRequests.ts +22 -0
  28. package/src/createGithubForkForRepo.ts +37 -0
  29. package/src/createGithubPullRequest.ts +94 -0
  30. package/src/createIssueComment.ts +29 -0
  31. package/src/fetchCMNodes.ts +22 -0
  32. package/src/fetchComfyRegistryNodes.ts +11 -0
  33. package/src/fetchCurrentGeoInfo.ts +6 -0
  34. package/src/fetchRelatedPullWithComments.ts +15 -0
  35. package/src/fetchRepoDescriptionMap.ts +15 -0
  36. package/src/followRuleSchema.ts +69 -0
  37. package/src/getActivatedShell.ts +18 -0
  38. package/src/getBranchWorkingDir.ts +16 -0
  39. package/src/getRepoWorkingDir.ts +6 -0
  40. package/src/ghUser.ts +6 -0
  41. package/src/index.ts +22 -0
  42. package/src/initializeFollowRules.ts +26 -0
  43. package/src/makePublishBranch.ts +58 -0
  44. package/src/makeTomlBranch.ts +53 -0
  45. package/src/matchRelatedPulls.ts +25 -0
  46. package/src/muteInstances.ts +16 -0
  47. package/src/parseIssueUrl.ts +6 -0
  48. package/src/parseOwnerRepo.ts +33 -0
  49. package/src/parsePullUrl.ts +6 -0
  50. package/src/parsePullsState.ts +6 -0
  51. package/src/parseTitleBodyOfMarkdown.ts +8 -0
  52. package/src/postSlackMessage.ts +21 -0
  53. package/src/preload.ts +30 -0
  54. package/src/pullStatusFollowSchema.ts +12 -0
  55. package/src/readTemplateTitle.ts +11 -0
  56. package/src/summaryLastPullComment.ts +8 -0
  57. package/src/tomlFillDescription.ts +17 -0
  58. package/src/updateCMNodesDuplicationWarnings.ts +56 -0
  59. package/src/updateCMRepos.ts +27 -0
  60. package/src/updateCNRepos.ts +58 -0
  61. package/src/updateCNReposCRPullsComments.ts +41 -0
  62. package/src/updateCNReposInfo.ts +57 -0
  63. package/src/updateCNReposPRCandidate.ts +85 -0
  64. package/src/updateCNReposPulls.ts +28 -0
  65. package/src/updateCNReposPullsDashboard.ts +49 -0
  66. package/src/updateCNReposRelatedPulls.ts +25 -0
  67. package/src/updateCRNodes.ts +50 -0
  68. package/src/updateCRRepos.ts +26 -0
  69. package/src/updateComfyTotals.ts +40 -0
  70. package/src/updateFollowRuleSet.ts +153 -0
  71. package/src/updateOutdatedPullsTemplates.ts +137 -0
  72. package/src/updateSlackMessages.ts +43 -0
  73. package/tailwind.config.ts +20 -0
@@ -0,0 +1,137 @@
1
+ import { $elemMatch } from "@/packages/mongodb-pipeline-ts/$elemMatch";
2
+ import DIE from "@snomiao/die";
3
+ import pMap from "p-map";
4
+ import { match } from "ts-pattern";
5
+ import { CNRepos, type CRPull } from "./CNRepos";
6
+ import { $filaten, $fresh, $stale } from "./db";
7
+ import { gh } from "./gh";
8
+ import { parsePull } from "./gh/parsePull";
9
+ import { ghUser } from "./ghUser";
10
+ import { parseUrlRepoOwner } from "./parseOwnerRepo";
11
+ import { readTemplate } from "./readTemplateTitle";
12
+ import { notifySlackLinks } from "./slack/notifySlackLinks";
13
+ import { $OK, TaskError, TaskOK } from "./utils/Task";
14
+ import { tLog } from "./utils/tLog";
15
+ import { tsmatch } from "./utils/tsmatch";
16
+ if (import.meta.main) {
17
+ await tLog("updateOutdatedPullsTemplates", updateOutdatedPullsTemplates);
18
+ }
19
+
20
+ export async function updateOutdatedPullsTemplates() {
21
+ const pyproject = await readTemplate("add-toml.md");
22
+ const publishcr = await readTemplate("add-action.md");
23
+ const outdated_pyproject = await readTemplate("outdated/add-toml.md");
24
+ const outdated_publishcr = await readTemplate("outdated/add-action.md");
25
+ // const templateOutdate = new Date("2024-06-13T09:02:56.630Z");
26
+
27
+ await CNRepos.createIndex({
28
+ "crPulls.mtime": -1,
29
+ "crPulls.data.edited.error": -1,
30
+ "crPulls.data.edited.mtime": -1,
31
+ "crPulls.data.edited.state": -1,
32
+ "crPulls.data.pull.body": -1,
33
+ "crPulls.data.pull.title": -1,
34
+ "crPulls.data.pull.user.login": -1,
35
+ });
36
+ return await pMap(
37
+ CNRepos.find(
38
+ $filaten({
39
+ crPulls: {
40
+ mtime: $fresh("1h"), // retry if update fails
41
+ data: $elemMatch({
42
+ edited: {
43
+ mtime: $stale("30m"), // retry if update fails
44
+ state: { $ne: "ok" },
45
+ error: { $nin: ["up to date", "body mismatch"] },
46
+ },
47
+ pull: {
48
+ user: { login: ghUser.login },
49
+ title: outdated_pyproject.title,
50
+ // title: {
51
+ // $in: [outdated_pyproject.title, outdated_publishcr.title],
52
+ // },
53
+ body: {
54
+ $in: [outdated_pyproject.body, outdated_publishcr.body],
55
+ },
56
+ },
57
+ }),
58
+ },
59
+ }),
60
+ // $filaten({
61
+ // crPulls: {
62
+ // data: $elemMatch({
63
+ // edited: {
64
+ // mtime: $stale("30m"), // retry if update fails
65
+ // state: { $ne: "ok" },
66
+ // error: { $nin: ["not editable", "up to date", "body mismatch"] },
67
+ // },
68
+ // pull: {
69
+ // updated_at: {
70
+ // $lte: new Date().toISOString().replace(/.\d\d\dZ/, "Z"),
71
+ // },
72
+ // },
73
+ // }),
74
+ // },
75
+ // }),
76
+ ),
77
+ async (repo) => {
78
+ const { repository } = repo;
79
+ console.log("Updating PR templates for: " + repository);
80
+ const crPulls = match(repo.crPulls)
81
+ .with($OK, (e) => e.data)
82
+ .otherwise(() => null)!;
83
+
84
+ // edit CRPulls templates to latest
85
+ const crPullsEdited = await pMap(
86
+ crPulls,
87
+ async (data, i): Promise<CRPull> => {
88
+ const { pull, type } = data;
89
+ const { number } = pull;
90
+ if (pull.user.login !== ghUser.login) DIE("not editable");
91
+ const replacement = match(pull)
92
+ .with(pyproject, () => DIE("is already latest template"))
93
+ .with(publishcr, () => DIE("is already latest template"))
94
+ .with(outdated_pyproject, () => pyproject)
95
+ .with(outdated_publishcr, () => publishcr)
96
+ // in case author clicked some task as completed, body will be different, may cause template mismatch
97
+ .otherwise(() => DIE("Template not found: " + pull.title));
98
+ if (!replacement) return { ...data, edited: TaskError("Template mismatch") };
99
+
100
+ const edited = await gh.issues
101
+ .update({
102
+ ...parseUrlRepoOwner(repository),
103
+ issue_number: number,
104
+ ...(pull.title === replacement.title ? {} : { title: replacement.title }),
105
+ ...(pull.body === replacement.body ? {} : { body: replacement.body }),
106
+ })
107
+ .then(() => true as const)
108
+ .then(TaskOK)
109
+ .catch(TaskError);
110
+ const updatedPull = (
111
+ await gh.pulls.get({
112
+ ...parseUrlRepoOwner(repository),
113
+ pull_number: number,
114
+ })
115
+ ).data;
116
+ await CNRepos.updateOne({ repository }, { $set: { [`crPulls.data.${i}.edited`]: edited } });
117
+ return { pull: parsePull(updatedPull), type, edited };
118
+ },
119
+ { concurrency: 2 },
120
+ )
121
+ .then(TaskOK)
122
+ .catch(TaskError);
123
+ tsmatch(crPullsEdited)
124
+ .with($OK, async ({ data }) => {
125
+ await notifySlackLinks(
126
+ `Updated PR body to latest template`,
127
+ data.map((e) => e.pull.html_url),
128
+ );
129
+ })
130
+ .otherwise(() => {});
131
+ await CNRepos.updateOne({ repository }, { $set: { crPullsEdited } });
132
+ // update outdated pr issue bodies
133
+ return crPullsEdited;
134
+ },
135
+ { concurrency: 2 },
136
+ );
137
+ }
@@ -0,0 +1,43 @@
1
+ import { $fresh, $stale } from "@/packages/mongodb-pipeline-ts";
2
+ import { $filaten } from "@/packages/mongodb-pipeline-ts/$filaten";
3
+ import pMap from "p-map";
4
+ import { postSlackMessage } from "./postSlackMessage";
5
+ import { SlackMsgs } from "./slack/SlackMsgs";
6
+
7
+ export async function updateSlackMessages() {
8
+ // send
9
+ return await pMap(
10
+ SlackMsgs.find(
11
+ $filaten({
12
+ $or: [
13
+ { status: { $exists: false } },
14
+ {
15
+ status: { $in: ["pending last", "error"] },
16
+ mtime: $stale("5m"), // try errors again after 5m
17
+ },
18
+ ],
19
+ }),
20
+ ),
21
+ async ({ _id, text, last_id: last, silent }) => {
22
+ await SlackMsgs.updateOne({ _id }, { $set: { status: "sending" } });
23
+ // max 5 msg per 30s
24
+ while (5 <= (await SlackMsgs.countDocuments({ mtime: $fresh("30s") })))
25
+ await new Promise((r) => setTimeout(r, 1000));
26
+ if (last) {
27
+ // check if last succ
28
+ const lastSent = await SlackMsgs.findOne({ _id: last });
29
+ if (lastSent?.status !== "sent") {
30
+ await SlackMsgs.updateOne({ _id }, { $set: { status: "pending last" } });
31
+ return;
32
+ }
33
+ }
34
+ console.log("SLACK POST MSG: " + JSON.stringify(text));
35
+ if (silent) return await SlackMsgs.updateOne({ _id }, { $set: { status: "sent", mtime: new Date() } });
36
+ const sent = await postSlackMessage(text)
37
+ .then((e) => ({ ...e, error: undefined, status: "sent" as const }))
38
+ .catch((e) => ({ error: e.message ?? String(e), status: "error" as const }));
39
+ await SlackMsgs.updateOne({ _id }, { $set: { ...sent, mtime: new Date() } });
40
+ },
41
+ { concurrency: 2 },
42
+ );
43
+ }
@@ -0,0 +1,20 @@
1
+ import daisyui from "daisyui";
2
+ import type { Config } from "tailwindcss";
3
+ const config: Config = {
4
+ content: [
5
+ "./pages/**/*.{js,ts,jsx,tsx,mdx}",
6
+ "./components/**/*.{js,ts,jsx,tsx,mdx}",
7
+ "./app/**/*.{js,ts,jsx,tsx,mdx}",
8
+ ],
9
+ theme: {
10
+ extend: {
11
+ backgroundImage: {
12
+ "gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
13
+ "gradient-conic": "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
14
+ },
15
+ },
16
+ },
17
+ plugins: [daisyui],
18
+ daisyui: { logs: false },
19
+ };
20
+ export default config;