Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions flaky-tests/webhooks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: Use webhooks to automate custom flaky test workflows

# Webhooks

Trunk provides webhooks for you to build custom integrations to automate workflows, like notifying your team when a test becomes flaky or automatically creating tickets to investigate flaky tests. Trunk already provides a Jira integration, and more are planned. Webhooks lets you build custom integrations for use cases that are not supported out of the box.
Trunk provides webhooks for you to build custom integrations to automate workflows, like notifying your team when a test becomes flaky or automatically creating tickets to investigate flaky tests. Trunk provides built-in connectors for [Linear](linear-integration.md) and [Jira](jira-integration.md) to automate ticket creation, and webhooks lets you build custom integrations for use cases that are not supported out of the box.

[Svix](https://docs.svix.com/) powers webhooks for Trunk. You'll be using Svix to configure webhooks and you should familiarize yourself with the [Svix App Portal docs](https://docs.svix.com/app-portal) to learn more.

Expand All @@ -16,4 +16,4 @@ Trunk lets you create custom workflows with **event-triggered webhooks**. Flaky

You can also find guides for specific examples here:

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th data-hidden></th><th data-hidden></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td>Send a Slack Message</td><td></td><td></td><td></td><td><a href="slack-integration.md">slack-integration.md</a></td></tr><tr><td>Create a GitHub Issue</td><td></td><td></td><td></td><td><a href="github-issues-integration.md">github-issues-integration.md</a></td></tr><tr><td>Send a Microsoft Teams Message</td><td></td><td></td><td></td><td><a href="microsoft-teams-integration.md">microsoft-teams-integration.md</a></td></tr><tr><td>Create a Linear Issue</td><td></td><td></td><td></td><td><a href="linear-integration.md">linear-integration.md</a></td></tr></tbody></table>
<table data-card-size="large" data-view="cards"><thead><tr><th></th><th data-hidden></th><th data-hidden></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td>Send a Slack Message</td><td></td><td></td><td></td><td><a href="slack-integration.md">slack-integration.md</a></td></tr><tr><td>Create a GitHub Issue</td><td></td><td></td><td></td><td><a href="github-issues-integration.md">github-issues-integration.md</a></td></tr><tr><td>Send a Microsoft Teams Message</td><td></td><td></td><td></td><td><a href="microsoft-teams-integration.md">microsoft-teams-integration.md</a></td></tr><tr><td>Create a Linear Issue</td><td></td><td></td><td></td><td><a href="linear-integration.md">linear-integration.md</a></td></tr><tr><td>Create a Jira Issue</td><td></td><td></td><td></td><td><a href="jira-integration.md">jira-integration.md</a></td></tr></tbody></table>
195 changes: 195 additions & 0 deletions flaky-tests/webhooks/jira-integration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
---
description: Learn how to automatically create Jira issues with Flaky Test webhooks
---

# Jira integration

Trunk allows you to automate Jira issue creation through webhooks. When a test becomes flaky and impacts enough PRs, a Jira issue is created automatically with full context including failure rates, ownership, and stack traces.

This guide will walk you through integrating Trunk Flaky Tests with Jira through webhooks. You will be able to automatically generate Jira issues for **new flaky tests** found in your repo that **impact more than 2 PRs**. This guide should take 15 minutes to complete.

Trunk also has a [built-in Jira integration](../ticketing-integrations/jira-integration.md) for manual ticket creation. You only need to use webhooks if you want to automate ticket creation or need additional customization.

### 1. Create a Jira API Token

Before you can create a webhook to automate Jira issue creation, you need to create an API token to authorize your requests.

1. Go to [Atlassian API token management](https://id.atlassian.com/manage-profile/security/api-tokens).
2. Click **Create API token**, give it a label (e.g., "Trunk Webhooks"), and click **Create**.
3. Copy the token and save it in a secure location. You'll need it later.

You'll also need to generate a Base64-encoded credential string for authentication. Run this in your terminal:

```bash
echo -n "your-email@example.com:your-api-token" | base64
```

Replace `your-email@example.com` with the email associated with your Jira account and `your-api-token` with the token you just created. Save the output for step 3.

### 2. Add a new webhook in Trunk <a href="#id-2.-add-a-webhook-url-to-the-jira-api-in-trunk" id="id-2.-add-a-webhook-url-to-the-jira-api-in-trunk"></a>

Trunk uses Svix to integrate with other services, such as creating Jira issues through webhooks.

You can create a new endpoint by:

1. Login to [Trunk Flaky Tests](https://app.trunk.io/login?intent=flaky%20tests)
2. From your profile on the top right, navigate to **Settings**
3. Under **Organization > Webhooks**, click **Automate Jira Issues Creation**.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR notes this as an open question — if the Automate Jira Issues Creation button doesn't exist in the Svix UI (unlike the Linear connector), users would need to create a generic endpoint instead. Worth confirming with Tyler that this specific button is live before this page gets traffic.

4. Set the **Endpoint URL** to your Jira Cloud REST API endpoint: `https://<your-domain>.atlassian.net/rest/api/2/issue`. Replace `<your-domain>` with your Jira Cloud domain (e.g., `acme` if your Jira URL is `acme.atlassian.net`).
5. Review the transformation code automatically generated for Jira issues. You can customize this transformation at any time. Learn more about [customizing transformations](#5-customize-your-transformation).
6. Create the new endpoint. You will be redirected to the endpoint configuration view.

If you're having trouble adding a new webhook endpoint with Svix, please see the [Adding Endpoint docs from Svix](https://docs.svix.com/receiving/using-app-portal/adding-endpoints).

### 3. Add custom headers

The Jira REST API requires authentication headers. You can configure custom headers in the endpoint configuration:

1. Navigate to **Webhooks > Advanced > Custom Headers.**
2. Fill in the **Key** and **Value** referencing the table below, and click the **+** button to add each header.

You'll need to configure the following headers:

| Key | Value |
| --------------- | ------------------------ |
| `Authorization` | `Basic <BASE64_TOKEN>` |
| `Content-Type` | `application/json` |

Replace `<BASE64_TOKEN>` with the Base64-encoded string you generated in [step 1](#1-create-a-jira-api-token).

### 4. Find your Jira project key and issue type

You'll need your Jira project key and preferred issue type to configure the transformation.

**Project key:** This is the short prefix on your Jira issues (e.g., `ENG`, `PROJ`, `KAN`). You can find it in the URL when viewing your Jira project: `https://your-domain.atlassian.net/jira/software/projects/<PROJECT_KEY>/board`.

**Issue type:** The type of issue to create. Common values are `Bug`, `Task`, or `Story`. The default is `Bug`.

### 5. Customize your transformation

Transformations are custom code snippets you can write to customize the Jira issues created by the webhook. A working template transformation will be added automatically for your webhook, but you can further customize the behavior.

1. In the endpoint configuration view, navigate to the **Advanced** tab. Under **Transformation**, toggle the **Enabled** switch.
2. Click **Edit transformation** to update your transformation code, and click **Save** to update the transformation.
3. You can test the transformation by selecting the `test_case.status_changed` payload and clicking **Run Test**. This will test the transformation but not send a message. You will learn to send a test message [in step 6](#6-test-your-webhook).

The generated webhook template contains several configurable constants out of the box:

<table><thead><tr><th width="346">Constant</th><th>Description</th></tr></thead><tbody><tr><td><code>JIRA_PROJECT_KEY</code></td><td>(<strong>Required)</strong> Your Jira project key (e.g., <code>ENG</code>, <code>PROJ</code>).</td></tr><tr><td><code>JIRA_ISSUE_TYPE</code></td><td><strong>(Optional)</strong> The issue type to create. Defaults to <code>Bug</code>.</td></tr><tr><td><code>JIRA_LABELS</code></td><td>(<strong>Optional)</strong> Array of labels to add to the issue. Defaults to <code>["flaky-test"]</code>.</td></tr><tr><td><code>JIRA_CUSTOM_FIELDS</code></td><td>(<strong>Optional)</strong> Object of custom field key-value pairs for projects that require additional fields.</td></tr><tr><td><code>PRS_IMPACTED_THRESHOLD</code></td><td>Issues will be created only for flaky tests that have impacted more PRs than the <code>PRS_IMPACTED_THRESHOLD</code>.<br><br>You can adjust this value if you see many issues about low-impact flaky tests.</td></tr></tbody></table>

Here is the provided transformation for context. You can customize your Jira issues integration by following the [Jira REST API docs](https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issues/#api-rest-api-2-issue-post) and [Svix transformations](https://docs.svix.com/transformations#using-transformations) documentation.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor phrasing nit — "Here is the provided transformation for context" is slightly awkward.

Suggested change
Here is the provided transformation for context. You can customize your Jira issues integration by following the [Jira REST API docs](https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issues/#api-rest-api-2-issue-post) and [Svix transformations](https://docs.svix.com/transformations#using-transformations) documentation.
Here is the default transformation code for reference. You can customize your Jira issues integration by following the [Jira REST API docs](https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issues/#api-rest-api-2-issue-post) and [Svix transformations](https://docs.svix.com/transformations#using-transformations) documentation.


{% hint style="info" %}
The default transformation only creates issues when `newStatus === "flaky"`. If you also want to create issues for tests marked as **Broken** (consistently failing at a high rate), update the filter condition. For example, change `newStatus !== "flaky"` to `newStatus !== "flaky" && newStatus !== "broken"` to handle both statuses.
{% endhint %}

```javascript
/**
* @param webhook the webhook object
* @param webhook.method destination method. Allowed values: "POST", "PUT"
* @param webhook.url current destination address
* @param webhook.eventType current webhook Event Type
* @param webhook.payload JSON payload
* @param webhook.cancel whether to cancel dispatch of the given webhook
*/

// Your Jira project key (e.g., "PROJ", "ENG"). This is required!
const JIRA_PROJECT_KEY = "";
// The Jira issue type to create (e.g., "Bug", "Task", "Story"). Defaults to "Bug".
const JIRA_ISSUE_TYPE = "Bug";
// Labels to add to the Jira issue. Optional.
const JIRA_LABELS = ["flaky-test"];

// Add any custom required fields your Jira project needs. Optional.
// Example: { "customfield_10042": { "value": "Platform" }, "customfield_10043": "some-value" }
const JIRA_CUSTOM_FIELDS = {};

// At least this many PRs need to be impacted for an issue to be created.
const PRS_IMPACTED_THRESHOLD = 2;

function handler(webhook) {
const impacted_prs = webhook.payload.test_case.pull_requests_impacted_last_7d;
const newStatus = webhook.payload.status_change.current_status.value;

// Filter for only flaky tests that impact more than the provided threshold
if (newStatus !== "flaky" || impacted_prs < PRS_IMPACTED_THRESHOLD) {
webhook.payload = "canceled";
webhook.cancel = true;
return webhook;
}

const description = summarizeTestCase(webhook.payload);

webhook.payload = {
fields: {
project: { key: JIRA_PROJECT_KEY },
issuetype: { name: JIRA_ISSUE_TYPE },
summary: `Flaky Test: ${webhook.payload.test_case.name}`,
description: description,
labels: JIRA_LABELS,
...JIRA_CUSTOM_FIELDS,
},
};
return webhook;
}

function summarizeTestCase(payload) {
const {
status_change: { previous_status },
test_case: {
name, file_path, status, quarantine, repository, codeowners,
failure_rate_last_7d, most_common_failures,
pull_requests_impacted_last_7d, ticket, html_url
}
} = payload;

const issueBody = `See all details on the [Trunk Test Detail page|${html_url}]

Transition time: ${status.timestamp}

Severity (last 7 days): ${(failure_rate_last_7d * 100).toFixed(2)}% failure rate; impacting ${pull_requests_impacted_last_7d} PRs

Ownership: this test is owned by ${(codeowners || ['@unassigned']).join(', ')}

----
*The most common failure reasons (out of ${most_common_failures.length} identified) are:*

${most_common_failures.map((failure, index) => {
return `*Reason #${index + 1}*: "${failure.summary}" \n`
}).join('')}

View the full stack trace on the [Test Detail page|${html_url}]
`;
return issueBody;
}
```

{% hint style="info" %}
The description uses [Jira wiki markup](https://jira.atlassian.com/secure/WikiRendererHelpAction.jspa?section=texteffects) for formatting. Links use the `[text|url]` syntax rather than markdown.
{% endhint %}

### 6. Test your webhook

You can create test issues by delivering a mock webhook. You can do this by:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: "You can … You can do this by:" is slightly repetitive.

Suggested change
You can create test issues by delivering a mock webhook. You can do this by:
Send a test Jira issue by delivering a mock webhook:


1. In the endpoint configuration view, navigate to the **Testing** tab and select a **Send event**
2. Under **Subscribed events,** select `test_case.status_changed` as the event type to send
3. Click **Send Example** to test your webhook

### 7. Monitoring webhooks

You can monitor the events and the webhook's delivery logs in the **Overview** tab of an endpoint configuration view.

You can see an overview of how many webhook deliveries have been attempted, how many are successful, how many are in flight, and how many fail in the **Attempt Delivery Status** modal.

You can see a list of past delivery attempts in the **Message Attempts** modal. You can filter this list by **Succeeded** and **Failed** status, and you can click on each message to see the **Message content**, response code, and error message of each attempt. You can learn more about [replaying messages](https://docs.svix.com/receiving/using-app-portal/replaying-messages) and [filtering logs](https://docs.svix.com/receiving/using-app-portal/filtering-logs) in the Svix docs.

### Congratulations!

A Jira issue will now be created when a test's health status changes to **flaky** and **impacts more than 2 PRs**. You can further modify your transformation script to customize your issues.

[See the Trunk webhook event catalog](https://www.svix.com/event-types/us/org_2eQPL41Ew5XSHxiXZIamIUIXg8H/#test_case.status_changed)

[Learn more about consuming webhooks in the Svix docs](https://docs.svix.com/receiving/introduction)

[Learn more about Jira's REST API](https://developer.atlassian.com/cloud/jira/platform/rest/v2/intro/)
1 change: 1 addition & 0 deletions summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
* [Microsoft Teams integration](flaky-tests/webhooks/microsoft-teams-integration.md)
* [GitHub Issues integration](flaky-tests/webhooks/github-issues-integration.md)
* [Linear integration](flaky-tests/webhooks/linear-integration.md)
* [Jira integration](flaky-tests/webhooks/jira-integration.md)
* [Flaky Tests API](flaky-tests/flaky-tests.md)
* [Trunk Analytics CLI](flaky-tests/uploader.md)
* [Use MCP Server](flaky-tests/use-mcp-server/README.md)
Expand Down
Loading