Skip to content

Commit 26152fc

Browse files
authored
Sentry integration (#171)
1 parent b3f2961 commit 26152fc

File tree

2 files changed

+349
-2
lines changed

2 files changed

+349
-2
lines changed

mint.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,9 @@
120120
"group": "Integrations",
121121
"pages": [
122122
"self-hosting/govern/integrations/github",
123-
"self-hosting/govern/integrations/slack",
124-
"self-hosting/govern/integrations/gitlab"
123+
"self-hosting/govern/integrations/gitlab",
124+
"self-hosting/govern/integrations/sentry",
125+
"self-hosting/govern/integrations/slack"
125126
]
126127
},
127128
"self-hosting/govern/external-secrets",
Lines changed: 346 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,346 @@
1+
---
2+
title: Set up Sentry integration for self-hosted Plane
3+
sidebarTitle: Sentry
4+
description: Configure Sentry error tracking and issue creation for your self-hosted Plane instance by creating a custom integration and connecting it to your workspace.
5+
---
6+
7+
This guide shows you how to set up Sentry integration for your self-hosted Plane instance. Unlike Plane Cloud where Sentry comes pre-configured, self-hosted instances require you to create a custom integration in Sentry and configure your Plane deployment with the necessary credentials.
8+
9+
<Note>
10+
**What you'll accomplish:**
11+
1. Create a Sentry custom integration with proper permissions and webhooks
12+
2. Configure your Plane instance with Sentry credentials
13+
3. Enable error tracking and automatic issue creation from Sentry alerts
14+
</Note>
15+
16+
## Before you begin
17+
18+
You'll need:
19+
- Administrator access to your Sentry organization
20+
- Access to your Plane instance configuration files
21+
- Your Plane instance domain (e.g., `plane.yourcompany.com`)
22+
23+
## Create Sentry custom integration
24+
25+
A custom integration (also called a public integration) connects your Sentry organization to Plane, enabling bidirectional communication for issue tracking and alert handling.
26+
27+
1. Log in to your Sentry organization.
28+
2. Go to **Settings****Developer Settings****Custom Integrations**.
29+
3. Click **Create New Integration**.
30+
4. Select **Public Integration**.
31+
5. Fill in these fields on the integration creation screen:
32+
33+
| Field | Value |
34+
|-------|-------|
35+
| **Name** | `Plane` (or any name you prefer) |
36+
| **Author** | Your organization name |
37+
| **Webhook URL** | `https://[YOUR_DOMAIN]/silo/api/sentry/sentry-webhook/` |
38+
| **Redirect URL** | `https://[YOUR_DOMAIN]/silo/api/oauth/sentry/auth/callback` |
39+
| **Verify Installation** | Disabled (recommended) |
40+
| **Alert Rule Action** | Enabled |
41+
42+
<Note>
43+
Replace `[YOUR_DOMAIN]` with your actual Plane instance domain. For example, if your Plane instance is at `plane.company.com`, your Webhook URL would be `https://plane.company.com/silo/api/sentry/sentry-webhook/`
44+
</Note>
45+
46+
![Public integration](/images/sentry/public-integration.webp)
47+
48+
**Field explanations:**
49+
50+
**Webhook URL**
51+
Sentry sends event notifications to this endpoint. Plane processes these webhooks to sync Sentry issues with Plane work items.
52+
53+
**Redirect URL**
54+
After OAuth authorization, Sentry redirects users back to this URL to complete the connection.
55+
56+
**Alert Rule Action**
57+
Enables automatic Plane work item creation when Sentry alert rules trigger.
58+
59+
### Configure integration schema
60+
61+
The schema defines how Sentry and Plane interact—what fields appear when creating issues and how alert rules behave.
62+
63+
Paste this schema into the **Schema** field:
64+
```json
65+
{
66+
"elements": [
67+
{
68+
"link": {
69+
"uri": "/api/sentry/issues/link",
70+
"required_fields": [
71+
{
72+
"uri": "/api/sentry/issues",
73+
"name": "identifier",
74+
"type": "select",
75+
"label": "Issue",
76+
"skip_load_on_open": true
77+
}
78+
]
79+
},
80+
"type": "issue-link",
81+
"create": {
82+
"uri": "/api/sentry/issues/create",
83+
"optional_fields": [
84+
{
85+
"uri": "/api/sentry/users",
86+
"name": "assignee_ids",
87+
"type": "select",
88+
"async": false,
89+
"label": "Assignees",
90+
"multiple": true,
91+
"depends_on": ["project_id"]
92+
},
93+
{
94+
"uri": "/api/sentry/priorities",
95+
"name": "priorities",
96+
"type": "select",
97+
"async": false,
98+
"label": "Priorities",
99+
"depends_on": ["project_id"]
100+
},
101+
{
102+
"uri": "/api/sentry/labels",
103+
"name": "labels",
104+
"type": "select",
105+
"async": false,
106+
"label": "Labels",
107+
"multiple": true,
108+
"depends_on": ["project_id"]
109+
},
110+
{
111+
"uri": "/api/sentry/states",
112+
"name": "state",
113+
"type": "select",
114+
"async": false,
115+
"label": "State",
116+
"depends_on": ["project_id"]
117+
},
118+
{
119+
"uri": "/api/sentry/modules",
120+
"name": "module",
121+
"type": "select",
122+
"async": false,
123+
"label": "Module",
124+
"depends_on": ["project_id"]
125+
},
126+
{
127+
"uri": "/api/sentry/cycles",
128+
"name": "cycle",
129+
"type": "select",
130+
"async": false,
131+
"label": "Cycle",
132+
"depends_on": ["project_id"]
133+
}
134+
],
135+
"required_fields": [
136+
{
137+
"name": "title",
138+
"type": "text",
139+
"label": "Title",
140+
"default": "issue.title"
141+
},
142+
{
143+
"name": "description",
144+
"type": "textarea",
145+
"label": "Description",
146+
"default": "issue.description"
147+
},
148+
{
149+
"uri": "/api/sentry/projects",
150+
"name": "project_id",
151+
"type": "select",
152+
"async": false,
153+
"label": "Project"
154+
}
155+
]
156+
}
157+
},
158+
{
159+
"type": "alert-rule-action",
160+
"title": "Create Plane Work Item or Intake Issue",
161+
"settings": {
162+
"uri": "/api/sentry/alert-rule",
163+
"type": "alert-rule-settings",
164+
"description": "Create a Plane Work Item or Intake Issue when an alert is triggered",
165+
"optional_fields": [
166+
{
167+
"uri": "/api/sentry/users",
168+
"name": "assignee_ids",
169+
"type": "select",
170+
"async": false,
171+
"label": "Assignees",
172+
"multiple": true,
173+
"depends_on": ["project_id"]
174+
},
175+
{
176+
"uri": "/api/sentry/states",
177+
"name": "state",
178+
"type": "select",
179+
"async": false,
180+
"label": "State",
181+
"depends_on": ["project_id"]
182+
},
183+
{
184+
"uri": "/api/sentry/labels",
185+
"name": "labels",
186+
"type": "select",
187+
"async": false,
188+
"label": "Labels",
189+
"multiple": true,
190+
"depends_on": ["project_id"]
191+
}
192+
],
193+
"required_fields": [
194+
{
195+
"name": "type",
196+
"type": "select",
197+
"label": "Type",
198+
"options": [
199+
["intake", "Intake"],
200+
["work_item", "Work Item"]
201+
]
202+
},
203+
{
204+
"uri": "/api/sentry/projects",
205+
"name": "project_id",
206+
"type": "select",
207+
"async": false,
208+
"label": "Project",
209+
"depends_on": ["type"]
210+
}
211+
]
212+
}
213+
}
214+
]
215+
}
216+
```
217+
218+
**What this schema enables**
219+
220+
**Work item linking**
221+
The first element defines how users create new Plane work items from Sentry or link existing ones. Required fields (title, description, project) ensure every work item has essential information. Optional fields (assignees, priority, labels, state, module, cycle) provide flexibility for detailed work item tracking.
222+
223+
**Alert rule actions**
224+
The second element enables automatic work item creation when Sentry alerts fire. You can configure whether alerts create regular work items or intake work items for triage, and set default assignees, states, and labels.
225+
226+
### Set permissions
227+
228+
Configure these permissions to allow Sentry to interact with Plane appropriately:
229+
230+
| Permission | Access Level | Why This Matters |
231+
|------------|--------------|------------------|
232+
| **Project** | Read | Access project details, tags, and debug files from Sentry |
233+
| **Team** | Read | Retrieve team member lists for assignee dropdowns |
234+
| **Release** | No Access | Not required for Plane integration |
235+
| **Distribution** | No Access | Not required for Plane integration |
236+
| **Issue & Event** | Read & Write | Create and link issues, sync status updates bidirectionally |
237+
| **Organization** | Read | Resolve organization IDs and retrieve repository information |
238+
| **Member** | Read | Access member details for assignee functionality |
239+
| **Alerts** | Read | Enable alert rule actions for automatic issue creation |
240+
241+
![Sentry integration permissions](/images/sentry/sentry-permissions.webp)
242+
243+
### Enable webhooks
244+
245+
Webhooks keep Plane and Sentry synchronized. When issues change in Sentry, Plane receives notifications and updates accordingly.
246+
247+
Enable the **issue** webhook with these events:
248+
249+
| Event | Why It's Needed |
250+
|-------|-----------------|
251+
| **created** | Notify Plane when new Sentry issues are detected |
252+
| **resolved** | Update linked Plane work items when Sentry issues are resolved |
253+
| **assigned** | Sync assignee changes from Sentry to Plane |
254+
| **archived** | Reflect archived status in Plane |
255+
| **unresolved** | Update Plane when resolved issues reopen |
256+
257+
![Sentry webhook configuration](/images/sentry/sentry-webhook-config.webp)
258+
259+
### Save and retrieve credentials
260+
261+
After saving your integration, Sentry generates OAuth credentials:
262+
263+
- **Client ID** - A public identifier for your integration
264+
- **Client Secret** - A private key used to authenticate API requests
265+
266+
<Warning>
267+
**Important**
268+
The Client Secret is only displayed once immediately after creating the integration. Copy it now and store it securely. If you lose it, you'll need to regenerate the integration.
269+
</Warning>
270+
271+
Copy both the Client ID and Client Secret. You'll need these in the next step.
272+
273+
## Configure your Plane instance
274+
275+
Add Sentry credentials to your Plane instance so it can communicate with Sentry's API.
276+
277+
### Locate your configuration file
278+
279+
**For Docker deployments:**
280+
- Edit `plane.env` in your Plane installation directory
281+
282+
**For Kubernetes deployments:**
283+
- Edit your `custom-values.yaml` file or ConfigMap containing environment variables
284+
285+
### Add environment variables
286+
287+
Add these variables to your Plane configuration:
288+
289+
**For Docker (`plane.env`):**
290+
```env
291+
# Sentry Integration
292+
SENTRY_BASE_URL=https://sentry.io
293+
SENTRY_CLIENT_ID=<your_client_id>
294+
SENTRY_CLIENT_SECRET=<your_client_secret>
295+
SENTRY_INTEGRATION_SLUG=plane
296+
```
297+
298+
**For Kubernetes (`custom-values.yaml`):**
299+
```yaml
300+
env:
301+
silo_envs:
302+
sentry_base_url: 'https://sentry.io'
303+
sentry_client_id: '<your_client_id>'
304+
sentry_client_secret: '<your_client_secret>'
305+
sentry_integration_slug: 'plane'
306+
```
307+
308+
Replace `<your_client_id>` and `<your_client_secret>` with the credentials from Step 1.
309+
310+
### Environment variable reference
311+
312+
| Variable | Required | Default | Description |
313+
|----------|----------|---------|-------------|
314+
| `SENTRY_BASE_URL` | No | `https://sentry.io` | Base URL of your Sentry instance. For self-hosted Sentry, use your Sentry domain (e.g., `https://sentry.company.com`) |
315+
| `SENTRY_CLIENT_ID` | Yes | - | Client ID from your Sentry custom integration |
316+
| `SENTRY_CLIENT_SECRET` | Yes | - | Client Secret from your Sentry custom integration (only shown once during creation) |
317+
| `SENTRY_INTEGRATION_SLUG` | No | - | The slug identifier for your integration. Find this in your integration's URL: `https://org.sentry.io/settings/developer-settings/plane-local` (here `plane-local` is the slug) |
318+
319+
<Note>
320+
**Using self-hosted Sentry?**
321+
If you're running your own Sentry instance, change `SENTRY_BASE_URL` to your Sentry domain. All other configuration remains the same.
322+
</Note>
323+
324+
### Restart Plane
325+
326+
Apply the configuration changes:
327+
328+
**For Docker:**
329+
```bash
330+
docker compose down
331+
docker compose up -d
332+
```
333+
334+
**For Kubernetes:**
335+
```bash
336+
helm upgrade plane-app plane-enterprise.tgz \
337+
--namespace plane \
338+
-f custom-values.yaml
339+
```
340+
341+
## Activate integration in your workspace
342+
343+
Once you’ve completed the instance configuration, [activate the Sentry integration](https://docs.plane.so/integrations/sentry#set-up-sentry-integration) in Plane.
344+
345+
346+
For questions about Sentry integration, contact [[email protected]](mailto:[email protected]).

0 commit comments

Comments
 (0)