comfy-pr 0.2.24 → 0.2.26
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.
- package/README.md +247 -225
- package/index.ts +6 -0
- package/next-env.d.ts +5 -5
- package/package.json +52 -25
- package/src/Authors.ts +42 -48
- package/src/CMNodes.ts +60 -60
- package/src/CNRepos.ts +78 -74
- package/src/CRNodes.ts +27 -27
- package/src/CRPulls.ts +4 -4
- package/src/EmailTasks.ts +101 -0
- package/src/FORK_OWNER.ts +5 -5
- package/src/FORK_PREFIX.ts +5 -5
- package/src/FollowRules.ts +25 -25
- package/src/GIT_USEREMAIL.ts +5 -5
- package/src/GIT_USERNAME.ts +9 -9
- package/src/GithubIssueComments.ts +3 -3
- package/src/PushedBranch.ts +3 -3
- package/src/Totals.ts +24 -9
- package/src/TrackingPRs.ts +12 -12
- package/src/WorkerInstances.ts +89 -89
- package/src/addCommentAction.ts +73 -65
- package/src/analyzePullsStatus.ts +219 -170
- package/src/analyzeTotals.test.ts +5 -5
- package/src/analyzeTotals.ts +118 -118
- package/src/bypassRepos.spec.ts +10 -0
- package/src/bypassRepos.ts +8 -0
- package/src/checkComfyActivated.ts +39 -39
- package/src/checkPRsFailures.ts +18 -0
- package/src/cli.ts +40 -40
- package/src/clone_modify_push_Branches.ts +21 -21
- package/src/createComfyRegistryPRsFromCandidates.ts +55 -55
- package/src/createComfyRegistryPullRequests.ts +32 -22
- package/src/createGithubForkForRepo.ts +54 -37
- package/src/createGithubPullRequest.ts +157 -94
- package/src/createIssueComment.ts +34 -29
- package/src/fetchCMNodes.ts +22 -22
- package/src/fetchComfyRegistryNodes.ts +11 -11
- package/src/fetchCurrentGeoInfo.ts +6 -6
- package/src/fetchRelatedPullWithComments.ts +15 -15
- package/src/fetchRepoDescriptionMap.ts +15 -15
- package/src/followRuleSchema.ts +79 -76
- package/src/getActivatedShell.ts +18 -18
- package/src/getBranchWorkingDir.ts +16 -16
- package/src/getRepoWorkingDir.ts +5 -5
- package/src/ghUser.ts +9 -6
- package/src/index.ts +26 -22
- package/src/initializeFollowRules.ts +26 -26
- package/src/makePublishBranch.ts +58 -58
- package/src/makeTomlBranch.ts +53 -53
- package/src/makeUpdateTomlLicenseBranch.ts +245 -0
- package/src/matchRelatedPulls.ts +47 -60
- package/src/muteInstances.ts +16 -16
- package/src/parseIssueUrl.ts +6 -6
- package/src/parseOwnerRepo.ts +33 -33
- package/src/parsePullUrl.ts +6 -6
- package/src/parsePullsState.ts +6 -6
- package/src/parseTitleBodyOfMarkdown.ts +8 -8
- package/src/postSlackMessage.ts +21 -21
- package/src/preload.ts +30 -30
- package/src/pullStatusFollowSchema.ts +12 -12
- package/src/readTemplateTitle.ts +11 -11
- package/src/sendEmailAction.ts +56 -0
- package/src/sendGmail.ts +105 -0
- package/src/showFollowRuleSet.ts +12 -12
- package/src/summaryLastPullComment.ts +8 -8
- package/src/tomlFillDescription.ts +17 -17
- package/src/updateAuthors.ts +7 -7
- package/src/updateAuthorsForGithub.ts +54 -50
- package/src/updateAuthorsFromCNRepo.ts +30 -30
- package/src/updateCMNodesDuplicationWarnings.ts +56 -56
- package/src/updateCMRepos.ts +27 -27
- package/src/updateCNRepos.ts +58 -58
- package/src/updateCNReposCRPullsComments.ts +40 -40
- package/src/updateCNReposInfo.ts +58 -57
- package/src/updateCNReposPRCandidate.ts +85 -85
- package/src/updateCNReposPulls.ts +31 -28
- package/src/updateCNReposPullsDashboard.ts +49 -49
- package/src/updateCNReposRelatedPulls.ts +25 -25
- package/src/updateCRNodes.ts +50 -50
- package/src/updateCRRepos.ts +26 -26
- package/src/updateComfyTotals.ts +43 -43
- package/src/updateFollowRuleSet.ts +136 -127
- package/src/updateOutdatedPullsTemplates.ts +165 -160
- package/src/updateSlackMessages.ts +43 -43
- package/tailwind.config.ts +75 -20
|
@@ -1,170 +1,219 @@
|
|
|
1
|
-
import { $pipeline } from "@/packages/mongodb-pipeline-ts/$pipeline";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import type {
|
|
6
|
-
import type {
|
|
7
|
-
import {
|
|
8
|
-
import type
|
|
9
|
-
import {
|
|
10
|
-
import type {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
//
|
|
20
|
-
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
// await writeFile("
|
|
24
|
-
|
|
25
|
-
//
|
|
26
|
-
await
|
|
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
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
})
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
.set({
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
})
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
.
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
1
|
+
import { $pipeline, type Pipeline } from "@/packages/mongodb-pipeline-ts/$pipeline";
|
|
2
|
+
import type { ObjectId } from "mongodb";
|
|
3
|
+
import prettyMs from "pretty-ms";
|
|
4
|
+
import { snoflow } from "snoflow";
|
|
5
|
+
import type { z } from "zod";
|
|
6
|
+
import type { Task } from "../packages/mongodb-pipeline-ts/Task";
|
|
7
|
+
import type { Author } from "./Authors";
|
|
8
|
+
import { CNRepos, type CRPull } from "./CNRepos";
|
|
9
|
+
import type { EmailTask } from "./EmailTasks";
|
|
10
|
+
import type { GithubIssueComment } from "./GithubIssueComments";
|
|
11
|
+
import { db } from "./db";
|
|
12
|
+
import { yaml } from "./utils/yaml";
|
|
13
|
+
import type { zPullStatus } from "./zod/zPullsStatus";
|
|
14
|
+
// import { $pipeline } from "./db/$pipeline";
|
|
15
|
+
// in case of dump production in local environment:
|
|
16
|
+
// bun --env-file .env.production.local src/dump.ts > dump.csv
|
|
17
|
+
export const DashboardDetails = db.collection<any>("DashboardDetails");
|
|
18
|
+
if (import.meta.main) {
|
|
19
|
+
// const r = peekYaml(await analyzePullsStatus());
|
|
20
|
+
|
|
21
|
+
// await mkdir(".cache").catch(() => null);
|
|
22
|
+
// await writeFile(".cache/dump.yaml", YAML.stringify(r));
|
|
23
|
+
// await writeFile(".cache/dump.csv", csvFormat(r));
|
|
24
|
+
// console.log("done");
|
|
25
|
+
// generate zod schema
|
|
26
|
+
// await writeFile("src/zPullsStatus.ts", jsonToZod(await analyzePullsStatus({ limit: 1 }), "zPullsStatus", true));
|
|
27
|
+
|
|
28
|
+
// analyzePullsStatusPipeline
|
|
29
|
+
await snoflow(analyzePullsStatusPipeline().aggregate())
|
|
30
|
+
.filter((e) => e.email)
|
|
31
|
+
.limit(2)
|
|
32
|
+
.map((e) => yaml.stringify({ e }))
|
|
33
|
+
.log()
|
|
34
|
+
.chunk()
|
|
35
|
+
.map((e) => e.length)
|
|
36
|
+
.toLog();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export type PullStatus = z.infer<typeof zPullStatus>;
|
|
40
|
+
export type PullsStatus = PullStatus[];
|
|
41
|
+
export type PullStatusShown = Awaited<ReturnType<typeof analyzePullsStatus>>[number];
|
|
42
|
+
|
|
43
|
+
export async function analyzePullsStatus({ skip = 0, limit = 0, pipeline = analyzePullsStatusPipeline() } = {}) {
|
|
44
|
+
"use server";
|
|
45
|
+
return await pipeline
|
|
46
|
+
.skip(skip)
|
|
47
|
+
.limit(limit || 2 ** 31 - 1)
|
|
48
|
+
.aggregate()
|
|
49
|
+
.map(({ updated_at, created_at, actived_at, on_registry_at, ...pull }) => {
|
|
50
|
+
const pull_updated = prettyMs(+new Date() - +new Date(updated_at), { compact: true }) + " ago";
|
|
51
|
+
const repo_updated = prettyMs(+new Date() - +new Date(actived_at), { compact: true }) + " ago";
|
|
52
|
+
return {
|
|
53
|
+
updated: pull_updated, // @deprecated
|
|
54
|
+
pull_updated,
|
|
55
|
+
repo_updated,
|
|
56
|
+
...pull,
|
|
57
|
+
lastcomment: pull.lastcomment?.replace(/\s+/g, " ").replace(/\*\*\*.*/g, "..."),
|
|
58
|
+
};
|
|
59
|
+
})
|
|
60
|
+
.toArray();
|
|
61
|
+
}
|
|
62
|
+
export function baseCRPullStatusPipeline(): Pipeline<
|
|
63
|
+
CRPull & {
|
|
64
|
+
repo: string;
|
|
65
|
+
on_registry: Task<boolean>;
|
|
66
|
+
type: string;
|
|
67
|
+
comments: GithubIssueComment[];
|
|
68
|
+
emailTask_id?: ObjectId;
|
|
69
|
+
}
|
|
70
|
+
> {
|
|
71
|
+
return (
|
|
72
|
+
$pipeline(CNRepos)
|
|
73
|
+
// get latest pr comments time
|
|
74
|
+
.set({ "crPulls.data.pull.latest_comment_at": { $max: { $max: "$crPulls.data.comments.data.updated_at" } } })
|
|
75
|
+
// unwind
|
|
76
|
+
.stage({ $unwind: "$crPulls.data" })
|
|
77
|
+
.match({ "crPulls.data.comments.data": { $exists: true } })
|
|
78
|
+
// repo infos
|
|
79
|
+
.set({ "crPulls.data.pull.actived_at": { $toDate: "$info.data.updated_at" } })
|
|
80
|
+
.set({ "crPulls.data.pull.repo": "$repository" })
|
|
81
|
+
.set({ "crPulls.data.pull.email": "$email" })
|
|
82
|
+
.set({ "crPulls.data.pull.on_registry": "$on_registry" })
|
|
83
|
+
// pull info
|
|
84
|
+
.set({ "crPulls.data.pull.type": "$crPulls.data.type" })
|
|
85
|
+
.set({ "crPulls.data.pull": "$crPulls.data.pull" })
|
|
86
|
+
.set({ "crPulls.data.pull.comments": "$crPulls.data.comments.data" })
|
|
87
|
+
.set({ "crPulls.data.pull.emailTask_id": "$crPulls.data.emailTask_id" })
|
|
88
|
+
// replace root as pull
|
|
89
|
+
.replaceRoot({ newRoot: "$crPulls.data.pull" })
|
|
90
|
+
.as<
|
|
91
|
+
CRPull & {
|
|
92
|
+
repo: string;
|
|
93
|
+
on_registry: Task<boolean>;
|
|
94
|
+
type: string;
|
|
95
|
+
comments: GithubIssueComment[];
|
|
96
|
+
emailTask_id?: ObjectId;
|
|
97
|
+
}
|
|
98
|
+
>()
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
export function analyzePullsStatusPipeline(): Pipeline<{
|
|
102
|
+
actived_at: Date;
|
|
103
|
+
email: string | "";
|
|
104
|
+
comments: number;
|
|
105
|
+
created_at: Date;
|
|
106
|
+
head: string;
|
|
107
|
+
lastcomment: string;
|
|
108
|
+
on_registry_at: Date;
|
|
109
|
+
on_registry: boolean;
|
|
110
|
+
comments_author: string;
|
|
111
|
+
ownername: string;
|
|
112
|
+
nickName: string;
|
|
113
|
+
repository: string;
|
|
114
|
+
state: "OPEN" | "MERGED" | "CLOSED";
|
|
115
|
+
updated_at: Date;
|
|
116
|
+
emailState: EmailTask["state"] | "";
|
|
117
|
+
url: string;
|
|
118
|
+
}> {
|
|
119
|
+
return (
|
|
120
|
+
baseCRPullStatusPipeline()
|
|
121
|
+
// fetch author email from Authors collection
|
|
122
|
+
.set({ ownername: "$base.user.login" })
|
|
123
|
+
.lookup({
|
|
124
|
+
from: "Authors",
|
|
125
|
+
// let: { <var_1>: <expression>, …, <var_n>: <expression> },
|
|
126
|
+
localField: "ownername",
|
|
127
|
+
foreignField: "githubId",
|
|
128
|
+
as: "author",
|
|
129
|
+
pipeline: [{ $project: { email: 1 } }],
|
|
130
|
+
})
|
|
131
|
+
.unwind({ path: "$author", preserveNullAndEmptyArrays: true })
|
|
132
|
+
.with<{ author: Author }>()
|
|
133
|
+
.lookup({
|
|
134
|
+
from: "EmailTasks",
|
|
135
|
+
// let: { <var_1>: <expression>, …, <var_n>: <expression> },
|
|
136
|
+
localField: "emailTask_id",
|
|
137
|
+
foreignField: "_id",
|
|
138
|
+
as: "emailTask",
|
|
139
|
+
})
|
|
140
|
+
.unwind({ path: "$emailTask", preserveNullAndEmptyArrays: true })
|
|
141
|
+
.set({ emailState: { $ifNull: ["$emailTask.state", ""] } }) // output could be "" | "waiting" | "sending" | "sent" | "error";
|
|
142
|
+
.with<{ emailState: EmailTask["state"] }>()
|
|
143
|
+
|
|
144
|
+
// .set({ author: { $first: ["$author"] } })
|
|
145
|
+
.project({ authors: 0 })
|
|
146
|
+
|
|
147
|
+
.set({ lastcomment: { $arrayElemAt: ["$comments", -1] } })
|
|
148
|
+
.set({ lastcomment: { $ifNull: [{ $concat: ["$lastcomment.user.login", ": ", "$lastcomment.body"] }, ""] } })
|
|
149
|
+
|
|
150
|
+
// calculate update_at max( )
|
|
151
|
+
// date format convert
|
|
152
|
+
.set({ created_at: { $toDate: "$created_at" } })
|
|
153
|
+
.set({ updated_at: { $toDate: "$updated_at" } })
|
|
154
|
+
.set({ latest_comment_at: { $toDate: "$latest_comment_at" } })
|
|
155
|
+
.set({ updated_at: { $max: ["$latest_comment_at", "$updated_at"] } })
|
|
156
|
+
|
|
157
|
+
// // projecting
|
|
158
|
+
.project({
|
|
159
|
+
created_at: 1,
|
|
160
|
+
updated_at: 1,
|
|
161
|
+
repository: 1,
|
|
162
|
+
on_registry: "$on_registry.data",
|
|
163
|
+
on_registry_at: "$on_registry.mtime",
|
|
164
|
+
state: { $toUpper: `$prState` },
|
|
165
|
+
url: "$html_url",
|
|
166
|
+
ownername: "$base.user.login",
|
|
167
|
+
nickName: "$base.user.name",
|
|
168
|
+
head: { $concat: ["$user.login", ":", "$type"] },
|
|
169
|
+
comments: { $size: "$comments" },
|
|
170
|
+
comments_author: {
|
|
171
|
+
$trim: {
|
|
172
|
+
input: {
|
|
173
|
+
$reduce: {
|
|
174
|
+
input: "$comments.user.login",
|
|
175
|
+
initialValue: "",
|
|
176
|
+
in: { $concat: ["$$value", " ", "$$this"] },
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
chars: " ",
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
actived_at: 1,
|
|
183
|
+
lastcomment: 1,
|
|
184
|
+
|
|
185
|
+
instagramId: "$author.instagramId",
|
|
186
|
+
discordId: "$author.discordId",
|
|
187
|
+
twitterId: "$author.twitterId",
|
|
188
|
+
email: { $ifNull: ["$author.email", ""] },
|
|
189
|
+
emailState: 1,
|
|
190
|
+
})
|
|
191
|
+
.unset("latest_comment_at")
|
|
192
|
+
.set({
|
|
193
|
+
CLOSED: { $eq: ["$state", "CLOSED"] },
|
|
194
|
+
MERGED: { $eq: ["$state", "MERGED"] },
|
|
195
|
+
OPEN: { $eq: ["$state", "OPEN"] },
|
|
196
|
+
})
|
|
197
|
+
.sort({ ownername: 1 })
|
|
198
|
+
.sort({ OPEN: -1, MERGED: -1, CLOSED: -1, updated_at: 1 })
|
|
199
|
+
.unset(["CLOSED", "MERGED", "OPEN"])
|
|
200
|
+
.as<{
|
|
201
|
+
actived_at: Date;
|
|
202
|
+
email: string | "";
|
|
203
|
+
comments: number;
|
|
204
|
+
created_at: Date;
|
|
205
|
+
head: string;
|
|
206
|
+
lastcomment: string;
|
|
207
|
+
on_registry_at: Date;
|
|
208
|
+
on_registry: boolean;
|
|
209
|
+
comments_author: string;
|
|
210
|
+
ownername: string;
|
|
211
|
+
nickName: string;
|
|
212
|
+
repository: string;
|
|
213
|
+
state: "OPEN" | "MERGED" | "CLOSED";
|
|
214
|
+
updated_at: Date;
|
|
215
|
+
emailState: EmailTask["state"] | "";
|
|
216
|
+
url: string;
|
|
217
|
+
}>()
|
|
218
|
+
);
|
|
219
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { analyzeTotals } from "./analyzeTotals";
|
|
2
|
-
|
|
3
|
-
it("analyze totals", async () => {
|
|
4
|
-
expect(await analyzeTotals()).toBeTruthy();
|
|
5
|
-
});
|
|
1
|
+
import { analyzeTotals } from "./analyzeTotals";
|
|
2
|
+
|
|
3
|
+
it("analyze totals", async () => {
|
|
4
|
+
expect(await analyzeTotals()).toBeTruthy();
|
|
5
|
+
});
|
package/src/analyzeTotals.ts
CHANGED
|
@@ -1,118 +1,118 @@
|
|
|
1
|
-
"use server";
|
|
2
|
-
import { $pipeline } from "@/packages/mongodb-pipeline-ts/$pipeline";
|
|
3
|
-
import promiseAllProperties from "promise-all-properties";
|
|
4
|
-
import YAML from "yaml";
|
|
5
|
-
import { CMNodes } from "./CMNodes";
|
|
6
|
-
import { CNRepos } from "./CNRepos";
|
|
7
|
-
import { CRNodes } from "./CRNodes";
|
|
8
|
-
import { $filaten } from "./db";
|
|
9
|
-
import { tLog } from "./utils/tLog";
|
|
10
|
-
|
|
11
|
-
if (import.meta.main) {
|
|
12
|
-
await tLog("analyzeTotals", async () => {
|
|
13
|
-
console.log(YAML.stringify(await analyzeTotals()));
|
|
14
|
-
return [];
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* @warning this function is heavy, TODO: split into small chunk
|
|
19
|
-
*/
|
|
20
|
-
export async function analyzeTotals() {
|
|
21
|
-
"use server";
|
|
22
|
-
const totals = await promiseAllProperties({
|
|
23
|
-
// Now: new Date().toISOString(),
|
|
24
|
-
"Total Nodes": promiseAllProperties({
|
|
25
|
-
"on ComfyUI Manager": CMNodes.estimatedDocumentCount(),
|
|
26
|
-
"on Registry": CRNodes.estimatedDocumentCount(),
|
|
27
|
-
}),
|
|
28
|
-
"Total Repos": $pipeline(CNRepos)
|
|
29
|
-
.group({
|
|
30
|
-
_id: null,
|
|
31
|
-
"on Comfy Manager List": { $sum: { $cond: [{ $eq: [{ $type: "$cm" }, "missing"] }, 0, 1] } },
|
|
32
|
-
"on Registry": { $sum: { $cond: [{ $eq: [{ $type: "$cr" }, "missing"] }, 0, 1] } },
|
|
33
|
-
Archived: { $sum: { $cond: ["$info.data.archived", 1, 0] } },
|
|
34
|
-
All: { $sum: 1 },
|
|
35
|
-
// Candidates: { $sum: { $cond: ["$candidate.data", 1, 0] } },
|
|
36
|
-
"Got ERROR on creating PR": { $sum: { $cond: [{ $eq: ["$createdPulls.state", "error"] }, 1, 0] } },
|
|
37
|
-
})
|
|
38
|
-
.project({ _id: 0 })
|
|
39
|
-
.aggregate()
|
|
40
|
-
// .map((e: any) => e.pairs)
|
|
41
|
-
.next(),
|
|
42
|
-
"Total Authors": $pipeline(CNRepos)
|
|
43
|
-
.match($filaten({ info: { data: { owner: { login: { $exists: true } } } } }))
|
|
44
|
-
.group({
|
|
45
|
-
_id: "$info.data.owner.login",
|
|
46
|
-
// author: "$info.data.owner.login",
|
|
47
|
-
cm: { $sum: { $cond: [{ $eq: [{ $type: "$cm" }, "missing"] }, 0, 1] } },
|
|
48
|
-
cr: { $sum: { $cond: [{ $eq: [{ $type: "$cr" }, "missing"] }, 0, 1] } },
|
|
49
|
-
All: { $sum: 1 },
|
|
50
|
-
})
|
|
51
|
-
.set({ author: "$_id" })
|
|
52
|
-
.group({
|
|
53
|
-
_id: null,
|
|
54
|
-
"on Comfy Manager List": { $sum: { $cond: [{ $eq: ["$cm", 0] }, 0, 1] } },
|
|
55
|
-
"on Registry": { $sum: { $cond: [{ $eq: ["$cr", 0] }, 0, 1] } },
|
|
56
|
-
All: { $sum: 1 },
|
|
57
|
-
})
|
|
58
|
-
.project({ _id: 0 })
|
|
59
|
-
.aggregate()
|
|
60
|
-
// .map((e: any) => e.pairs)
|
|
61
|
-
.next(),
|
|
62
|
-
"Total PRs Made": $pipeline(CNRepos)
|
|
63
|
-
.unwind("$crPulls.data")
|
|
64
|
-
.group({ _id: "$crPulls.data.type", total: { $sum: 1 } })
|
|
65
|
-
.sort({ _id: 1 })
|
|
66
|
-
.set({ id_total: [["$_id", "$total"]] })
|
|
67
|
-
.group({ _id: null, pairs: { $mergeObjects: { $arrayToObject: "$id_total" } } })
|
|
68
|
-
.aggregate()
|
|
69
|
-
.map((e: any) => e.pairs)
|
|
70
|
-
.next(),
|
|
71
|
-
"Total Open": $pipeline(CNRepos)
|
|
72
|
-
.unwind("$crPulls.data")
|
|
73
|
-
.match({ "crPulls.data.pull.prState": "open" })
|
|
74
|
-
.group({ _id: "$crPulls.data.type", total: { $sum: 1 } })
|
|
75
|
-
.sort({ _id: 1 })
|
|
76
|
-
.set({ id_total: [["$_id", "$total"]] })
|
|
77
|
-
.group({ _id: null, pairs: { $mergeObjects: { $arrayToObject: "$id_total" } } })
|
|
78
|
-
.aggregate()
|
|
79
|
-
.map((e: any) => e.pairs)
|
|
80
|
-
.next(),
|
|
81
|
-
"Total Merged (on Registry)": $pipeline(CNRepos)
|
|
82
|
-
.unwind("$crPulls.data")
|
|
83
|
-
.match({ cr: { $exists: true }, "crPulls.data.pull.prState": "merged" })
|
|
84
|
-
.group({ _id: "$crPulls.data.type", total: { $sum: 1 } })
|
|
85
|
-
.sort({ _id: 1 })
|
|
86
|
-
.set({ id_total: [["$_id", "$total"]] })
|
|
87
|
-
.group({ _id: null, pairs: { $mergeObjects: { $arrayToObject: "$id_total" } } })
|
|
88
|
-
.aggregate()
|
|
89
|
-
.map((e: any) => e.pairs)
|
|
90
|
-
.next(),
|
|
91
|
-
"Total Merged (not on Registry)": $pipeline(CNRepos)
|
|
92
|
-
.unwind("$crPulls.data")
|
|
93
|
-
.match({ cr: { $exists: false }, "crPulls.data.pull.prState": "merged" })
|
|
94
|
-
.group({ _id: "$crPulls.data.type", total: { $sum: 1 } })
|
|
95
|
-
.sort({ _id: 1 })
|
|
96
|
-
.set({ id_total: [["$_id", "$total"]] })
|
|
97
|
-
.group({ _id: null, pairs: { $mergeObjects: { $arrayToObject: "$id_total" } } })
|
|
98
|
-
.aggregate()
|
|
99
|
-
.map((e: any) => e.pairs)
|
|
100
|
-
.next(),
|
|
101
|
-
"Total Closed": $pipeline(CNRepos)
|
|
102
|
-
.unwind("$crPulls.data")
|
|
103
|
-
.match({ "crPulls.data.pull.prState": "closed" })
|
|
104
|
-
.group({ _id: "$crPulls.data.type", total: { $sum: 1 } })
|
|
105
|
-
.sort({ _id: 1 })
|
|
106
|
-
.set({ id_total: [["$_id", "$total"]] })
|
|
107
|
-
.group({ _id: null, pairs: { $mergeObjects: { $arrayToObject: "$id_total" } } })
|
|
108
|
-
.aggregate()
|
|
109
|
-
.map((e: any) => e.pairs)
|
|
110
|
-
.next(),
|
|
111
|
-
|
|
112
|
-
// // Follow Rules
|
|
113
|
-
// "Follow Up Rules": (async function () {
|
|
114
|
-
// return TaskDataOrNull(await showFollowRuleSet({ name: "default" }));
|
|
115
|
-
// })(),
|
|
116
|
-
});
|
|
117
|
-
return totals;
|
|
118
|
-
}
|
|
1
|
+
"use server";
|
|
2
|
+
import { $pipeline } from "@/packages/mongodb-pipeline-ts/$pipeline";
|
|
3
|
+
import promiseAllProperties from "promise-all-properties";
|
|
4
|
+
import YAML from "yaml";
|
|
5
|
+
import { CMNodes } from "./CMNodes";
|
|
6
|
+
import { CNRepos } from "./CNRepos";
|
|
7
|
+
import { CRNodes } from "./CRNodes";
|
|
8
|
+
import { $filaten } from "./db";
|
|
9
|
+
import { tLog } from "./utils/tLog";
|
|
10
|
+
|
|
11
|
+
if (import.meta.main) {
|
|
12
|
+
await tLog("analyzeTotals", async () => {
|
|
13
|
+
console.log(YAML.stringify(await analyzeTotals()));
|
|
14
|
+
return [];
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* @warning this function is heavy, TODO: split into small chunk
|
|
19
|
+
*/
|
|
20
|
+
export async function analyzeTotals() {
|
|
21
|
+
"use server";
|
|
22
|
+
const totals = await promiseAllProperties({
|
|
23
|
+
// Now: new Date().toISOString(),
|
|
24
|
+
"Total Nodes": promiseAllProperties({
|
|
25
|
+
"on ComfyUI Manager": CMNodes.estimatedDocumentCount(),
|
|
26
|
+
"on Registry": CRNodes.estimatedDocumentCount(),
|
|
27
|
+
}),
|
|
28
|
+
"Total Repos": $pipeline(CNRepos)
|
|
29
|
+
.group({
|
|
30
|
+
_id: null,
|
|
31
|
+
"on Comfy Manager List": { $sum: { $cond: [{ $eq: [{ $type: "$cm" }, "missing"] }, 0, 1] } },
|
|
32
|
+
"on Registry": { $sum: { $cond: [{ $eq: [{ $type: "$cr" }, "missing"] }, 0, 1] } },
|
|
33
|
+
Archived: { $sum: { $cond: ["$info.data.archived", 1, 0] } },
|
|
34
|
+
All: { $sum: 1 },
|
|
35
|
+
// Candidates: { $sum: { $cond: ["$candidate.data", 1, 0] } },
|
|
36
|
+
"Got ERROR on creating PR": { $sum: { $cond: [{ $eq: ["$createdPulls.state", "error"] }, 1, 0] } },
|
|
37
|
+
})
|
|
38
|
+
.project({ _id: 0 })
|
|
39
|
+
.aggregate()
|
|
40
|
+
// .map((e: any) => e.pairs)
|
|
41
|
+
.next(),
|
|
42
|
+
"Total Authors": $pipeline(CNRepos)
|
|
43
|
+
.match($filaten({ info: { data: { owner: { login: { $exists: true } } } } }))
|
|
44
|
+
.group({
|
|
45
|
+
_id: "$info.data.owner.login",
|
|
46
|
+
// author: "$info.data.owner.login",
|
|
47
|
+
cm: { $sum: { $cond: [{ $eq: [{ $type: "$cm" }, "missing"] }, 0, 1] } },
|
|
48
|
+
cr: { $sum: { $cond: [{ $eq: [{ $type: "$cr" }, "missing"] }, 0, 1] } },
|
|
49
|
+
All: { $sum: 1 },
|
|
50
|
+
})
|
|
51
|
+
.set({ author: "$_id" })
|
|
52
|
+
.group({
|
|
53
|
+
_id: null,
|
|
54
|
+
"on Comfy Manager List": { $sum: { $cond: [{ $eq: ["$cm", 0] }, 0, 1] } },
|
|
55
|
+
"on Registry": { $sum: { $cond: [{ $eq: ["$cr", 0] }, 0, 1] } },
|
|
56
|
+
All: { $sum: 1 },
|
|
57
|
+
})
|
|
58
|
+
.project({ _id: 0 })
|
|
59
|
+
.aggregate()
|
|
60
|
+
// .map((e: any) => e.pairs)
|
|
61
|
+
.next(),
|
|
62
|
+
"Total PRs Made": $pipeline(CNRepos)
|
|
63
|
+
.unwind("$crPulls.data")
|
|
64
|
+
.group({ _id: "$crPulls.data.type", total: { $sum: 1 } })
|
|
65
|
+
.sort({ _id: 1 })
|
|
66
|
+
.set({ id_total: [["$_id", "$total"]] })
|
|
67
|
+
.group({ _id: null, pairs: { $mergeObjects: { $arrayToObject: "$id_total" } } })
|
|
68
|
+
.aggregate()
|
|
69
|
+
.map((e: any) => e.pairs)
|
|
70
|
+
.next(),
|
|
71
|
+
"Total Open": $pipeline(CNRepos)
|
|
72
|
+
.unwind("$crPulls.data")
|
|
73
|
+
.match({ "crPulls.data.pull.prState": "open" })
|
|
74
|
+
.group({ _id: "$crPulls.data.type", total: { $sum: 1 } })
|
|
75
|
+
.sort({ _id: 1 })
|
|
76
|
+
.set({ id_total: [["$_id", "$total"]] })
|
|
77
|
+
.group({ _id: null, pairs: { $mergeObjects: { $arrayToObject: "$id_total" } } })
|
|
78
|
+
.aggregate()
|
|
79
|
+
.map((e: any) => e.pairs)
|
|
80
|
+
.next(),
|
|
81
|
+
"Total Merged (on Registry)": $pipeline(CNRepos)
|
|
82
|
+
.unwind("$crPulls.data")
|
|
83
|
+
.match({ cr: { $exists: true }, "crPulls.data.pull.prState": "merged" })
|
|
84
|
+
.group({ _id: "$crPulls.data.type", total: { $sum: 1 } })
|
|
85
|
+
.sort({ _id: 1 })
|
|
86
|
+
.set({ id_total: [["$_id", "$total"]] })
|
|
87
|
+
.group({ _id: null, pairs: { $mergeObjects: { $arrayToObject: "$id_total" } } })
|
|
88
|
+
.aggregate()
|
|
89
|
+
.map((e: any) => e.pairs)
|
|
90
|
+
.next(),
|
|
91
|
+
"Total Merged (not on Registry)": $pipeline(CNRepos)
|
|
92
|
+
.unwind("$crPulls.data")
|
|
93
|
+
.match({ cr: { $exists: false }, "crPulls.data.pull.prState": "merged" })
|
|
94
|
+
.group({ _id: "$crPulls.data.type", total: { $sum: 1 } })
|
|
95
|
+
.sort({ _id: 1 })
|
|
96
|
+
.set({ id_total: [["$_id", "$total"]] })
|
|
97
|
+
.group({ _id: null, pairs: { $mergeObjects: { $arrayToObject: "$id_total" } } })
|
|
98
|
+
.aggregate()
|
|
99
|
+
.map((e: any) => e.pairs)
|
|
100
|
+
.next(),
|
|
101
|
+
"Total Closed": $pipeline(CNRepos)
|
|
102
|
+
.unwind("$crPulls.data")
|
|
103
|
+
.match({ "crPulls.data.pull.prState": "closed" })
|
|
104
|
+
.group({ _id: "$crPulls.data.type", total: { $sum: 1 } })
|
|
105
|
+
.sort({ _id: 1 })
|
|
106
|
+
.set({ id_total: [["$_id", "$total"]] })
|
|
107
|
+
.group({ _id: null, pairs: { $mergeObjects: { $arrayToObject: "$id_total" } } })
|
|
108
|
+
.aggregate()
|
|
109
|
+
.map((e: any) => e.pairs)
|
|
110
|
+
.next(),
|
|
111
|
+
|
|
112
|
+
// // Follow Rules
|
|
113
|
+
// "Follow Up Rules": (async function () {
|
|
114
|
+
// return TaskDataOrNull(await showFollowRuleSet({ name: "default" }));
|
|
115
|
+
// })(),
|
|
116
|
+
});
|
|
117
|
+
return totals;
|
|
118
|
+
}
|