@sentry/junior-linear 0.206.0 → 0.208.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
|
@@ -21,13 +21,13 @@ This package does not require a shared `LINEAR_API_KEY` or a custom OAuth app fo
|
|
|
21
21
|
|
|
22
22
|
Linear operations use Linear's hosted MCP tools directly. When an issue is created through that path, Junior links it to the current conversation.
|
|
23
23
|
|
|
24
|
-
To run watches or event
|
|
24
|
+
To run watches or event automations when Linear issues are created:
|
|
25
25
|
|
|
26
26
|
1. Set `LINEAR_WEBHOOK_SECRET` to the Linear webhook signing secret.
|
|
27
27
|
2. Create a Linear webhook for the `Issue` resource at `https://<junior-host>/api/webhooks/linear`.
|
|
28
28
|
3. Redeploy Junior.
|
|
29
29
|
|
|
30
|
-
The plugin verifies the `Linear-Signature` header and publishes `issue.created` for the issue identifier and the team key. Team event
|
|
30
|
+
The plugin verifies the `Linear-Signature` header and publishes `issue.created` for the issue identifier and the team key. Team event automations use the Linear team key, such as `SRE`. Issue and team watches also accept an optional `match.teamKey` filter on trusted event data.
|
|
31
31
|
|
|
32
32
|
Optional: set channel defaults when a Slack thread usually routes work to the same Linear destination:
|
|
33
33
|
|
package/dist/index.js
CHANGED
|
@@ -4,12 +4,12 @@ import {
|
|
|
4
4
|
} from "@sentry/junior-plugin-api";
|
|
5
5
|
import { z as z2 } from "zod";
|
|
6
6
|
|
|
7
|
-
// src/
|
|
7
|
+
// src/events/issue.ts
|
|
8
8
|
import {
|
|
9
|
-
|
|
9
|
+
eventMatchFieldsSchema
|
|
10
10
|
} from "@sentry/junior-plugin-api";
|
|
11
11
|
var LINEAR_ISSUE_EVENTS = ["issue.created"];
|
|
12
|
-
var LINEAR_ISSUE_MATCH_FIELDS =
|
|
12
|
+
var LINEAR_ISSUE_MATCH_FIELDS = eventMatchFieldsSchema.parse({
|
|
13
13
|
teamKey: {
|
|
14
14
|
kind: "string",
|
|
15
15
|
description: "Linear team key for the issue, such as SRE"
|
|
@@ -35,7 +35,7 @@ function linearTeamResource(input) {
|
|
|
35
35
|
// src/webhooks/handler.ts
|
|
36
36
|
import { createHmac, timingSafeEqual } from "crypto";
|
|
37
37
|
|
|
38
|
-
// src/webhooks/
|
|
38
|
+
// src/webhooks/events.ts
|
|
39
39
|
import { z } from "zod";
|
|
40
40
|
var issueWebhookSchema = z.object({
|
|
41
41
|
action: z.string(),
|
|
@@ -78,7 +78,7 @@ function occurredAtMs(input) {
|
|
|
78
78
|
if (Number.isFinite(input.webhookTimestamp)) return input.webhookTimestamp;
|
|
79
79
|
return Date.now();
|
|
80
80
|
}
|
|
81
|
-
function
|
|
81
|
+
function normalizeLinearEvents(input) {
|
|
82
82
|
if (input.linearEvent.toLowerCase() !== "issue") return [];
|
|
83
83
|
const parsed = issueWebhookSchema.safeParse(input.body);
|
|
84
84
|
if (!parsed.success || parsed.data.action !== "create" || parsed.data.type.toLowerCase() !== "issue") {
|
|
@@ -146,9 +146,9 @@ function createLinearWebhookRoute(args) {
|
|
|
146
146
|
status: 400
|
|
147
147
|
});
|
|
148
148
|
}
|
|
149
|
-
const events =
|
|
149
|
+
const events = normalizeLinearEvents({ body, linearEvent });
|
|
150
150
|
for (const event of events) {
|
|
151
|
-
await args.
|
|
151
|
+
await args.events.publish(event);
|
|
152
152
|
}
|
|
153
153
|
return new Response(events.length ? "Accepted" : "Ignored", {
|
|
154
154
|
status: 200
|
|
@@ -195,7 +195,7 @@ async function annotateCreatedIssue(ctx) {
|
|
|
195
195
|
function linearPlugin() {
|
|
196
196
|
return defineJuniorPlugin({
|
|
197
197
|
packageName: "@sentry/junior-linear",
|
|
198
|
-
|
|
198
|
+
events: {
|
|
199
199
|
resourceTypes: [
|
|
200
200
|
{
|
|
201
201
|
type: "issue",
|
|
@@ -231,7 +231,7 @@ function linearPlugin() {
|
|
|
231
231
|
routes(ctx) {
|
|
232
232
|
return [
|
|
233
233
|
createLinearWebhookRoute({
|
|
234
|
-
|
|
234
|
+
events: ctx.events,
|
|
235
235
|
webhookSecret: linearWebhookSecret
|
|
236
236
|
})
|
|
237
237
|
];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { PluginRoute,
|
|
2
|
-
/** Create the public, signed Linear
|
|
1
|
+
import type { PluginRoute, EventPublisher } from "@sentry/junior-plugin-api";
|
|
2
|
+
/** Create the public, signed Linear event webhook route. */
|
|
3
3
|
export declare function createLinearWebhookRoute(args: {
|
|
4
|
-
|
|
4
|
+
events: EventPublisher;
|
|
5
5
|
webhookSecret(): string | undefined;
|
|
6
6
|
}): PluginRoute;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/junior-linear",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.208.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"zod": "^4.5.4",
|
|
26
|
-
"@sentry/junior-plugin-api": "0.
|
|
26
|
+
"@sentry/junior-plugin-api": "0.208.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@oxlint/plugins": "1.79.0",
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { ResourceEventInput } from "@sentry/junior-plugin-api";
|
|
2
|
-
/** Normalize one verified Linear webhook into issue- and team-scoped events. */
|
|
3
|
-
export declare function normalizeLinearResourceEvents(input: {
|
|
4
|
-
body: unknown;
|
|
5
|
-
linearEvent: string;
|
|
6
|
-
}): ResourceEventInput[];
|
|
File without changes
|