@sentry/junior-github 0.117.0 → 0.118.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.
package/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # @sentry/junior-github
2
2
 
3
- `@sentry/junior-github` adds GitHub issue, pull request, repository, and user-attachment workflows to Junior using a GitHub App.
3
+ `@sentry/junior-github` adds GitHub deployment, issue, pull request,
4
+ repository, and user-attachment workflows to Junior using a GitHub App.
4
5
 
5
6
  Install it alongside `@sentry/junior`:
6
7
 
@@ -24,6 +25,7 @@ export const plugins = defineJuniorPlugins([
24
25
 
25
26
  Full setup guide: https://junior.sentry.dev/extend/github-plugin/
26
27
 
27
- The plugin owns its signed webhook route, normalized pull request and issue
28
- outcome projections, and dashboard operational report. Core only owns delivery
29
- from plugin-published resource events into matching conversation subscriptions.
28
+ The plugin owns its signed webhook route, deployment and pull request resource
29
+ events, normalized pull request and issue outcome projections, and dashboard
30
+ operational report. Core only owns delivery from plugin-published resource
31
+ events into matching conversation subscriptions.
package/SETUP.md CHANGED
@@ -14,6 +14,7 @@ In GitHub:
14
14
  - Contents: Read and write
15
15
  - Pull requests: Read and write
16
16
  - Actions: Read and write
17
+ - Deployments: Read
17
18
  - Workflows: Write
18
19
  - Metadata: Read
19
20
 
@@ -77,8 +78,15 @@ the App bot login from that email. Set the GitHub App webhook URL to
77
78
  `https://<junior-host>/api/webhooks/github` and subscribe to Pull request
78
79
  and Issues events. The secret in GitHub must match the deployment environment.
79
80
 
80
- Conversation watches additionally use Check suite, Issue comment, Pull request
81
- review, and Pull request review comment events.
81
+ Conversation watches additionally use Check suite, Deployment, Deployment
82
+ status, Issue comment, Pull request review, and Pull request review comment
83
+ events.
84
+
85
+ `github_getDeployment` reads the latest deployment and status for an exact
86
+ repository, environment, and commit SHA. When webhooks are configured, its
87
+ result can subscribe the current conversation to deployment creation, progress,
88
+ success, failure, and error events. The subscription remains available when
89
+ GitHub has not created the deployment yet.
82
90
 
83
91
  ```bash
84
92
  vercel env add GITHUB_WEBHOOK_SECRET production
@@ -108,6 +116,7 @@ githubPlugin({
108
116
  appPermissions: {
109
117
  actions: "write",
110
118
  contents: "write",
119
+ deployments: "read",
111
120
  issues: "write",
112
121
  metadata: "read",
113
122
  pull_requests: "write",
@@ -1,6 +1,41 @@
1
1
  // src/webhooks/resource-events.ts
2
2
  import { z } from "zod";
3
3
 
4
+ // src/resource-events/deployment.ts
5
+ var GITHUB_DEPLOYMENT_EVENTS = [
6
+ "deployment.created",
7
+ "deployment.queued",
8
+ "deployment.pending",
9
+ "deployment.in_progress",
10
+ "deployment.succeeded",
11
+ "deployment.failed",
12
+ "deployment.error"
13
+ ];
14
+ var SUGGESTED_EVENTS = [
15
+ "deployment.succeeded",
16
+ "deployment.failed",
17
+ "deployment.error"
18
+ ];
19
+ function gitHubDeploymentSourceResource(input) {
20
+ const commitSha = input.commitSha.toLowerCase();
21
+ const environment = input.environment.trim();
22
+ const repo = input.repo.toLowerCase();
23
+ return {
24
+ label: `GitHub deployment for ${repo} at ${commitSha.slice(0, 12)}`,
25
+ provider: "github",
26
+ resourceRef: `github:deployment-source:${repo}:${encodeURIComponent(environment.toLowerCase())}:${commitSha}`
27
+ };
28
+ }
29
+ function gitHubDeploymentSourceSubscribable(input) {
30
+ if (!process.env.GITHUB_WEBHOOK_SECRET?.trim()) return void 0;
31
+ return {
32
+ ...gitHubDeploymentSourceResource(input),
33
+ suggestedEvents: SUGGESTED_EVENTS,
34
+ supportedEvents: [...GITHUB_DEPLOYMENT_EVENTS],
35
+ type: "deployment_source"
36
+ };
37
+ }
38
+
4
39
  // src/resource-events/pull-request.ts
5
40
  var SUPPORTED_EVENTS = [
6
41
  "checks.failed",
@@ -13,7 +48,7 @@ var SUPPORTED_EVENTS = [
13
48
  "state.merged",
14
49
  "state.closed_unmerged"
15
50
  ];
16
- var SUGGESTED_EVENTS = [
51
+ var SUGGESTED_EVENTS2 = [
17
52
  "checks.failed",
18
53
  "comment.created",
19
54
  "review.changes_requested",
@@ -33,7 +68,7 @@ function gitHubPullRequestSubscribable(input) {
33
68
  if (!process.env.GITHUB_WEBHOOK_SECRET?.trim()) return void 0;
34
69
  return {
35
70
  ...gitHubPullRequestResource(input),
36
- suggestedEvents: SUGGESTED_EVENTS,
71
+ suggestedEvents: SUGGESTED_EVENTS2,
37
72
  supportedEvents: SUPPORTED_EVENTS,
38
73
  type: "pull_request"
39
74
  };
@@ -43,7 +78,125 @@ function gitHubPullRequestSubscribable(input) {
43
78
  function gitHubEventKey(deliveryId, eventType) {
44
79
  return `github:${deliveryId}:${eventType}`;
45
80
  }
46
- var repositorySchema = z.object({ full_name: z.string().min(1) });
81
+ var repositorySchema = z.object({ full_name: z.string().min(1) }).passthrough();
82
+ var deploymentSchema = z.object({
83
+ created_at: z.string().optional(),
84
+ environment: z.string().min(1),
85
+ id: z.number(),
86
+ sha: z.string().regex(/^[0-9a-f]{40}$/i)
87
+ }).passthrough();
88
+ var deploymentWebhookSchema = z.object({
89
+ action: z.string(),
90
+ deployment: deploymentSchema,
91
+ repository: repositorySchema
92
+ }).passthrough();
93
+ var canonicalDeploymentEventSchema = z.object({
94
+ action: z.string(),
95
+ commitSha: z.string().regex(/^[0-9a-f]{40}$/i),
96
+ createdAt: z.string().optional(),
97
+ deploymentId: z.number(),
98
+ environment: z.string().min(1),
99
+ repo: z.string().min(1)
100
+ }).strict();
101
+ function parseDeploymentEvent(body) {
102
+ const parsed = deploymentWebhookSchema.safeParse(body);
103
+ if (!parsed.success) return void 0;
104
+ return canonicalDeploymentEventSchema.parse({
105
+ action: parsed.data.action,
106
+ commitSha: parsed.data.deployment.sha,
107
+ createdAt: parsed.data.deployment.created_at,
108
+ deploymentId: parsed.data.deployment.id,
109
+ environment: parsed.data.deployment.environment,
110
+ repo: parsed.data.repository.full_name
111
+ });
112
+ }
113
+ function normalizeDeploymentEvent(deliveryId, body) {
114
+ const parsed = parseDeploymentEvent(body);
115
+ if (!parsed || parsed.action !== "created") return void 0;
116
+ const resource = gitHubDeploymentSourceResource({
117
+ commitSha: parsed.commitSha,
118
+ environment: parsed.environment,
119
+ repo: parsed.repo
120
+ });
121
+ const eventType = "deployment.created";
122
+ return {
123
+ eventKey: gitHubEventKey(deliveryId, eventType),
124
+ eventType,
125
+ occurredAtMs: providerTime(parsed.createdAt) ?? Date.now(),
126
+ provider: "github",
127
+ resourceRef: resource.resourceRef,
128
+ trustedSummary: `${resource.label} was created (deployment ${parsed.deploymentId}).`
129
+ };
130
+ }
131
+ var deploymentStatusWebhookSchema = z.object({
132
+ action: z.string(),
133
+ deployment: deploymentSchema,
134
+ deployment_status: z.object({
135
+ created_at: z.string().optional(),
136
+ description: z.string().optional().nullable(),
137
+ state: z.string()
138
+ }).passthrough(),
139
+ repository: repositorySchema
140
+ }).passthrough();
141
+ var canonicalDeploymentStatusEventSchema = canonicalDeploymentEventSchema.extend({
142
+ description: z.string().optional().nullable(),
143
+ state: z.string(),
144
+ statusCreatedAt: z.string().optional()
145
+ }).strict();
146
+ function parseDeploymentStatusEvent(body) {
147
+ const parsed = deploymentStatusWebhookSchema.safeParse(body);
148
+ if (!parsed.success) return void 0;
149
+ return canonicalDeploymentStatusEventSchema.parse({
150
+ action: parsed.data.action,
151
+ commitSha: parsed.data.deployment.sha,
152
+ createdAt: parsed.data.deployment.created_at,
153
+ deploymentId: parsed.data.deployment.id,
154
+ description: parsed.data.deployment_status.description,
155
+ environment: parsed.data.deployment.environment,
156
+ repo: parsed.data.repository.full_name,
157
+ state: parsed.data.deployment_status.state,
158
+ statusCreatedAt: parsed.data.deployment_status.created_at
159
+ });
160
+ }
161
+ function deploymentStatusEventType(state) {
162
+ switch (state) {
163
+ case "queued":
164
+ case "pending":
165
+ case "in_progress":
166
+ return `deployment.${state}`;
167
+ case "success":
168
+ return "deployment.succeeded";
169
+ case "failure":
170
+ return "deployment.failed";
171
+ case "error":
172
+ return "deployment.error";
173
+ default:
174
+ return void 0;
175
+ }
176
+ }
177
+ function normalizeDeploymentStatusEvent(deliveryId, body) {
178
+ const parsed = parseDeploymentStatusEvent(body);
179
+ if (!parsed || parsed.action !== "created") return void 0;
180
+ const eventType = deploymentStatusEventType(parsed.state);
181
+ if (!eventType) return void 0;
182
+ const resource = gitHubDeploymentSourceResource({
183
+ commitSha: parsed.commitSha,
184
+ environment: parsed.environment,
185
+ repo: parsed.repo
186
+ });
187
+ const outcome = eventType === "deployment.succeeded" ? "succeeded" : eventType === "deployment.failed" ? "failed" : eventType === "deployment.error" ? "reported an error" : eventType === "deployment.in_progress" ? "started" : `is ${parsed.state}`;
188
+ const terminal = eventType === "deployment.succeeded" || eventType === "deployment.failed" || eventType === "deployment.error";
189
+ return {
190
+ eventKey: gitHubEventKey(deliveryId, eventType),
191
+ eventType,
192
+ occurredAtMs: providerTime(parsed.statusCreatedAt) ?? Date.now(),
193
+ provider: "github",
194
+ resourceRef: resource.resourceRef,
195
+ ...terminal ? { terminal: true } : {},
196
+ trustedSummary: `${resource.label} ${outcome} (deployment ${parsed.deploymentId}).`,
197
+ untrustedText: parsed.description ?? void 0
198
+ };
199
+ }
47
200
  var checkSuiteWebhookSchema = z.object({
48
201
  action: z.string(),
49
202
  check_suite: z.object({
@@ -207,6 +360,14 @@ function normalizePullRequestEvent(deliveryId, body) {
207
360
  }
208
361
  function normalizeGitHubResourceEvents(args) {
209
362
  switch (args.eventName) {
363
+ case "deployment": {
364
+ const event = normalizeDeploymentEvent(args.deliveryId, args.body);
365
+ return event ? [event] : [];
366
+ }
367
+ case "deployment_status": {
368
+ const event = normalizeDeploymentStatusEvent(args.deliveryId, args.body);
369
+ return event ? [event] : [];
370
+ }
210
371
  case "pull_request": {
211
372
  const event = normalizePullRequestEvent(args.deliveryId, args.body);
212
373
  return event ? [event] : [];
@@ -234,6 +395,7 @@ function normalizeGitHubResourceEvents(args) {
234
395
  }
235
396
 
236
397
  export {
398
+ gitHubDeploymentSourceSubscribable,
237
399
  gitHubPullRequestSubscribable,
238
400
  normalizeGitHubResourceEvents
239
401
  };