@useairfoil/producer-github 0.0.0-stage → 0.0.2
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 +115 -2
- package/dist/index.d.mts +1939 -0
- package/dist/index.mjs +3 -0
- package/dist/main.d.mts +1 -0
- package/dist/main.mjs +698 -0
- package/dist/main.mjs.map +1 -0
- package/dist/manifest.d.mts +56 -0
- package/dist/manifest.mjs +137 -0
- package/dist/manifest.mjs.map +1 -0
- package/dist/rolldown-runtime-D7D4PA-g.mjs +13 -0
- package/dist/src-D6cTmVtF.mjs +1566 -0
- package/dist/src-D6cTmVtF.mjs.map +1 -0
- package/package.json +48 -4
- package/src/client/auth.ts +113 -0
- package/src/client/client.ts +192 -0
- package/src/client/constants.ts +4 -0
- package/src/connector.ts +97 -0
- package/src/create-table.ts +5 -0
- package/src/demo/changes.ts +420 -0
- package/src/demo/index.ts +59 -0
- package/src/demo/setup.ts +34 -0
- package/src/demo/shared.ts +101 -0
- package/src/index.ts +13 -0
- package/src/main.ts +22 -0
- package/src/manifest.ts +45 -0
- package/src/resources/check-runs.ts +72 -0
- package/src/resources/commit-statuses.ts +84 -0
- package/src/resources/commits.ts +101 -0
- package/src/resources/issue-comments.ts +75 -0
- package/src/resources/issues.ts +78 -0
- package/src/resources/pull-request-commits.ts +91 -0
- package/src/resources/pull-request-review-comments.ts +78 -0
- package/src/resources/pull-request-reviews.ts +76 -0
- package/src/resources/pull-requests.ts +79 -0
- package/src/resources/releases.ts +74 -0
- package/src/resources/repositories.ts +101 -0
- package/src/resources/shared.ts +480 -0
- package/src/resources/workflow-jobs.ts +73 -0
- package/src/resources/workflow-runs.ts +70 -0
- package/src/sandbox.ts +35 -0
- package/src/schemas/check-runs.ts +48 -0
- package/src/schemas/commit-statuses.ts +31 -0
- package/src/schemas/commits.ts +64 -0
- package/src/schemas/events.ts +139 -0
- package/src/schemas/issue-comments.ts +38 -0
- package/src/schemas/issues.ts +62 -0
- package/src/schemas/pull-request-commits.ts +28 -0
- package/src/schemas/pull-request-review-comments.ts +67 -0
- package/src/schemas/pull-request-reviews.ts +37 -0
- package/src/schemas/pull-requests.ts +75 -0
- package/src/schemas/releases.ts +53 -0
- package/src/schemas/repositories.ts +53 -0
- package/src/schemas/shared.ts +86 -0
- package/src/schemas/workflow-jobs.ts +54 -0
- package/src/schemas/workflow-runs.ts +55 -0
- package/src/start.ts +47 -0
- package/src/tables.ts +31 -0
- package/src/webhook/route.ts +46 -0
- package/src/webhook/signature.ts +20 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { C as auth_exports, S as client_exports, _ as IssueObjectSchema, b as IssueCommentSchema, d as RepositoryObjectSchema, f as RepositorySchema, h as PullRequestSchema, i as webhookPath, m as PullRequestObjectSchema, n as connector_exports, v as IssueSchema, y as IssueCommentObjectSchema } from "./src-D6cTmVtF.mjs";
|
|
2
|
+
import { manifest } from "./manifest.mjs";
|
|
3
|
+
export { auth_exports as GitHubAuth, client_exports as GitHubClient, connector_exports as GitHubConnector, IssueCommentObjectSchema, IssueCommentSchema, IssueObjectSchema, IssueSchema, PullRequestObjectSchema, PullRequestSchema, RepositoryObjectSchema, RepositorySchema, manifest, webhookPath };
|
package/dist/main.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|
package/dist/main.mjs
ADDED
|
@@ -0,0 +1,698 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { a as WorkflowJobSchema, b as IssueCommentSchema, c as CommitStatusSchema, f as RepositorySchema, g as PullRequestReviewCommentSchema, h as PullRequestSchema, l as CommitSchema, o as PullRequestReviewSchema, p as ReleaseSchema, r as layerConfig, s as PullRequestCommitSchema, t as GitHubConnector, u as WorkflowRunSchema, v as IssueSchema, x as CheckRunSchema } from "./src-D6cTmVtF.mjs";
|
|
3
|
+
import { GitHubConfigDef } from "./manifest.mjs";
|
|
4
|
+
import { ConnectorApp, Demo, Ingestor, RuntimeConfig, StateStore, Telemetry } from "@useairfoil/connector-kit";
|
|
5
|
+
import { Config, Duration, Effect, Layer, Logger, Schema } from "effect";
|
|
6
|
+
import { FetchHttpClient } from "effect/http";
|
|
7
|
+
import { NodeRuntime, NodeServices } from "@effect/platform-node";
|
|
8
|
+
import { Command } from "effect/cli";
|
|
9
|
+
import { PgClient } from "@effect/sql-pg";
|
|
10
|
+
//#region package.json
|
|
11
|
+
var version = "0.0.1";
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region src/tables.ts
|
|
14
|
+
const tableSchemas = {
|
|
15
|
+
repositories: RepositorySchema,
|
|
16
|
+
issues: IssueSchema,
|
|
17
|
+
pull_requests: PullRequestSchema,
|
|
18
|
+
issue_comments: IssueCommentSchema,
|
|
19
|
+
pull_request_reviews: PullRequestReviewSchema,
|
|
20
|
+
pull_request_review_comments: PullRequestReviewCommentSchema,
|
|
21
|
+
pull_request_commits: PullRequestCommitSchema,
|
|
22
|
+
commits: CommitSchema,
|
|
23
|
+
check_runs: CheckRunSchema,
|
|
24
|
+
commit_statuses: CommitStatusSchema,
|
|
25
|
+
workflow_runs: WorkflowRunSchema,
|
|
26
|
+
workflow_jobs: WorkflowJobSchema,
|
|
27
|
+
releases: ReleaseSchema
|
|
28
|
+
};
|
|
29
|
+
//#endregion
|
|
30
|
+
//#region src/create-table.ts
|
|
31
|
+
const createTableCommand = ConnectorApp.makeCreateTableCommand(tableSchemas);
|
|
32
|
+
//#endregion
|
|
33
|
+
//#region src/demo/shared.ts
|
|
34
|
+
const day = Duration.toMillis(Duration.days(1));
|
|
35
|
+
const minute = Duration.toMillis(Duration.minutes(1));
|
|
36
|
+
const org = "acme-labs";
|
|
37
|
+
const owner = {
|
|
38
|
+
id: 91000000n,
|
|
39
|
+
login: org,
|
|
40
|
+
type: "Organization"
|
|
41
|
+
};
|
|
42
|
+
const people = [
|
|
43
|
+
"mara-ellis",
|
|
44
|
+
"dkowalski",
|
|
45
|
+
"jin-park",
|
|
46
|
+
"sofia-rojas",
|
|
47
|
+
"tbrennan",
|
|
48
|
+
"amir-haddad",
|
|
49
|
+
"lucy-chen",
|
|
50
|
+
"oscar-mendez",
|
|
51
|
+
"priya-nair",
|
|
52
|
+
"felix-weber",
|
|
53
|
+
"nadia-kova",
|
|
54
|
+
"ben-ortiz"
|
|
55
|
+
].map((login, k) => ({
|
|
56
|
+
id: BigInt(5e7 + k),
|
|
57
|
+
login,
|
|
58
|
+
type: "User"
|
|
59
|
+
}));
|
|
60
|
+
const actionsBot = {
|
|
61
|
+
id: 41898282n,
|
|
62
|
+
login: "github-actions[bot]",
|
|
63
|
+
type: "Bot"
|
|
64
|
+
};
|
|
65
|
+
const repositories = [
|
|
66
|
+
{
|
|
67
|
+
name: "api",
|
|
68
|
+
language: "Go",
|
|
69
|
+
topics: ["api", "backend"],
|
|
70
|
+
description: "Public REST API"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: "web",
|
|
74
|
+
language: "TypeScript",
|
|
75
|
+
topics: ["frontend", "react"],
|
|
76
|
+
description: "Web app"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
name: "mobile",
|
|
80
|
+
language: "Kotlin",
|
|
81
|
+
topics: ["android"],
|
|
82
|
+
description: "Android app"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
name: "infra",
|
|
86
|
+
language: "HCL",
|
|
87
|
+
topics: ["terraform"],
|
|
88
|
+
description: "Cloud infrastructure"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: "docs",
|
|
92
|
+
language: "MDX",
|
|
93
|
+
topics: ["documentation"],
|
|
94
|
+
description: "Product docs"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: "sdk-js",
|
|
98
|
+
language: "TypeScript",
|
|
99
|
+
topics: ["sdk"],
|
|
100
|
+
description: "JavaScript SDK"
|
|
101
|
+
}
|
|
102
|
+
];
|
|
103
|
+
const repositoryId = (r) => BigInt(7e8 + r);
|
|
104
|
+
const labels = [
|
|
105
|
+
{
|
|
106
|
+
id: 6100000001n,
|
|
107
|
+
name: "bug"
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
id: 6100000002n,
|
|
111
|
+
name: "enhancement"
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
id: 6100000003n,
|
|
115
|
+
name: "documentation"
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
id: 6100000004n,
|
|
119
|
+
name: "good first issue"
|
|
120
|
+
}
|
|
121
|
+
];
|
|
122
|
+
const verbs = [
|
|
123
|
+
"Fix",
|
|
124
|
+
"Add",
|
|
125
|
+
"Improve",
|
|
126
|
+
"Update",
|
|
127
|
+
"Remove",
|
|
128
|
+
"Refactor",
|
|
129
|
+
"Support"
|
|
130
|
+
];
|
|
131
|
+
const paths = [
|
|
132
|
+
"src/server.ts",
|
|
133
|
+
"src/client.ts",
|
|
134
|
+
"src/routes/users.ts",
|
|
135
|
+
"src/lib/cache.ts",
|
|
136
|
+
"README.md"
|
|
137
|
+
];
|
|
138
|
+
const nodeId = (prefix, id) => `${prefix}_kwDO${id.toString(16).toUpperCase()}`;
|
|
139
|
+
const urlOf = (repo) => `https://github.com/${org}/${repo.name}`;
|
|
140
|
+
/** Date helpers for one run. `at` keeps a time from going past now. */
|
|
141
|
+
const clock = ({ faker, now }) => {
|
|
142
|
+
const at = (time) => new Date(Math.min(time, now.getTime()));
|
|
143
|
+
const later = (from, min, max) => at(from.getTime() + faker.number.int({
|
|
144
|
+
min,
|
|
145
|
+
max
|
|
146
|
+
}));
|
|
147
|
+
return {
|
|
148
|
+
at,
|
|
149
|
+
later
|
|
150
|
+
};
|
|
151
|
+
};
|
|
152
|
+
//#endregion
|
|
153
|
+
//#region src/demo/changes.ts
|
|
154
|
+
/**
|
|
155
|
+
* One group is one change in a repository: an issue, the pull request that
|
|
156
|
+
* fixes it, and its CI.
|
|
157
|
+
*/
|
|
158
|
+
const changeRows = (index, context) => {
|
|
159
|
+
const { faker, now } = context;
|
|
160
|
+
const { at, later } = clock(context);
|
|
161
|
+
const rows = {
|
|
162
|
+
issues: [],
|
|
163
|
+
pull_requests: [],
|
|
164
|
+
issue_comments: [],
|
|
165
|
+
pull_request_reviews: [],
|
|
166
|
+
pull_request_review_comments: [],
|
|
167
|
+
pull_request_commits: [],
|
|
168
|
+
commits: [],
|
|
169
|
+
check_runs: [],
|
|
170
|
+
commit_statuses: [],
|
|
171
|
+
workflow_runs: [],
|
|
172
|
+
workflow_jobs: [],
|
|
173
|
+
releases: []
|
|
174
|
+
};
|
|
175
|
+
const r = index % repositories.length;
|
|
176
|
+
const repo = repositories[r] ?? repositories[0];
|
|
177
|
+
const repoId = repositoryId(r);
|
|
178
|
+
const round = Math.floor(index / repositories.length);
|
|
179
|
+
const issueNumber = BigInt(round * 2 + 1);
|
|
180
|
+
const prNumber = BigInt(round * 2 + 2);
|
|
181
|
+
const id = BigInt(index);
|
|
182
|
+
const author = faker.helpers.arrayElement(people);
|
|
183
|
+
const reviewer = faker.helpers.arrayElement(people.filter((person) => person !== author));
|
|
184
|
+
const association = (account) => account.type === "Bot" ? "NONE" : "MEMBER";
|
|
185
|
+
const title = `${faker.helpers.arrayElement(verbs)} ${faker.hacker.adjective()} ${faker.hacker.noun()} handling`;
|
|
186
|
+
const label = faker.helpers.arrayElement(labels);
|
|
187
|
+
const opened = at(now.getTime() - faker.number.int({
|
|
188
|
+
min: day,
|
|
189
|
+
max: 600 * day
|
|
190
|
+
}));
|
|
191
|
+
const comment = (issueNumber, n, created) => {
|
|
192
|
+
const commentId = 1800000000n + id * 10n + BigInt(n);
|
|
193
|
+
const user = faker.helpers.arrayElement(people);
|
|
194
|
+
return {
|
|
195
|
+
id: commentId,
|
|
196
|
+
version: created,
|
|
197
|
+
node_id: nodeId("IC", commentId),
|
|
198
|
+
repository_id: repoId,
|
|
199
|
+
issue_number: issueNumber,
|
|
200
|
+
user,
|
|
201
|
+
author_association: association(user),
|
|
202
|
+
body: faker.helpers.arrayElement([
|
|
203
|
+
"I can reproduce this on the latest release.",
|
|
204
|
+
"Thanks for the report. Looking into it.",
|
|
205
|
+
"This should be fixed once the pull request lands.",
|
|
206
|
+
"Can we add a test for this case?",
|
|
207
|
+
"LGTM, thanks!"
|
|
208
|
+
]),
|
|
209
|
+
created_at: created,
|
|
210
|
+
html_url: `${urlOf(repo)}/issues/${issueNumber}#issuecomment-${commentId}`
|
|
211
|
+
};
|
|
212
|
+
};
|
|
213
|
+
const fixed = faker.datatype.boolean({ probability: .75 });
|
|
214
|
+
const issueComments = Array.from({ length: faker.number.int({ max: 3 }) }, (_, n) => comment(issueNumber, n, later(opened, minute, 5 * day)));
|
|
215
|
+
rows.issue_comments.push(...issueComments);
|
|
216
|
+
const branch = `${author.login.split("-")[0]}/${title.toLowerCase().split(" ").slice(1, 3).join("-")}`;
|
|
217
|
+
const prOpened = later(opened, 60 * minute, 7 * day);
|
|
218
|
+
const prState = faker.helpers.weightedArrayElement([
|
|
219
|
+
{
|
|
220
|
+
weight: 70,
|
|
221
|
+
value: "merged"
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
weight: 10,
|
|
225
|
+
value: "closed"
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
weight: 20,
|
|
229
|
+
value: "open"
|
|
230
|
+
}
|
|
231
|
+
]);
|
|
232
|
+
const baseSha = faker.git.commitSha();
|
|
233
|
+
let committed = prOpened;
|
|
234
|
+
const shas = Array.from({ length: faker.number.int({
|
|
235
|
+
min: 1,
|
|
236
|
+
max: 4
|
|
237
|
+
}) }, (_, n) => {
|
|
238
|
+
committed = later(committed, 10 * minute, day);
|
|
239
|
+
return {
|
|
240
|
+
sha: faker.git.commitSha(),
|
|
241
|
+
message: n === 0 ? title : faker.git.commitMessage(),
|
|
242
|
+
at: committed
|
|
243
|
+
};
|
|
244
|
+
});
|
|
245
|
+
const headSha = shas.at(-1)?.sha ?? baseSha;
|
|
246
|
+
const reviewed = later(committed, 30 * minute, 2 * day);
|
|
247
|
+
const closedAt = prState === "open" ? null : later(reviewed, 10 * minute, day);
|
|
248
|
+
const mergedAt = prState === "merged" ? closedAt : null;
|
|
249
|
+
const prComments = Array.from({ length: faker.number.int({ max: 2 }) }, (_, n) => comment(prNumber, 5 + n, later(prOpened, minute, 2 * day)));
|
|
250
|
+
rows.issue_comments.push(...prComments);
|
|
251
|
+
const prUpdated = new Date(Math.max(closedAt?.getTime() ?? 0, reviewed.getTime(), ...prComments.map((row) => row.created_at.getTime())));
|
|
252
|
+
const prId = 1500000000n + id;
|
|
253
|
+
rows.pull_requests.push({
|
|
254
|
+
id: prId,
|
|
255
|
+
version: prUpdated,
|
|
256
|
+
node_id: nodeId("PR", prId),
|
|
257
|
+
repository_id: repoId,
|
|
258
|
+
number: prNumber,
|
|
259
|
+
title,
|
|
260
|
+
body: `Fixes #${issueNumber}.\n\n${faker.hacker.phrase()}`,
|
|
261
|
+
state: prState === "open" ? "open" : "closed",
|
|
262
|
+
draft: prState === "open" && faker.datatype.boolean({ probability: .2 }),
|
|
263
|
+
locked: false,
|
|
264
|
+
user: author,
|
|
265
|
+
author_association: "MEMBER",
|
|
266
|
+
labels: [label],
|
|
267
|
+
assignees: [author],
|
|
268
|
+
requested_reviewers: prState === "open" ? [reviewer] : [],
|
|
269
|
+
milestone: null,
|
|
270
|
+
head: {
|
|
271
|
+
ref: branch,
|
|
272
|
+
sha: headSha,
|
|
273
|
+
label: `${org}:${branch}`
|
|
274
|
+
},
|
|
275
|
+
base: {
|
|
276
|
+
ref: "main",
|
|
277
|
+
sha: baseSha,
|
|
278
|
+
label: `${org}:main`
|
|
279
|
+
},
|
|
280
|
+
created_at: prOpened,
|
|
281
|
+
closed_at: closedAt,
|
|
282
|
+
merged_at: mergedAt,
|
|
283
|
+
html_url: `${urlOf(repo)}/pull/${prNumber}`
|
|
284
|
+
});
|
|
285
|
+
for (const commit of shas) rows.pull_request_commits.push({
|
|
286
|
+
key: `${repoId}:${prNumber}:${commit.sha}`,
|
|
287
|
+
version: prUpdated,
|
|
288
|
+
repository_id: repoId,
|
|
289
|
+
pull_request_number: prNumber,
|
|
290
|
+
sha: commit.sha,
|
|
291
|
+
message: commit.message,
|
|
292
|
+
author: {
|
|
293
|
+
name: author.login,
|
|
294
|
+
date: commit.at
|
|
295
|
+
},
|
|
296
|
+
committer: {
|
|
297
|
+
name: author.login,
|
|
298
|
+
date: commit.at
|
|
299
|
+
},
|
|
300
|
+
author_user: author,
|
|
301
|
+
committer_user: author,
|
|
302
|
+
html_url: `${urlOf(repo)}/commit/${commit.sha}`
|
|
303
|
+
});
|
|
304
|
+
const reviewState = faker.helpers.weightedArrayElement([
|
|
305
|
+
{
|
|
306
|
+
weight: 70,
|
|
307
|
+
value: "APPROVED"
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
weight: 20,
|
|
311
|
+
value: "CHANGES_REQUESTED"
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
weight: 10,
|
|
315
|
+
value: "COMMENTED"
|
|
316
|
+
}
|
|
317
|
+
]);
|
|
318
|
+
if (prState !== "open" || faker.datatype.boolean({ probability: .5 })) {
|
|
319
|
+
const reviewId = 2400000000n + id;
|
|
320
|
+
rows.pull_request_reviews.push({
|
|
321
|
+
id: reviewId,
|
|
322
|
+
version: now,
|
|
323
|
+
node_id: nodeId("PRR", reviewId),
|
|
324
|
+
repository_id: repoId,
|
|
325
|
+
pull_request_number: prNumber,
|
|
326
|
+
user: reviewer,
|
|
327
|
+
author_association: "MEMBER",
|
|
328
|
+
state: reviewState,
|
|
329
|
+
body: reviewState === "APPROVED" ? "" : "A few small things before this lands.",
|
|
330
|
+
commit_id: headSha,
|
|
331
|
+
submitted_at: reviewed,
|
|
332
|
+
html_url: `${urlOf(repo)}/pull/${prNumber}#pullrequestreview-${reviewId}`
|
|
333
|
+
});
|
|
334
|
+
if (reviewState !== "APPROVED") {
|
|
335
|
+
const line = BigInt(faker.number.int({
|
|
336
|
+
min: 5,
|
|
337
|
+
max: 200
|
|
338
|
+
}));
|
|
339
|
+
const reviewCommentId = 2900000000n + id;
|
|
340
|
+
rows.pull_request_review_comments.push({
|
|
341
|
+
id: reviewCommentId,
|
|
342
|
+
version: reviewed,
|
|
343
|
+
node_id: nodeId("PRRC", reviewCommentId),
|
|
344
|
+
repository_id: repoId,
|
|
345
|
+
pull_request_number: prNumber,
|
|
346
|
+
pull_request_review_id: reviewId,
|
|
347
|
+
user: reviewer,
|
|
348
|
+
author_association: "MEMBER",
|
|
349
|
+
body: faker.helpers.arrayElement([
|
|
350
|
+
"Could this return early instead?",
|
|
351
|
+
"Nit: this name is a bit unclear.",
|
|
352
|
+
"We should handle the error here."
|
|
353
|
+
]),
|
|
354
|
+
path: faker.helpers.arrayElement(paths),
|
|
355
|
+
commit_id: headSha,
|
|
356
|
+
original_commit_id: headSha,
|
|
357
|
+
diff_hunk: `@@ -${line},6 +${line},8 @@`,
|
|
358
|
+
line,
|
|
359
|
+
original_line: line,
|
|
360
|
+
start_line: null,
|
|
361
|
+
side: "RIGHT",
|
|
362
|
+
subject_type: "line",
|
|
363
|
+
created_at: reviewed,
|
|
364
|
+
html_url: `${urlOf(repo)}/pull/${prNumber}#discussion_r${reviewCommentId}`
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
const ciPassed = faker.datatype.boolean({ probability: .85 });
|
|
369
|
+
const runId = 9000000000n + id;
|
|
370
|
+
const runStarted = later(committed, 1e4, minute);
|
|
371
|
+
const workflowId = 60000000n + BigInt(r);
|
|
372
|
+
rows.workflow_runs.push({
|
|
373
|
+
id: runId,
|
|
374
|
+
version: later(runStarted, 2 * minute, 15 * minute),
|
|
375
|
+
node_id: nodeId("WFR", runId),
|
|
376
|
+
repository_id: repoId,
|
|
377
|
+
workflow_id: workflowId,
|
|
378
|
+
name: "CI",
|
|
379
|
+
display_title: title,
|
|
380
|
+
path: ".github/workflows/ci.yml",
|
|
381
|
+
event: "pull_request",
|
|
382
|
+
status: "completed",
|
|
383
|
+
conclusion: ciPassed ? "success" : "failure",
|
|
384
|
+
head_branch: branch,
|
|
385
|
+
head_sha: headSha,
|
|
386
|
+
run_number: BigInt(round + 1),
|
|
387
|
+
run_attempt: 1n,
|
|
388
|
+
check_suite_id: 30000000000n + id,
|
|
389
|
+
actor: author,
|
|
390
|
+
triggering_actor: author,
|
|
391
|
+
pull_requests: [{
|
|
392
|
+
id: prId,
|
|
393
|
+
number: prNumber
|
|
394
|
+
}],
|
|
395
|
+
created_at: runStarted,
|
|
396
|
+
run_started_at: runStarted,
|
|
397
|
+
html_url: `${urlOf(repo)}/actions/runs/${runId}`
|
|
398
|
+
});
|
|
399
|
+
["build", "test"].forEach((name, j) => {
|
|
400
|
+
const jobId = 25000000000n + id * 2n + BigInt(j);
|
|
401
|
+
const started = later(runStarted, 5e3, minute);
|
|
402
|
+
const completed = later(started, minute, 10 * minute);
|
|
403
|
+
const conclusion = ciPassed || name === "build" ? "success" : "failure";
|
|
404
|
+
rows.workflow_jobs.push({
|
|
405
|
+
id: jobId,
|
|
406
|
+
version: now,
|
|
407
|
+
node_id: nodeId("CR", jobId),
|
|
408
|
+
repository_id: repoId,
|
|
409
|
+
run_id: runId,
|
|
410
|
+
run_attempt: 1n,
|
|
411
|
+
workflow_name: "CI",
|
|
412
|
+
name,
|
|
413
|
+
head_sha: headSha,
|
|
414
|
+
head_branch: branch,
|
|
415
|
+
status: "completed",
|
|
416
|
+
conclusion,
|
|
417
|
+
created_at: runStarted,
|
|
418
|
+
started_at: started,
|
|
419
|
+
completed_at: completed,
|
|
420
|
+
runner_name: `GitHub Actions ${faker.number.int({
|
|
421
|
+
min: 1,
|
|
422
|
+
max: 99
|
|
423
|
+
})}`,
|
|
424
|
+
labels: ["ubuntu-latest"],
|
|
425
|
+
steps: [
|
|
426
|
+
"Set up job",
|
|
427
|
+
"Checkout",
|
|
428
|
+
`Run ${name}`,
|
|
429
|
+
"Complete job"
|
|
430
|
+
].map((step, s) => ({
|
|
431
|
+
number: BigInt(s + 1),
|
|
432
|
+
name: step,
|
|
433
|
+
status: "completed",
|
|
434
|
+
conclusion: s === 2 ? conclusion : "success",
|
|
435
|
+
started_at: started,
|
|
436
|
+
completed_at: completed
|
|
437
|
+
})),
|
|
438
|
+
html_url: `${urlOf(repo)}/actions/runs/${runId}/job/${jobId}`
|
|
439
|
+
});
|
|
440
|
+
rows.check_runs.push({
|
|
441
|
+
id: jobId,
|
|
442
|
+
version: now,
|
|
443
|
+
node_id: nodeId("CR", jobId),
|
|
444
|
+
repository_id: repoId,
|
|
445
|
+
head_sha: headSha,
|
|
446
|
+
name,
|
|
447
|
+
status: "completed",
|
|
448
|
+
conclusion,
|
|
449
|
+
started_at: started,
|
|
450
|
+
completed_at: completed,
|
|
451
|
+
app: {
|
|
452
|
+
id: 15368n,
|
|
453
|
+
name: "GitHub Actions"
|
|
454
|
+
},
|
|
455
|
+
check_suite: { id: 30000000000n + id },
|
|
456
|
+
output: {
|
|
457
|
+
title: null,
|
|
458
|
+
summary: null
|
|
459
|
+
},
|
|
460
|
+
external_id: null,
|
|
461
|
+
details_url: `${urlOf(repo)}/actions/runs/${runId}/job/${jobId}`,
|
|
462
|
+
html_url: `${urlOf(repo)}/actions/runs/${runId}/job/${jobId}`
|
|
463
|
+
});
|
|
464
|
+
});
|
|
465
|
+
if (mergedAt) {
|
|
466
|
+
const sha = faker.git.commitSha();
|
|
467
|
+
rows.commits.push({
|
|
468
|
+
key: `${repoId}:${sha}`,
|
|
469
|
+
version: mergedAt,
|
|
470
|
+
repository_id: repoId,
|
|
471
|
+
sha,
|
|
472
|
+
node_id: nodeId("C", 3000000000n + id),
|
|
473
|
+
message: `${title} (#${prNumber})`,
|
|
474
|
+
author: {
|
|
475
|
+
name: author.login,
|
|
476
|
+
date: mergedAt
|
|
477
|
+
},
|
|
478
|
+
committer: {
|
|
479
|
+
name: "GitHub",
|
|
480
|
+
date: mergedAt
|
|
481
|
+
},
|
|
482
|
+
author_user: author,
|
|
483
|
+
committer_user: {
|
|
484
|
+
id: 19864447n,
|
|
485
|
+
login: "web-flow",
|
|
486
|
+
type: "User"
|
|
487
|
+
},
|
|
488
|
+
parents: [baseSha],
|
|
489
|
+
verified: true,
|
|
490
|
+
html_url: `${urlOf(repo)}/commit/${sha}`
|
|
491
|
+
});
|
|
492
|
+
const statusId = 3500000000n + id;
|
|
493
|
+
const deployed = faker.datatype.boolean({ probability: .95 });
|
|
494
|
+
rows.commit_statuses.push({
|
|
495
|
+
id: statusId,
|
|
496
|
+
version: later(mergedAt, minute, 10 * minute),
|
|
497
|
+
node_id: nodeId("SC", statusId),
|
|
498
|
+
repository_id: repoId,
|
|
499
|
+
sha,
|
|
500
|
+
state: deployed ? "success" : "failure",
|
|
501
|
+
context: "deploy/production",
|
|
502
|
+
description: deployed ? "Deployed to production" : "Deploy failed",
|
|
503
|
+
target_url: `https://deploy.example.com/${repo.name}/${sha.slice(0, 7)}`,
|
|
504
|
+
creator: actionsBot,
|
|
505
|
+
created_at: later(mergedAt, minute, 10 * minute)
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
const issueClosed = fixed && mergedAt ? mergedAt : null;
|
|
509
|
+
const issueId = 1200000000n + id;
|
|
510
|
+
rows.issues.push({
|
|
511
|
+
id: issueId,
|
|
512
|
+
version: new Date(Math.max(opened.getTime(), issueClosed?.getTime() ?? 0, ...issueComments.map((row) => row.created_at.getTime()))),
|
|
513
|
+
node_id: nodeId("I", issueId),
|
|
514
|
+
repository_id: repoId,
|
|
515
|
+
number: issueNumber,
|
|
516
|
+
title,
|
|
517
|
+
body: `${faker.hacker.phrase()}\n\nSteps to reproduce are in the thread.`,
|
|
518
|
+
state: issueClosed ? "closed" : "open",
|
|
519
|
+
state_reason: issueClosed ? "completed" : null,
|
|
520
|
+
locked: false,
|
|
521
|
+
user: faker.helpers.arrayElement(people),
|
|
522
|
+
author_association: "MEMBER",
|
|
523
|
+
labels: [label],
|
|
524
|
+
assignees: [author],
|
|
525
|
+
milestone: null,
|
|
526
|
+
comments: BigInt(issueComments.length),
|
|
527
|
+
created_at: opened,
|
|
528
|
+
closed_at: issueClosed,
|
|
529
|
+
html_url: `${urlOf(repo)}/issues/${issueNumber}`
|
|
530
|
+
});
|
|
531
|
+
if (round % 5 === 4 && mergedAt) {
|
|
532
|
+
const releaseId = 4000000000n + id;
|
|
533
|
+
const tag = `v1.${Math.floor(round / 5)}.0`;
|
|
534
|
+
rows.releases.push({
|
|
535
|
+
id: releaseId,
|
|
536
|
+
version: mergedAt,
|
|
537
|
+
node_id: nodeId("RE", releaseId),
|
|
538
|
+
repository_id: repoId,
|
|
539
|
+
tag_name: tag,
|
|
540
|
+
target_commitish: "main",
|
|
541
|
+
name: tag,
|
|
542
|
+
body: `## What's changed\n\n- ${title} (#${prNumber})`,
|
|
543
|
+
draft: false,
|
|
544
|
+
prerelease: false,
|
|
545
|
+
author,
|
|
546
|
+
assets: [],
|
|
547
|
+
created_at: mergedAt,
|
|
548
|
+
published_at: mergedAt,
|
|
549
|
+
html_url: `${urlOf(repo)}/releases/tag/${tag}`
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
return rows;
|
|
553
|
+
};
|
|
554
|
+
//#endregion
|
|
555
|
+
//#region src/demo/setup.ts
|
|
556
|
+
/** The repositories, written once before any change. */
|
|
557
|
+
const setupRows = ({ now }) => {
|
|
558
|
+
const created = /* @__PURE__ */ new Date(now.getTime() - 900 * day);
|
|
559
|
+
return { repositories: repositories.map((repo, r) => ({
|
|
560
|
+
id: repositoryId(r),
|
|
561
|
+
version: now,
|
|
562
|
+
node_id: nodeId("R", repositoryId(r)),
|
|
563
|
+
name: repo.name,
|
|
564
|
+
full_name: `${org}/${repo.name}`,
|
|
565
|
+
owner,
|
|
566
|
+
private: repo.name !== "sdk-js" && repo.name !== "docs",
|
|
567
|
+
visibility: repo.name === "sdk-js" || repo.name === "docs" ? "public" : "private",
|
|
568
|
+
description: repo.description,
|
|
569
|
+
fork: false,
|
|
570
|
+
archived: false,
|
|
571
|
+
disabled: false,
|
|
572
|
+
default_branch: "main",
|
|
573
|
+
language: repo.language,
|
|
574
|
+
topics: [...repo.topics],
|
|
575
|
+
html_url: urlOf(repo),
|
|
576
|
+
created_at: new Date(created.getTime() + r * 30 * day),
|
|
577
|
+
_deleted: false
|
|
578
|
+
})) };
|
|
579
|
+
};
|
|
580
|
+
//#endregion
|
|
581
|
+
//#region src/demo/index.ts
|
|
582
|
+
const demo = Demo.define({
|
|
583
|
+
name: "producer-github",
|
|
584
|
+
setup: {
|
|
585
|
+
tables: [Demo.table({
|
|
586
|
+
name: "repositories",
|
|
587
|
+
rowSchema: RepositorySchema,
|
|
588
|
+
version: "version"
|
|
589
|
+
})],
|
|
590
|
+
rows: setupRows
|
|
591
|
+
},
|
|
592
|
+
group: {
|
|
593
|
+
tables: [
|
|
594
|
+
Demo.table({
|
|
595
|
+
name: "issues",
|
|
596
|
+
rowSchema: IssueSchema,
|
|
597
|
+
version: "version"
|
|
598
|
+
}),
|
|
599
|
+
Demo.table({
|
|
600
|
+
name: "pull_requests",
|
|
601
|
+
rowSchema: PullRequestSchema,
|
|
602
|
+
version: "version"
|
|
603
|
+
}),
|
|
604
|
+
Demo.table({
|
|
605
|
+
name: "issue_comments",
|
|
606
|
+
rowSchema: IssueCommentSchema,
|
|
607
|
+
version: "version"
|
|
608
|
+
}),
|
|
609
|
+
Demo.table({
|
|
610
|
+
name: "pull_request_reviews",
|
|
611
|
+
rowSchema: PullRequestReviewSchema,
|
|
612
|
+
version: "version"
|
|
613
|
+
}),
|
|
614
|
+
Demo.table({
|
|
615
|
+
name: "pull_request_review_comments",
|
|
616
|
+
rowSchema: PullRequestReviewCommentSchema,
|
|
617
|
+
version: "version"
|
|
618
|
+
}),
|
|
619
|
+
Demo.table({
|
|
620
|
+
name: "pull_request_commits",
|
|
621
|
+
rowSchema: PullRequestCommitSchema,
|
|
622
|
+
version: "version"
|
|
623
|
+
}),
|
|
624
|
+
Demo.table({
|
|
625
|
+
name: "commits",
|
|
626
|
+
rowSchema: CommitSchema,
|
|
627
|
+
version: "version"
|
|
628
|
+
}),
|
|
629
|
+
Demo.table({
|
|
630
|
+
name: "check_runs",
|
|
631
|
+
rowSchema: CheckRunSchema,
|
|
632
|
+
version: "version"
|
|
633
|
+
}),
|
|
634
|
+
Demo.table({
|
|
635
|
+
name: "commit_statuses",
|
|
636
|
+
rowSchema: CommitStatusSchema,
|
|
637
|
+
version: "version"
|
|
638
|
+
}),
|
|
639
|
+
Demo.table({
|
|
640
|
+
name: "workflow_runs",
|
|
641
|
+
rowSchema: WorkflowRunSchema,
|
|
642
|
+
version: "version"
|
|
643
|
+
}),
|
|
644
|
+
Demo.table({
|
|
645
|
+
name: "workflow_jobs",
|
|
646
|
+
rowSchema: WorkflowJobSchema,
|
|
647
|
+
version: "version"
|
|
648
|
+
}),
|
|
649
|
+
Demo.table({
|
|
650
|
+
name: "releases",
|
|
651
|
+
rowSchema: ReleaseSchema,
|
|
652
|
+
version: "version"
|
|
653
|
+
})
|
|
654
|
+
],
|
|
655
|
+
rows: changeRows
|
|
656
|
+
}
|
|
657
|
+
});
|
|
658
|
+
const demoCommand = ConnectorApp.makeDemoCommand(demo).pipe(Command.provide(RuntimeConfig.layerHosted()));
|
|
659
|
+
//#endregion
|
|
660
|
+
//#region src/sandbox.ts
|
|
661
|
+
const ConnectorLayer$1 = layerConfig(GitHubConfigDef.config);
|
|
662
|
+
const TelemetryLayer$1 = Layer.mergeAll(Telemetry.layerOtlp(), Telemetry.layerMetricsConsoleDump());
|
|
663
|
+
const sandboxCommand = Command.make("sandbox", {}, () => Effect.gen(function* () {
|
|
664
|
+
const port = yield* RuntimeConfig.httpPort;
|
|
665
|
+
const entrypoint = yield* GitHubConnector;
|
|
666
|
+
return yield* ConnectorApp.start(entrypoint, { port });
|
|
667
|
+
}).pipe(Effect.annotateLogs({ component: "github" }), Effect.provide(Layer.mergeAll(StateStore.layerMemory, Ingestor.layerConsole, ConnectorLayer$1, Logger.layer([Logger.consolePretty()]), TelemetryLayer$1)))).pipe(Command.withDescription("Run the connector locally and log ingested data"));
|
|
668
|
+
//#endregion
|
|
669
|
+
//#region src/start.ts
|
|
670
|
+
const ConnectorLayer = layerConfig(GitHubConfigDef.config);
|
|
671
|
+
const TelemetryLayer = Telemetry.layerOtlp();
|
|
672
|
+
const PostgresLayer = PgClient.layerConfig({
|
|
673
|
+
url: Config.schema(Schema.Redacted(Schema.NonEmptyString), RuntimeConfig.PlatformRuntimeKey.postgresConnectionString),
|
|
674
|
+
maxConnections: Config.succeed(2),
|
|
675
|
+
connectTimeout: Config.succeed("5 seconds"),
|
|
676
|
+
applicationName: Config.succeed("airfoil-producer-github")
|
|
677
|
+
});
|
|
678
|
+
const StateStoreLayer = StateStore.layerSql().pipe(Layer.provide(PostgresLayer));
|
|
679
|
+
const startCommand = Command.make("start", {}, () => Effect.gen(function* () {
|
|
680
|
+
const port = yield* RuntimeConfig.httpPort;
|
|
681
|
+
const entrypoint = yield* GitHubConnector;
|
|
682
|
+
return yield* ConnectorApp.start(entrypoint, { port }).pipe(Effect.provide(Ingestor.layerWingsConfig(entrypoint)));
|
|
683
|
+
}).pipe(Effect.annotateLogs({ component: "github" }), Effect.provide(Layer.mergeAll(StateStoreLayer, ConnectorLayer, Logger.layer([Logger.consolePretty()]), TelemetryLayer)), Effect.provide(RuntimeConfig.layerHosted()))).pipe(Command.withDescription("Run the production connector against Wings"));
|
|
684
|
+
//#endregion
|
|
685
|
+
//#region src/main.ts
|
|
686
|
+
const BootstrapLayer = Layer.mergeAll(FetchHttpClient.layer, NodeServices.layer);
|
|
687
|
+
const program = Command.make("producer-github", {}, () => Effect.void).pipe(Command.withSubcommands([
|
|
688
|
+
startCommand,
|
|
689
|
+
sandboxCommand,
|
|
690
|
+
createTableCommand,
|
|
691
|
+
demoCommand
|
|
692
|
+
]));
|
|
693
|
+
const cli = Command.run(program, { version });
|
|
694
|
+
NodeRuntime.runMain(cli.pipe(Effect.provide(BootstrapLayer), Effect.scoped));
|
|
695
|
+
//#endregion
|
|
696
|
+
export {};
|
|
697
|
+
|
|
698
|
+
//# sourceMappingURL=main.mjs.map
|