Skip to content
Open
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
60 changes: 60 additions & 0 deletions flaky-tests/webhooks.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,66 @@ Trunk lets you create custom workflows with **event-triggered webhooks**. Flaky
Open the referenced resource in a new tab.
</Card>

Trunk publishes three Flaky Tests event types to Svix. Each event includes a full JSON schema with field descriptions visible in the Svix app portal.

#### `test_case.monitor_status_changed`

Emitted when a monitor activates or resolves for a test case.

| Field | Type | Description |
|---|---|---|
| `type` | string | Always `test_case.monitor_status_changed` |
| `timestamp` | string (ISO 8601) | When the event occurred |
| `monitor.id` | string (UUID) | Unique identifier for the monitor |
| `monitor.type` | string | The type of monitor (e.g., `pass_on_retry`) |
| `monitor.status` | string | Current monitor status (`active` or `resolved`) |
| `evidence` | object | Data supporting the status change; structure varies by monitor type |
| `repository.id` | string (UUID) | Unique identifier for the repository |
| `repository.html_url` | string | URL of the repository |
| `test_case.id` | string (UUID) | Stable unique identifier for the test |
| `test_case.name` | string | Name of the test |
| `test_case.classname` | string | Test classname |
| `test_case.file_path` | string | File path of the test |
| `test_case.html_url` | string | URL to the test detail page in Trunk |
| `test_case.codeowners` | array of strings | Code owners associated with the test |
| `test_case.quarantined` | boolean | Whether the test is quarantined |
| `test_case.variant` | string | Test variant name |

#### `v2.test_case.status_changed`

Emitted when a test case changes status (e.g., becomes flaky or is resolved), as triggered by a monitor.

| Field | Type | Description |
|---|---|---|
| `type` | string | Always `v2.test_case.status_changed` |
| `timestamp` | string (ISO 8601) | When the event occurred |
| `previous_status` | string | The prior status of the test case |
| `new_status` | string | The updated status of the test case |
| `triggered_by.monitor_id` | string (UUID) | Unique identifier of the triggering monitor |
| `triggered_by.monitor_type` | string | Type of monitor that triggered the change |
| `triggered_by.monitor_status` | string | Status of the monitor at the time of the trigger |
| `repository` | object | See `repository` fields above |
| `test_case` | object | See `test_case` fields above |

#### `test_case.investigation_completed`

Emitted when an AI-powered flaky test analysis finishes for a test case.

| Field | Type | Description |
|---|---|---|
| `type` | string | Always `test_case.investigation_completed` |
| `investigation_id` | string (UUID) | Unique identifier for the investigation |
| `confidence` | number | Overall confidence score (0-1) for the findings |
| `created_at` | string (ISO 8601) | When the investigation completed |
| `markdown_summary` | string | Markdown-formatted summary of findings and recommendations |
| `failure_message` | string | The original failure message that triggered the investigation |
| `facts` | array | Facts discovered during the investigation |
| `facts[].fact_type` | string | Category of the fact (e.g., `GIT_BLAME`) |
| `facts[].content` | string | Detailed description with citations to supporting evidence |
| `facts[].confidence` | number | Confidence score (0-1) for this individual fact |
| `repository` | object | See `repository` fields above |
| `test_case` | object | See `test_case` fields above |

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="/flaky-tests/webhooks/slack-integration">slack-integration</a></td></tr><tr><td>Create a GitHub Issue</td><td></td><td></td><td></td><td><a href="/flaky-tests/webhooks/github-issues-integration">github-issues-integration</a></td></tr><tr><td>Send a Microsoft Teams Message</td><td></td><td></td><td></td><td><a href="/flaky-tests/webhooks/microsoft-teams-integration">microsoft-teams-integration</a></td></tr><tr><td>Create a Linear Issue</td><td></td><td></td><td></td><td><a href="/flaky-tests/webhooks/linear-integration">linear-integration</a></td></tr></tbody></table>
43 changes: 43 additions & 0 deletions merge-queue/administration/metrics.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,46 @@ The time in queue can be displayed as different statistical measures. You can sh
| P95 | The value below 95% of the time in queue falls. |
| P99 | The value below 99% of the time in queue falls. |

### Drill down into metrics

From the **Conclusion count** and **Time in queue** charts, you can drill into any point or window on the graph to see the exact pull requests that made up those numbers.

#### Why drill down?

Aggregated charts tell you *that* something happened — drilling down tells you *which PRs* caused it. This makes it easy to:

* **Track down outliers** — if the P99 on Time in queue spikes, drill into that bucket to find the specific PR that dragged the tail out.
* **Investigate failure spikes** — click a bar on Conclusion count where failures jumped and see exactly which PRs failed and why.
* **Audit a time window** — pull the full list of PRs merged, failed, or canceled during an incident window or release cut.
* **Answer one-off questions** — "which PRs merged between 2pm and 4pm yesterday?" without writing a query against the Prometheus endpoint.

#### Select data points

You have two ways to select:

* **Click a single data point** to see the PRs in that time bucket.
* **Click and drag across the chart** to select a range of data points spanning multiple time buckets. The selected range stays highlighted and the rest of the chart dims, giving you a focused view of just that window. The same range syncs across both charts so you can correlate Conclusion count and Time in queue data for the period you picked.

Once a selection is made, a **View PRs** button appears. Click it to open the list of PRs that make up the selection.

To pick a different window, drag a new selection. To clear the selection, change the time range, time bucket, or **Time in UTC** setting at the top of the dashboard.

#### Review the PR list

The PR list page shows every PR included in your selection, along with:

* **Conclusion** — whether the PR merged, failed, or was cancelled.
* **Reason** — the specific cause behind the conclusion (for example, Merged by Trunk, Required status failed, PR closed). See the [Conclusion count](#conclusion-count) table for the full list.
* **Time in queue** — how long the PR spent in the merge queue from entry to exit.

Both columns are sortable, so you can quickly surface the longest-running PRs in a window or group all failures of the same type together.

The PR list page shows the selected date range as a subtitle and a **Back to Health** link to return to the charts. If the selection contains more than 2,500 PRs, the list shows the first 2,500 with a notice indicating the total. Narrow the time bucket on the chart to drill into a smaller window.

<Info>
Drill down and range selection are currently available on the Conclusion count and Time in queue charts. Additional Health charts will support the same interactions as they land in the UI.
</Info>

---

### Prometheus metrics endpoint
Expand Down Expand Up @@ -164,8 +204,11 @@ These metrics summarize activity over a sliding 1-hour window. They update conti
| `mq_pr_restarts_1h_total` | Gauge | — | PR restarts (TESTING to PENDING transitions) in the last hour |
| `mq_pr_wait_duration_1h_seconds` | Histogram | `le` (bucket boundary) | Distribution of time PRs spent waiting before testing starts |
| `mq_pr_test_duration_1h_seconds` | Histogram | `le` (bucket boundary) | Distribution of time PRs spent in the testing phase |
| `mq_pr_time_in_queue_1h_seconds` | Histogram | `le` (bucket boundary) | Distribution of total time PRs spent in the queue, from entry to exit (includes waiting, testing, and any other phases, such as [pending failure](/merge-queue/optimizations/pending-failure-depth)). |
| Each histogram emits `_bucket{le="..."}`, `_sum`, and `_count` series. Bucket boundaries (in seconds): 60, 300, 600, 900, 1800, 3600, 5400, 7200, +Inf. | | | |

For clarity, PRs in the "Waiting to Enter Queue" state (submitted to the queue but still waiting on prerequisites such as GitHub mergeability before they can be admitted to the queue) are not considered to be "in the queue" yet. So any time spent in this state is not counted in the Wait Duration or Time in Queue metrics.

<Warning>
Rolling window metrics use **gauge semantics**, not true Prometheus counters. They represent a snapshot of the last hour, not cumulative totals. PromQL functions like `rate()` and `increase()` are **not meaningful** on these metrics. Use the values directly instead.
</Warning>
Expand Down
17 changes: 17 additions & 0 deletions merge-queue/using-the-queue/monitor-queue-status.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,15 @@ PRs queued at the default medium priority or at low priority do not display a ba

For details on setting priority levels, see [Priority merging](/merge-queue/optimizations/priority-merging).

#### Impacted targets in the graph

When running in [Parallel mode](/merge-queue/optimizations/parallel-queues), the graph view surfaces impacted targets data to help you understand why PRs are grouped or ordered the way they are.

* **Per-PR tooltips**: Hover over a PR node to see which targets that PR impacts.
* **Overlapping targets on edges**: Use the **Show targets on hover** toggle to display which targets overlap between connected PRs. Overlapping targets explain why PRs are in the same testing sequence: PRs with shared targets must be tested together.

This is useful for debugging unexpected queue ordering or understanding why specific PRs are batched together.

### Health view

Select a period of time to inspect using the **Period** dropdown (default 7 days) and a **Granularity** (defaults to daily) of queue metrics
Expand All @@ -94,3 +103,11 @@ When a PR has not been admitted to the queue yet, Trunk Merge Queue waits for:
<figure><img src="https://577236045-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F61Ep9MrYBkJa0Yq3zS1s%2Fuploads%2Fgit-blob-627bff62df4527afcafc2b11e3d471dba63910cb%2Fmerge-details.png?alt=media" alt="" /><figcaption><p>PR readiness details for a PR that has been submitted but has not yet entered the merge queue.</p></figcaption></figure>

In the screenshot above, the PR has been submitted to Merge but has not yet been added to the queue. It will be added once all of the branch protection rules pass and there are no merge conflics with the target branch.

### View impacted targets

In [Parallel mode](/merge-queue/optimizations/parallel-queues), the PR detail page includes a **View Impacted Targets** button when targets have been uploaded for the PR. The modal shows one of three states:

* `IMPACTS_ALL`: The PR depends on everything in the queue, and every PR submitted after this one will depend on it. No parallel optimization is possible.
* **Specific targets**: A list of each target the PR impacts.
* **None (empty list)**: An empty list of targets was uploaded. The PR will not depend on anything, and nothing will depend on it.