@@ -318,3 +318,87 @@ sentry issue ignore CLI-G5 --until auto
318318| ` 10users/2hours ` | 10 users within 2 hours |
319319| * (omitted)* | Archive forever |
320320:::
321+
322+ ### Link an external issue
323+
324+ Link an existing tracker issue or GitHub pull request to a Sentry issue:
325+
326+ ``` bash
327+ sentry issue link FRONT-123 https://github.com/example/app/issues/42
328+ sentry issue link FRONT-123 https://github.com/example/app/pull/43
329+ sentry issue link FRONT-123 https://example.atlassian.net/browse/APP-42
330+ sentry issue link FRONT-123 https://linear.app/example/issue/APP-42/fix-error
331+ ```
332+
333+ The matching integration must already be installed in the Sentry organization.
334+ Linking requires a Sentry version with native issue URL resolution and guarded
335+ Sentry App callbacks; older self-hosted versions may require an upgrade.
336+ Native integrations include GitHub, GitHub Enterprise, Jira, Jira Server,
337+ GitLab, Bitbucket, and Azure DevOps. Linear uses its installed Sentry App.
338+ Sentry resolves native issue URLs through the selected integration; the remote
339+ issue must be visible to that installation.
340+ Use ` --integration <id> ` if more than one native integration matches the URL.
341+ Other Sentry Apps require ` --app <slug> ` and must expose an issue-link form;
342+ additional required form values can be supplied with ` --field name=value ` .
343+ For other Apps, an issue select can be supplied by exact ID or label with
344+ ` --field ` , for example ` --app custom --field task_id=123 ` . Sentry checks
345+ that the app's callback identifies the requested URL before saving the association.
346+
347+ ``` bash
348+ sentry issue link my-org/FRONT-123 https://github.com/example/app/issues/42 --dry-run
349+ sentry issue link my-org/FRONT-123 https://github.com/example/app/issues/42 --json
350+ ```
351+
352+ ` --dry-run ` discovers the integration and prepares the link without submitting a
353+ write. The provider validates the remote issue when the link is submitted.
354+ An existing matching link succeeds with ` changed: false ` . A Sentry App that
355+ already links this issue to a different resource must be unlinked first.
356+ App callbacks must return the exact supplied URL; use the issue URL copied from
357+ the tracker, including its title suffix. A mismatch fails without saving the link.
358+
359+ GitHub and GitHub Enterprise pull requests are stored as external references.
360+ Their ` /pull/NUMBER ` and ` /issues/NUMBER ` URLs identify the same resource for
361+ duplicate detection and unlinking. Linking a PR does not mark it as a fix or
362+ resolve the Sentry issue.
363+
364+ This command does not create a tracker issue or link a commit. Existing
365+ integration status-sync settings continue to apply after linking.
366+
367+ #### Link permissions
368+
369+ Linking requires ` event:write ` and access to the Sentry project. Discovering
370+ Sentry Apps also requires ` org:read ` . Both scopes are included in the default
371+ OAuth login. If an older OAuth session lacks the
372+ requested scopes, the CLI offers reauthorization after a permission error.
373+ Use ` sentry auth login ` to request the current default scopes. Environment tokens must
374+ be updated separately.
375+
376+ ### Unlink an external issue
377+
378+ Remove an association without deleting either issue:
379+
380+ ``` bash
381+ sentry issue unlink FRONT-123 https://github.com/example/app/issues/42
382+ sentry issue unlink FRONT-123 https://github.com/example/app/pull/43 --yes
383+ sentry issue unlink my-org/FRONT-123 https://example.atlassian.net/browse/APP-42 --yes
384+ sentry issue unlink FRONT-123 https://linear.app/example/issue/APP-42/fix-error --dry-run
385+ ```
386+
387+ Use ` --yes ` for non-interactive execution. ` --dry-run ` shows whether the link
388+ exists without removing it. If the association is already absent, the command
389+ succeeds with ` changed: false ` .
390+
391+ Unlink matches the URL against stored associations and sends Sentry's internal
392+ link ID to the existing DELETE endpoint. It does not require fetching the ticket
393+ from the remote tracker, so a deleted remote ticket can still be unlinked.
394+ For a custom Sentry App, select it with ` --app <slug> ` ; unlink does not require
395+ the app to expose a link form. Use ` --integration <id> ` to disambiguate native
396+ integration links.
397+
398+ #### Unlink permissions
399+
400+ Unlink requires ** ` event:write ` and access to the Sentry project** ; ` event:admin `
401+ is also accepted. The organization's “Let Members Delete Events” setting does
402+ not restrict unlinking on updated Sentry versions.
403+
404+ Granting a token more scopes does not override project-access policy.
0 commit comments