@sentry/junior-github 0.182.0 → 0.183.0

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.
@@ -821,6 +821,11 @@ function createPermissionCache() {
821
821
  }
822
822
 
823
823
  // src/webhooks/check-suite.ts
824
+ var CHECK_SUITE_PULL_REQUEST_MATCH_KEYS = /* @__PURE__ */ new Set([
825
+ "authorEmail",
826
+ "authorUsername",
827
+ "isDraft"
828
+ ]);
824
829
  function gitHubEventKey(deliveryId, eventType) {
825
830
  return `github:${deliveryId}:${eventType}`;
826
831
  }
@@ -834,7 +839,29 @@ function pullRequestTargets(event, repo) {
834
839
  }
835
840
  ];
836
841
  }
837
- var repositorySchema = z.object({ full_name: z.string().min(1) }).passthrough();
842
+ var checkRunRepoRefSchema = z.object({
843
+ id: z.number(),
844
+ name: z.string().min(1),
845
+ url: z.string().min(1)
846
+ }).passthrough();
847
+ var checkRunPullRequestSideSchema = z.object({
848
+ ref: z.string().optional(),
849
+ repo: checkRunRepoRefSchema,
850
+ sha: z.string().optional()
851
+ }).passthrough();
852
+ var checkRunPullRequestSchema = z.object({
853
+ base: checkRunPullRequestSideSchema,
854
+ head: checkRunPullRequestSideSchema.optional(),
855
+ id: z.number().optional(),
856
+ number: z.number(),
857
+ url: z.string().optional()
858
+ }).passthrough();
859
+ var repositorySchema = z.object({
860
+ full_name: z.string().min(1),
861
+ id: z.number(),
862
+ name: z.string().min(1),
863
+ owner: z.object({ login: z.string().min(1) }).passthrough()
864
+ }).passthrough();
838
865
  var checkSuiteWebhookSchema = z.object({
839
866
  action: z.string(),
840
867
  check_suite: z.object({
@@ -846,12 +873,28 @@ var checkSuiteWebhookSchema = z.object({
846
873
  head_sha: z.string().optional(),
847
874
  id: z.number().optional(),
848
875
  latest_check_runs_count: z.number().optional().nullable(),
849
- pull_requests: z.array(
850
- z.object({ draft: z.boolean().optional(), number: z.number() })
851
- )
876
+ pull_requests: z.array(checkRunPullRequestSchema)
852
877
  }),
853
878
  repository: repositorySchema
854
879
  });
880
+ var checkRunsListResponseSchema = z.object({
881
+ check_runs: z.array(z.unknown()).optional()
882
+ }).passthrough();
883
+ function isCheckSuiteRepositoryPullRequest(pullRequest, repositoryId) {
884
+ return pullRequest.base.repo.id === repositoryId;
885
+ }
886
+ function checkSuiteEventType(conclusion) {
887
+ if (conclusion === "failure" || conclusion === "timed_out") {
888
+ return "pull_request.checks.failed";
889
+ }
890
+ if (conclusion === "success") {
891
+ return "pull_request.checks.recovered";
892
+ }
893
+ return void 0;
894
+ }
895
+ function isGitHubNotFoundError(error) {
896
+ return error instanceof Error && error.name === "GitHubRequestError" && "status" in error && error.status === 404;
897
+ }
855
898
  var FAILING_CHECK_CONCLUSIONS = /* @__PURE__ */ new Set([
856
899
  "failure",
857
900
  "timed_out",
@@ -954,16 +997,16 @@ function normalizeCheckSuiteEvents(deliveryId, body, options) {
954
997
  const parsed = checkSuiteWebhookSchema.safeParse(body);
955
998
  if (!parsed.success || parsed.data.action !== "completed") return [];
956
999
  const conclusion = parsed.data.check_suite.conclusion;
957
- if (!conclusion) return [];
958
- const eventType = conclusion === "failure" || conclusion === "timed_out" ? "pull_request.checks.failed" : conclusion === "success" ? "pull_request.checks.recovered" : void 0;
959
- if (!eventType) return [];
1000
+ const eventType = checkSuiteEventType(conclusion);
1001
+ if (!eventType || typeof conclusion !== "string") return [];
960
1002
  const suite = parsed.data.check_suite;
961
1003
  const appName = suite.app?.name?.trim() || suite.app?.slug?.trim() || void 0;
962
1004
  const headSha = typeof suite.head_sha === "string" && /^[0-9a-f]{7,40}$/i.test(suite.head_sha) ? suite.head_sha : void 0;
1005
+ const repository = parsed.data.repository;
1006
+ const repo = repository.full_name;
963
1007
  return suite.pull_requests.flatMap((pullRequest) => {
964
- const repo = parsed.data.repository.full_name;
1008
+ if (!isCheckSuiteRepositoryPullRequest(pullRequest, repository.id)) return [];
965
1009
  const facts = options?.pullRequestFactsByNumber?.[pullRequest.number];
966
- const draft = typeof pullRequest.draft === "boolean" ? pullRequest.draft : typeof facts?.isDraft === "boolean" ? facts.isDraft : void 0;
967
1010
  return pullRequestTargets(
968
1011
  buildCheckSuiteResourceEvent({
969
1012
  appName,
@@ -974,7 +1017,7 @@ function normalizeCheckSuiteEvents(deliveryId, body, options) {
974
1017
  eventType,
975
1018
  failingChecks: eventType === "pull_request.checks.failed" ? options?.failingChecks : void 0,
976
1019
  headSha,
977
- ...typeof draft === "boolean" ? { isDraft: draft } : void 0,
1020
+ ...typeof facts?.isDraft === "boolean" ? { isDraft: facts.isDraft } : void 0,
978
1021
  latestCheckRunsCount: typeof suite.latest_check_runs_count === "number" ? suite.latest_check_runs_count : void 0,
979
1022
  pullRequestNumber: pullRequest.number,
980
1023
  repo,
@@ -984,7 +1027,28 @@ function normalizeCheckSuiteEvents(deliveryId, body, options) {
984
1027
  );
985
1028
  });
986
1029
  }
987
- function parseCheckSuiteFactsTarget(body) {
1030
+ function parseCheckSuitePublishTargets(body) {
1031
+ const parsed = checkSuiteWebhookSchema.safeParse(body);
1032
+ if (!parsed.success || parsed.data.action !== "completed") return void 0;
1033
+ const eventType = checkSuiteEventType(parsed.data.check_suite.conclusion);
1034
+ if (!eventType) return void 0;
1035
+ const repository = parsed.data.repository;
1036
+ const repo = repository.full_name;
1037
+ const identifiers = /* @__PURE__ */ new Set([
1038
+ gitHubRepositoryResource({ repo }).identifier
1039
+ ]);
1040
+ for (const pullRequest of parsed.data.check_suite.pull_requests) {
1041
+ if (!isCheckSuiteRepositoryPullRequest(pullRequest, repository.id)) continue;
1042
+ identifiers.add(
1043
+ gitHubPullRequestResource({ number: pullRequest.number, repo }).identifier
1044
+ );
1045
+ }
1046
+ return {
1047
+ eventTypes: [eventType],
1048
+ identifiers: [...identifiers]
1049
+ };
1050
+ }
1051
+ function parseCheckSuiteFactsTarget(body, options) {
988
1052
  const parsed = checkSuiteWebhookSchema.safeParse(body);
989
1053
  if (!parsed.success || parsed.data.action !== "completed") return void 0;
990
1054
  const conclusion = parsed.data.check_suite.conclusion;
@@ -996,34 +1060,35 @@ function parseCheckSuiteFactsTarget(body) {
996
1060
  if (typeof headSha !== "string" || !/^[0-9a-f]{7,40}$/i.test(headSha) || typeof checkSuiteId !== "number") {
997
1061
  return void 0;
998
1062
  }
999
- const [owner, repoName, ...extra] = parsed.data.repository.full_name.split("/");
1000
- if (!owner || !repoName || extra.length > 0) return void 0;
1063
+ const repository = parsed.data.repository;
1001
1064
  const pullRequestNumbers = [
1002
1065
  ...new Set(
1003
- parsed.data.check_suite.pull_requests.map(
1004
- (pullRequest) => pullRequest.number
1005
- )
1066
+ parsed.data.check_suite.pull_requests.filter(
1067
+ (pullRequest) => isCheckSuiteRepositoryPullRequest(pullRequest, repository.id)
1068
+ ).map((pullRequest) => pullRequest.number)
1006
1069
  )
1007
1070
  ];
1008
1071
  const loadFailingChecks = conclusion === "failure" || conclusion === "timed_out";
1009
- if (!loadFailingChecks && pullRequestNumbers.length === 0) {
1072
+ const loadPullRequestFacts = Boolean(
1073
+ options?.loadPullRequestFacts && pullRequestNumbers.length > 0
1074
+ );
1075
+ if (!loadFailingChecks && !loadPullRequestFacts) {
1010
1076
  return void 0;
1011
1077
  }
1012
1078
  return {
1013
1079
  checkSuiteId,
1014
1080
  headSha,
1015
1081
  loadFailingChecks,
1016
- owner,
1082
+ loadPullRequestFacts,
1083
+ owner: repository.owner.login,
1017
1084
  pullRequestNumbers,
1018
- repoName
1085
+ repoName: repository.name
1019
1086
  };
1020
1087
  }
1021
1088
  function checkRunsFromResponse(value) {
1022
- if (!value || typeof value !== "object" || Array.isArray(value)) {
1023
- return [];
1024
- }
1025
- const checkRuns = value.check_runs;
1026
- return Array.isArray(checkRuns) ? checkRuns : [];
1089
+ const parsed = checkRunsListResponseSchema.safeParse(value);
1090
+ if (!parsed.success) return [];
1091
+ return parsed.data.check_runs ?? [];
1027
1092
  }
1028
1093
  function pullRequestFactsFromResponse(value) {
1029
1094
  if (!isRecord(value)) return void 0;
@@ -1038,8 +1103,16 @@ function pullRequestFactsFromResponse(value) {
1038
1103
  }
1039
1104
  return Object.keys(facts).length > 0 ? facts : void 0;
1040
1105
  }
1106
+ function needsCheckSuitePullRequestFacts(matchKeys) {
1107
+ for (const key of matchKeys) {
1108
+ if (CHECK_SUITE_PULL_REQUEST_MATCH_KEYS.has(key)) return true;
1109
+ }
1110
+ return false;
1111
+ }
1041
1112
  async function loadCheckSuiteFacts(args) {
1042
- const target = parseCheckSuiteFactsTarget(args.body);
1113
+ const target = parseCheckSuiteFactsTarget(args.body, {
1114
+ loadPullRequestFacts: args.loadPullRequestFacts
1115
+ });
1043
1116
  if (!target) return void 0;
1044
1117
  const facts = {};
1045
1118
  if (target.loadFailingChecks) {
@@ -1068,7 +1141,7 @@ async function loadCheckSuiteFacts(args) {
1068
1141
  });
1069
1142
  }
1070
1143
  }
1071
- if (target.pullRequestNumbers.length > 0) {
1144
+ if (target.loadPullRequestFacts) {
1072
1145
  try {
1073
1146
  const token = await issueInstallationToken({
1074
1147
  appIdEnv: args.appIdEnv,
@@ -1085,14 +1158,16 @@ async function loadCheckSuiteFacts(args) {
1085
1158
  `/repos/${encodeURIComponent(target.owner)}/${encodeURIComponent(target.repoName)}/pulls/${number}`,
1086
1159
  { token: token.token }
1087
1160
  );
1088
- const facts2 = pullRequestFactsFromResponse(response);
1089
- return facts2 ? [number, facts2] : void 0;
1161
+ const loadedFacts = pullRequestFactsFromResponse(response);
1162
+ return loadedFacts ? [number, loadedFacts] : void 0;
1090
1163
  } catch (error) {
1091
- args.log?.error("GitHub pull request data load failed", {
1092
- errorType: error instanceof Error ? error.name : "UnknownError",
1093
- pullRequest: number,
1094
- repository: `${target.owner}/${target.repoName}`
1095
- });
1164
+ if (!isGitHubNotFoundError(error)) {
1165
+ args.log?.error("GitHub pull request data load failed", {
1166
+ errorType: error instanceof Error ? error.name : "UnknownError",
1167
+ pullRequest: number,
1168
+ repository: `${target.owner}/${target.repoName}`
1169
+ });
1170
+ }
1096
1171
  return void 0;
1097
1172
  }
1098
1173
  })
@@ -1726,6 +1801,8 @@ export {
1726
1801
  issueInstallationToken,
1727
1802
  issueInstallationCredential,
1728
1803
  createPermissionCache,
1804
+ parseCheckSuitePublishTargets,
1805
+ needsCheckSuitePullRequestFacts,
1729
1806
  loadCheckSuiteFacts,
1730
1807
  normalizeGitHubResourceEvents
1731
1808
  };
package/dist/index.js CHANGED
@@ -35,14 +35,16 @@ import {
35
35
  issueInstallationToken,
36
36
  issueUserCredential,
37
37
  loadCheckSuiteFacts,
38
+ needsCheckSuitePullRequestFacts,
38
39
  normalizeGitHubResourceEvents,
39
40
  normalizePermissions,
40
41
  normalizeScopeList,
42
+ parseCheckSuitePublishTargets,
41
43
  readEnv,
42
44
  readGrantPermissions,
43
45
  requireEnv,
44
46
  resolveUserAccount
45
- } from "./chunk-JROTRF27.js";
47
+ } from "./chunk-KXAUXJ3Q.js";
46
48
 
47
49
  // src/plugin.ts
48
50
  import {
@@ -2398,6 +2400,7 @@ var githubPullRequestOutcomeInputSchema = z13.object({
2398
2400
  repositoryFullName: z13.string().min(1),
2399
2401
  repositoryId: z13.string().min(1),
2400
2402
  state: githubPullRequestStateSchema,
2403
+ title: z13.string().min(1).optional(),
2401
2404
  updatedAt: z13.date()
2402
2405
  }).strict();
2403
2406
  var githubPullRequestConversationsInputSchema = z13.object({
@@ -2727,6 +2730,7 @@ var canonicalPullRequestOutcomeSchema = z15.object({
2727
2730
  merged: z15.boolean(),
2728
2731
  merged_at: z15.string().nullable().optional(),
2729
2732
  number: z15.number().int().positive(),
2733
+ title: z15.string().min(1).optional(),
2730
2734
  updated_at: z15.string(),
2731
2735
  user: z15.object({ login: z15.string().min(1) }).strict()
2732
2736
  }).strict(),
@@ -2745,6 +2749,7 @@ var pullRequestOutcomeSchema = z15.object({
2745
2749
  merged: z15.boolean(),
2746
2750
  merged_at: z15.string().nullable().optional(),
2747
2751
  number: z15.number().int().positive(),
2752
+ title: z15.string().min(1).optional(),
2748
2753
  updated_at: z15.string(),
2749
2754
  user: z15.object({ login: z15.string().min(1) }).passthrough()
2750
2755
  }).passthrough(),
@@ -2763,6 +2768,7 @@ var pullRequestOutcomeSchema = z15.object({
2763
2768
  merged: provider.pull_request.merged,
2764
2769
  merged_at: provider.pull_request.merged_at,
2765
2770
  number: provider.pull_request.number,
2771
+ title: provider.pull_request.title,
2766
2772
  updated_at: provider.pull_request.updated_at,
2767
2773
  user: { login: provider.pull_request.user.login }
2768
2774
  },
@@ -2845,6 +2851,7 @@ function normalizeGitHubPullRequestOutcome(args) {
2845
2851
  repositoryFullName: parsed.repository.full_name,
2846
2852
  repositoryId: String(parsed.repository.id),
2847
2853
  state,
2854
+ title: pullRequest.title,
2848
2855
  updatedAt
2849
2856
  };
2850
2857
  }
@@ -2908,6 +2915,25 @@ function webhookInstallationId(body) {
2908
2915
  }
2909
2916
  return parseInstallationId(installation.id);
2910
2917
  }
2918
+ function githubCodeChange(outcome, conversationIds) {
2919
+ return {
2920
+ closedAt: outcome.closedAt,
2921
+ conversationIds,
2922
+ mergedAt: outcome.mergedAt,
2923
+ number: outcome.number,
2924
+ openedAt: outcome.openedAt,
2925
+ providerId: outcome.pullRequestId,
2926
+ repository: {
2927
+ name: outcome.repositoryFullName,
2928
+ providerId: outcome.repositoryId,
2929
+ url: `https://github.com/${outcome.repositoryFullName}`
2930
+ },
2931
+ state: outcome.state === "closed_unmerged" ? "closed" : outcome.state,
2932
+ title: outcome.title,
2933
+ updatedAt: outcome.updatedAt,
2934
+ url: `https://github.com/${outcome.repositoryFullName}/pull/${outcome.number}`
2935
+ };
2936
+ }
2911
2937
  function createGitHubWebhookRoute(args) {
2912
2938
  return {
2913
2939
  method: "POST",
@@ -2944,6 +2970,14 @@ function createGitHubWebhookRoute(args) {
2944
2970
  args.db,
2945
2971
  pullRequestOutcome
2946
2972
  );
2973
+ if (recordedOutcome.applied) {
2974
+ await args.codeChanges.record(
2975
+ githubCodeChange(
2976
+ pullRequestOutcome,
2977
+ recordedOutcome.conversationIds
2978
+ )
2979
+ );
2980
+ }
2947
2981
  if (recordedOutcome.applied && pullRequestOutcome.state !== "open") {
2948
2982
  const status = pullRequestOutcome.state === "merged" ? "merged" : "closed";
2949
2983
  await Promise.all(
@@ -3005,14 +3039,23 @@ function createGitHubWebhookRoute(args) {
3005
3039
  args.db,
3006
3040
  pullRequestConversations
3007
3041
  ) : false;
3042
+ if (recordedPullRequestConversations && pullRequestConversations) {
3043
+ await args.codeChanges.associateConversations({
3044
+ conversationIds: pullRequestConversations.conversationIds,
3045
+ providerId: pullRequestConversations.pullRequestId
3046
+ });
3047
+ }
3008
3048
  const recordedPullRequestLinkedIssues = pullRequestLinkedIssues ? await recordGitHubPullRequestLinkedIssues(
3009
3049
  args.db,
3010
3050
  pullRequestLinkedIssues
3011
3051
  ) : false;
3052
+ const checkSuitePublishTargets = eventName === "check_suite" ? parseCheckSuitePublishTargets(body) : void 0;
3053
+ const checkSuiteMatchKeys = checkSuitePublishTargets && args.resourceEvents.neededMatchKeys ? await args.resourceEvents.neededMatchKeys(checkSuitePublishTargets) : [];
3012
3054
  const checkSuiteFacts = eventName === "check_suite" ? await loadCheckSuiteFacts({
3013
3055
  appIdEnv: args.appIdEnv,
3014
3056
  body,
3015
3057
  installationIdEnv: args.installationIdEnv,
3058
+ loadPullRequestFacts: needsCheckSuitePullRequestFacts(checkSuiteMatchKeys),
3016
3059
  log: args.log,
3017
3060
  privateKeyEnv: args.privateKeyEnv
3018
3061
  }) : void 0;
@@ -5342,6 +5385,7 @@ function githubPlugin(options = {}) {
5342
5385
  )
5343
5386
  });
5344
5387
  },
5388
+ codeChanges: ctx.codeChanges,
5345
5389
  db: ctx.db,
5346
5390
  installationId: () => readEnv(installationIdEnv),
5347
5391
  installationIdEnv,
@@ -19,6 +19,7 @@ declare const githubPullRequestOutcomeInputSchema: z.ZodObject<{
19
19
  merged: "merged";
20
20
  closed_unmerged: "closed_unmerged";
21
21
  }>;
22
+ title: z.ZodOptional<z.ZodString>;
22
23
  updatedAt: z.ZodDate;
23
24
  }, z.core.$strict>;
24
25
  export type GitHubPullRequestOutcomeInput = z.output<typeof githubPullRequestOutcomeInputSchema>;
package/dist/testing.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  normalizeGitHubResourceEvents
3
- } from "./chunk-JROTRF27.js";
3
+ } from "./chunk-KXAUXJ3Q.js";
4
4
  export {
5
5
  normalizeGitHubResourceEvents
6
6
  };
@@ -8,7 +8,7 @@ export type GitHubFailingCheck = {
8
8
  htmlUrl?: string;
9
9
  name: string;
10
10
  };
11
- /** Pull request values filled in when the check suite body omits them. */
11
+ /** Pull request values filled in when a match filter needs them. */
12
12
  export type GitHubCheckSuitePullRequestFacts = {
13
13
  authorEmail?: string;
14
14
  authorUsername?: string;
@@ -17,7 +17,7 @@ export type GitHubCheckSuitePullRequestFacts = {
17
17
  /** Optional values for one check suite event. */
18
18
  export type GitHubCheckSuiteFacts = {
19
19
  failingChecks?: GitHubFailingCheck[];
20
- /** Pull request values by number when GitHub omitted them on the suite. */
20
+ /** Pull request values by number when a match filter needs them. */
21
21
  pullRequestFactsByNumber?: Record<number, GitHubCheckSuitePullRequestFacts>;
22
22
  };
23
23
  /** Build a browser URL for one check suite. GitHub does not send html_url. */
@@ -48,20 +48,31 @@ export declare function selectFailingChecks(checkRuns: unknown, options?: {
48
48
  }): GitHubFailingCheck[];
49
49
  /** Normalize a completed check suite for each attached pull request. */
50
50
  export declare function normalizeCheckSuiteEvents(deliveryId: string, body: unknown, options?: GitHubCheckSuiteFacts): ResourceEventInput[];
51
+ /** Identifiers and event types one completed check suite may publish. */
52
+ export declare function parseCheckSuitePublishTargets(body: unknown): {
53
+ eventTypes: string[];
54
+ identifiers: string[];
55
+ } | undefined;
51
56
  /** Read which check suite values still need a GitHub API load. */
52
- export declare function parseCheckSuiteFactsTarget(body: unknown): {
57
+ export declare function parseCheckSuiteFactsTarget(body: unknown, options?: {
58
+ loadPullRequestFacts?: boolean;
59
+ }): {
53
60
  checkSuiteId: number;
54
61
  headSha: string;
55
62
  loadFailingChecks: boolean;
63
+ loadPullRequestFacts: boolean;
56
64
  owner: string;
57
65
  pullRequestNumbers: number[];
58
66
  repoName: string;
59
67
  } | undefined;
60
- /** Load missing values for one check suite event. */
68
+ /** True when active match filters need pull request fields from the API. */
69
+ export declare function needsCheckSuitePullRequestFacts(matchKeys: Iterable<string>): boolean;
70
+ /** Load failed check runs and optional pull request match fields. */
61
71
  export declare function loadCheckSuiteFacts(args: {
62
72
  appIdEnv: string;
63
73
  body: unknown;
64
74
  installationIdEnv: string;
75
+ loadPullRequestFacts?: boolean;
65
76
  log?: {
66
77
  error(message: string, metadata?: Record<string, unknown>): void;
67
78
  };
@@ -1,4 +1,4 @@
1
- import type { PluginConversationAnnotations, PluginLogger, PluginRoute, ResourceEventPublisher } from "@sentry/junior-plugin-api";
1
+ import type { CodeChangePublisher, PluginConversationAnnotations, PluginLogger, PluginRoute, ResourceEventPublisher } from "@sentry/junior-plugin-api";
2
2
  import type { GitHubDb } from "../db/database.js";
3
3
  import type { GitHubPullRequestCommitComposition } from "../db/schema.js";
4
4
  /** Create the public, signed GitHub webhook route owned by the plugin. */
@@ -10,6 +10,7 @@ export declare function createGitHubWebhookRoute(args: {
10
10
  number: number;
11
11
  repositoryFullName: string;
12
12
  }): Promise<GitHubPullRequestCommitComposition | undefined>;
13
+ codeChanges: CodeChangePublisher;
13
14
  db: GitHubDb;
14
15
  installationId(): string | undefined;
15
16
  installationIdEnv: string;
@@ -1,7 +1,7 @@
1
1
  import type { ResourceEventInput } from "@sentry/junior-plugin-api";
2
2
  import { type GitHubCheckSuiteFacts } from "./check-suite.js";
3
3
  export type { GitHubCheckSuiteFacts, GitHubCheckSuitePullRequestFacts, GitHubFailingCheck, } from "./check-suite.js";
4
- export { buildCheckSuiteResourceEvent, buildCheckSuiteUrl, loadCheckSuiteFacts, parseCheckSuiteFactsTarget, selectFailingChecks, } from "./check-suite.js";
4
+ export { buildCheckSuiteResourceEvent, buildCheckSuiteUrl, loadCheckSuiteFacts, needsCheckSuitePullRequestFacts, parseCheckSuiteFactsTarget, parseCheckSuitePublishTargets, selectFailingChecks, } from "./check-suite.js";
5
5
  /** Read the check suite target used to load missing suite facts. */
6
6
  /** Normalize one verified GitHub delivery into conversation resource events. */
7
7
  export declare function normalizeGitHubResourceEvents(args: {
@@ -0,0 +1,74 @@
1
+ INSERT INTO junior_code_repositories (
2
+ id,
3
+ name,
4
+ provider,
5
+ provider_id,
6
+ url,
7
+ updated_at
8
+ )
9
+ SELECT DISTINCT ON (repository_id)
10
+ gen_random_uuid(),
11
+ repository_full_name,
12
+ 'github',
13
+ repository_id,
14
+ 'https://github.com/' || repository_full_name,
15
+ updated_at
16
+ FROM junior_github_pull_requests
17
+ ORDER BY repository_id, updated_at DESC
18
+ ON CONFLICT (provider, provider_id) DO UPDATE SET
19
+ name = EXCLUDED.name,
20
+ url = EXCLUDED.url,
21
+ updated_at = EXCLUDED.updated_at
22
+ WHERE junior_code_repositories.updated_at <= EXCLUDED.updated_at;
23
+ --> statement-breakpoint
24
+ INSERT INTO junior_code_changes (
25
+ id,
26
+ closed_at,
27
+ conversation_ids,
28
+ merged_at,
29
+ number,
30
+ opened_at,
31
+ provider,
32
+ provider_id,
33
+ repository_id,
34
+ state,
35
+ updated_at,
36
+ url
37
+ )
38
+ SELECT
39
+ gen_random_uuid(),
40
+ github_change.closed_at,
41
+ github_change.conversation_ids,
42
+ github_change.merged_at,
43
+ github_change.number,
44
+ github_change.opened_at,
45
+ 'github',
46
+ github_change.pull_request_id,
47
+ repository.id,
48
+ CASE github_change.state
49
+ WHEN 'closed_unmerged' THEN 'closed'
50
+ ELSE github_change.state
51
+ END,
52
+ github_change.updated_at,
53
+ 'https://github.com/' || github_change.repository_full_name || '/pull/' || github_change.number
54
+ FROM junior_github_pull_requests AS github_change
55
+ JOIN junior_code_repositories AS repository
56
+ ON repository.provider = 'github'
57
+ AND repository.provider_id = github_change.repository_id
58
+ ON CONFLICT (provider, provider_id) DO UPDATE SET
59
+ closed_at = EXCLUDED.closed_at,
60
+ conversation_ids = ARRAY(
61
+ SELECT DISTINCT value
62
+ FROM unnest(
63
+ junior_code_changes.conversation_ids || EXCLUDED.conversation_ids
64
+ ) AS value
65
+ ORDER BY value
66
+ ),
67
+ merged_at = EXCLUDED.merged_at,
68
+ number = EXCLUDED.number,
69
+ opened_at = EXCLUDED.opened_at,
70
+ repository_id = EXCLUDED.repository_id,
71
+ state = EXCLUDED.state,
72
+ updated_at = EXCLUDED.updated_at,
73
+ url = EXCLUDED.url
74
+ WHERE junior_code_changes.updated_at <= EXCLUDED.updated_at;
@@ -0,0 +1,348 @@
1
+ {
2
+ "id": "da9cceed-a211-4f1b-a5b8-ac4237b9caf5",
3
+ "prevId": "a54d392c-28bb-4cd3-ba14-1bcfa793fcce",
4
+ "version": "7",
5
+ "dialect": "postgresql",
6
+ "tables": {
7
+ "public.junior_github_issues": {
8
+ "name": "junior_github_issues",
9
+ "schema": "",
10
+ "columns": {
11
+ "issue_id": {
12
+ "name": "issue_id",
13
+ "type": "text",
14
+ "primaryKey": true,
15
+ "notNull": true
16
+ },
17
+ "repository_id": {
18
+ "name": "repository_id",
19
+ "type": "text",
20
+ "primaryKey": false,
21
+ "notNull": true
22
+ },
23
+ "repository_full_name": {
24
+ "name": "repository_full_name",
25
+ "type": "text",
26
+ "primaryKey": false,
27
+ "notNull": true
28
+ },
29
+ "number": {
30
+ "name": "number",
31
+ "type": "integer",
32
+ "primaryKey": false,
33
+ "notNull": true
34
+ },
35
+ "state": {
36
+ "name": "state",
37
+ "type": "text",
38
+ "primaryKey": false,
39
+ "notNull": true
40
+ },
41
+ "state_reason": {
42
+ "name": "state_reason",
43
+ "type": "text",
44
+ "primaryKey": false,
45
+ "notNull": false
46
+ },
47
+ "conversation_ids": {
48
+ "name": "conversation_ids",
49
+ "type": "text[]",
50
+ "primaryKey": false,
51
+ "notNull": true,
52
+ "default": "ARRAY[]::text[]"
53
+ },
54
+ "opened_at": {
55
+ "name": "opened_at",
56
+ "type": "timestamp with time zone",
57
+ "primaryKey": false,
58
+ "notNull": true
59
+ },
60
+ "closed_at": {
61
+ "name": "closed_at",
62
+ "type": "timestamp with time zone",
63
+ "primaryKey": false,
64
+ "notNull": false
65
+ },
66
+ "updated_at": {
67
+ "name": "updated_at",
68
+ "type": "timestamp with time zone",
69
+ "primaryKey": false,
70
+ "notNull": true
71
+ }
72
+ },
73
+ "indexes": {
74
+ "junior_github_issues_opened_at_idx": {
75
+ "name": "junior_github_issues_opened_at_idx",
76
+ "columns": [
77
+ {
78
+ "expression": "opened_at",
79
+ "isExpression": false,
80
+ "asc": true,
81
+ "nulls": "last"
82
+ }
83
+ ],
84
+ "isUnique": false,
85
+ "with": {},
86
+ "method": "btree",
87
+ "concurrently": false
88
+ },
89
+ "junior_github_issues_closed_at_idx": {
90
+ "name": "junior_github_issues_closed_at_idx",
91
+ "columns": [
92
+ {
93
+ "expression": "closed_at",
94
+ "isExpression": false,
95
+ "asc": true,
96
+ "nulls": "last"
97
+ }
98
+ ],
99
+ "isUnique": false,
100
+ "with": {},
101
+ "method": "btree",
102
+ "concurrently": false
103
+ },
104
+ "junior_github_issues_open_idx": {
105
+ "name": "junior_github_issues_open_idx",
106
+ "columns": [
107
+ {
108
+ "expression": "issue_id",
109
+ "isExpression": false,
110
+ "asc": true,
111
+ "nulls": "last"
112
+ }
113
+ ],
114
+ "isUnique": false,
115
+ "with": {},
116
+ "method": "btree",
117
+ "where": "\"junior_github_issues\".\"state\" = 'open'",
118
+ "concurrently": false
119
+ }
120
+ },
121
+ "foreignKeys": {},
122
+ "compositePrimaryKeys": {},
123
+ "uniqueConstraints": {},
124
+ "policies": {},
125
+ "checkConstraints": {},
126
+ "isRLSEnabled": false
127
+ },
128
+ "public.junior_github_pull_request_issues": {
129
+ "name": "junior_github_pull_request_issues",
130
+ "schema": "",
131
+ "columns": {
132
+ "pull_request_id": {
133
+ "name": "pull_request_id",
134
+ "type": "text",
135
+ "primaryKey": false,
136
+ "notNull": true
137
+ },
138
+ "issue_repository_full_name": {
139
+ "name": "issue_repository_full_name",
140
+ "type": "text",
141
+ "primaryKey": false,
142
+ "notNull": true
143
+ },
144
+ "issue_number": {
145
+ "name": "issue_number",
146
+ "type": "integer",
147
+ "primaryKey": false,
148
+ "notNull": true
149
+ }
150
+ },
151
+ "indexes": {},
152
+ "foreignKeys": {
153
+ "junior_github_pull_request_issues_pull_request_id_junior_github_pull_requests_pull_request_id_fk": {
154
+ "name": "junior_github_pull_request_issues_pull_request_id_junior_github_pull_requests_pull_request_id_fk",
155
+ "tableFrom": "junior_github_pull_request_issues",
156
+ "columnsFrom": ["pull_request_id"],
157
+ "tableTo": "junior_github_pull_requests",
158
+ "columnsTo": ["pull_request_id"],
159
+ "onUpdate": "no action",
160
+ "onDelete": "cascade"
161
+ }
162
+ },
163
+ "compositePrimaryKeys": {
164
+ "junior_github_pull_request_issues_pull_request_id_issue_repository_full_name_issue_number_pk": {
165
+ "name": "junior_github_pull_request_issues_pull_request_id_issue_repository_full_name_issue_number_pk",
166
+ "columns": [
167
+ "pull_request_id",
168
+ "issue_repository_full_name",
169
+ "issue_number"
170
+ ]
171
+ }
172
+ },
173
+ "uniqueConstraints": {},
174
+ "policies": {},
175
+ "checkConstraints": {},
176
+ "isRLSEnabled": false
177
+ },
178
+ "public.junior_github_pull_requests": {
179
+ "name": "junior_github_pull_requests",
180
+ "schema": "",
181
+ "columns": {
182
+ "pull_request_id": {
183
+ "name": "pull_request_id",
184
+ "type": "text",
185
+ "primaryKey": true,
186
+ "notNull": true
187
+ },
188
+ "repository_id": {
189
+ "name": "repository_id",
190
+ "type": "text",
191
+ "primaryKey": false,
192
+ "notNull": true
193
+ },
194
+ "repository_full_name": {
195
+ "name": "repository_full_name",
196
+ "type": "text",
197
+ "primaryKey": false,
198
+ "notNull": true
199
+ },
200
+ "number": {
201
+ "name": "number",
202
+ "type": "integer",
203
+ "primaryKey": false,
204
+ "notNull": true
205
+ },
206
+ "state": {
207
+ "name": "state",
208
+ "type": "text",
209
+ "primaryKey": false,
210
+ "notNull": true
211
+ },
212
+ "commit_composition": {
213
+ "name": "commit_composition",
214
+ "type": "text",
215
+ "primaryKey": false,
216
+ "notNull": false
217
+ },
218
+ "conversation_ids": {
219
+ "name": "conversation_ids",
220
+ "type": "text[]",
221
+ "primaryKey": false,
222
+ "notNull": true,
223
+ "default": "ARRAY[]::text[]"
224
+ },
225
+ "opened_at": {
226
+ "name": "opened_at",
227
+ "type": "timestamp with time zone",
228
+ "primaryKey": false,
229
+ "notNull": true
230
+ },
231
+ "merged_at": {
232
+ "name": "merged_at",
233
+ "type": "timestamp with time zone",
234
+ "primaryKey": false,
235
+ "notNull": false
236
+ },
237
+ "closed_at": {
238
+ "name": "closed_at",
239
+ "type": "timestamp with time zone",
240
+ "primaryKey": false,
241
+ "notNull": false
242
+ },
243
+ "updated_at": {
244
+ "name": "updated_at",
245
+ "type": "timestamp with time zone",
246
+ "primaryKey": false,
247
+ "notNull": true
248
+ }
249
+ },
250
+ "indexes": {
251
+ "junior_github_pull_requests_opened_at_idx": {
252
+ "name": "junior_github_pull_requests_opened_at_idx",
253
+ "columns": [
254
+ {
255
+ "expression": "opened_at",
256
+ "isExpression": false,
257
+ "asc": true,
258
+ "nulls": "last"
259
+ }
260
+ ],
261
+ "isUnique": false,
262
+ "with": {},
263
+ "method": "btree",
264
+ "concurrently": false
265
+ },
266
+ "junior_github_pull_requests_merged_at_idx": {
267
+ "name": "junior_github_pull_requests_merged_at_idx",
268
+ "columns": [
269
+ {
270
+ "expression": "merged_at",
271
+ "isExpression": false,
272
+ "asc": true,
273
+ "nulls": "last"
274
+ }
275
+ ],
276
+ "isUnique": false,
277
+ "with": {},
278
+ "method": "btree",
279
+ "concurrently": false
280
+ },
281
+ "junior_github_pull_requests_closed_at_idx": {
282
+ "name": "junior_github_pull_requests_closed_at_idx",
283
+ "columns": [
284
+ {
285
+ "expression": "closed_at",
286
+ "isExpression": false,
287
+ "asc": true,
288
+ "nulls": "last"
289
+ }
290
+ ],
291
+ "isUnique": false,
292
+ "with": {},
293
+ "method": "btree",
294
+ "concurrently": false
295
+ },
296
+ "junior_github_pull_requests_open_idx": {
297
+ "name": "junior_github_pull_requests_open_idx",
298
+ "columns": [
299
+ {
300
+ "expression": "pull_request_id",
301
+ "isExpression": false,
302
+ "asc": true,
303
+ "nulls": "last"
304
+ }
305
+ ],
306
+ "isUnique": false,
307
+ "with": {},
308
+ "method": "btree",
309
+ "where": "\"junior_github_pull_requests\".\"state\" = 'open'",
310
+ "concurrently": false
311
+ },
312
+ "junior_github_pull_requests_unmerged_conversations_idx": {
313
+ "name": "junior_github_pull_requests_unmerged_conversations_idx",
314
+ "columns": [
315
+ {
316
+ "expression": "conversation_ids",
317
+ "isExpression": false,
318
+ "asc": true,
319
+ "nulls": "last"
320
+ }
321
+ ],
322
+ "isUnique": false,
323
+ "with": {},
324
+ "method": "gin",
325
+ "where": "\"junior_github_pull_requests\".\"state\" <> 'merged'",
326
+ "concurrently": false
327
+ }
328
+ },
329
+ "foreignKeys": {},
330
+ "compositePrimaryKeys": {},
331
+ "uniqueConstraints": {},
332
+ "policies": {},
333
+ "checkConstraints": {},
334
+ "isRLSEnabled": false
335
+ }
336
+ },
337
+ "enums": {},
338
+ "schemas": {},
339
+ "views": {},
340
+ "sequences": {},
341
+ "roles": {},
342
+ "policies": {},
343
+ "_meta": {
344
+ "columns": {},
345
+ "schemas": {},
346
+ "tables": {}
347
+ }
348
+ }
@@ -57,6 +57,13 @@
57
57
  "when": 1786486305688,
58
58
  "tag": "0007_shallow_millenium_guard",
59
59
  "breakpoints": true
60
+ },
61
+ {
62
+ "idx": 8,
63
+ "version": "7",
64
+ "when": 1787598510781,
65
+ "tag": "0008_native_code_backfill",
66
+ "breakpoints": true
60
67
  }
61
68
  ]
62
- }
69
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/junior-github",
3
- "version": "0.182.0",
3
+ "version": "0.183.0",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -31,7 +31,7 @@
31
31
  "@sinclair/typebox": "^0.34.49",
32
32
  "drizzle-orm": "^0.45.2",
33
33
  "zod": "^4.4.3",
34
- "@sentry/junior-plugin-api": "0.182.0"
34
+ "@sentry/junior-plugin-api": "0.183.0"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@oxlint/plugins": "1.79.0",