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
1 change: 1 addition & 0 deletions docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
"root": "merge-queue/using-the-queue/index",
"pages": [
"merge-queue/using-the-queue/reference",
"merge-queue/using-the-queue/stacked-pull-requests",
"merge-queue/using-the-queue/monitor-queue-status",
"merge-queue/using-the-queue/handle-failed-pull-requests",
"merge-queue/using-the-queue/emergency-pull-requests",
Expand Down
Binary file added images/image-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/image-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/image-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
55 changes: 28 additions & 27 deletions index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,24 @@
title: "Trunk Platform"
description: "Ship Software as Fast as AI Writes It"
og:title: "Trunk Platform Documentation"
icon: "rocket"
---

AI generates code at machine speed, but code review, CI, and delivery still move at human pace. That gap is widening, and it gets worse every time you add another AI agent to the loop.

Trunk enables continuous delivery: any commit on your main branch could be deployed to production. We do this by eliminating the two bottlenecks that prevent it. Flaky tests that waste developer time, and serialized merge queues that cap your throughput.

Teams start with whichever problem hurts more, then expand. Caseware cut merge time from 6 hours to 90 minutes. Zillow eliminated all pipeline blockages from flaky tests. Faire prevented 20% of main branch failures from green-green conflicts.

<Accordion title="Want to see how it works? Have questions?">
[Schedule time here](https://calendly.com/trunk/demo) or email [support@trunk.io](mailto:support@trunk.io)
[Schedule time here](https://calendly.com/trunk/demo) or email [support@trunk.io](mailto:support@trunk.io)
</Accordion>

## Why This Matters Now

You check out `main` on Monday morning, grab your coffee, open a pull request, and CI fails for reasons that have nothing to do with your code. You're reading logs, pinging Slack, trying to figure out who broke what. That happens to every engineer, every day. Continuous delivery means every commit on main is known-good. Every CI failure is yours to fix, not something you inherited.

That problem has existed for years. What makes it urgent now is volume. AI agents are generating 50+ PRs a day, and they hit the same merge queue serialization and flaky test noise that slows humans. Except agents can't context-switch to other work while they wait. Every bottleneck in your CI pipeline that used to cost you hours now costs you days.
That problem has existed for years. What makes it urgent now is volume. AI agents are generating 50\+ PRs a day, and they hit the same merge queue serialization and flaky test noise that slows humans. Except agents can't context-switch to other work while they wait. Every bottleneck in your CI pipeline that used to cost you hours now costs you days.

## Trunk Flaky Tests

Expand All @@ -31,11 +33,11 @@ On the repair side, we're working with design partners on AI-powered fixing thro

## Trunk Merge Queue

Traditional merge queues guarantee main stability by testing PRs one at a time. At 100+ PRs/day, that becomes a bottleneck. Monorepos make this easier to solve. If you have mobile, frontend, and backend code in the same repo, those PRs can test and merge independently because they don't touch the same targets. Linear merge queues don't know that. They put everything in one line.
Traditional merge queues guarantee main stability by testing PRs one at a time. At 100\+ PRs/day, that becomes a bottleneck. Monorepos make this easier to solve. If you have mobile, frontend, and backend code in the same repo, those PRs can test and merge independently because they don't touch the same targets. Linear merge queues don't know that. They put everything in one line.

Trunk's merge queue runs in parallel mode. It knows which targets each PR affects, finds non-overlapping sets, and tests them at the same time. When queue depth grows, it batches multiple PRs into a single CI run and bisects automatically if the batch fails. Anti-flake protection keeps flaky failures from stalling the queue: if a later batch that includes the same code passes, both merge.

Validated at 250+ PRs/hour sustained over 24 hours. Peaked at 300+ simultaneous PRs in parallel testing.
Validated at 250\+ PRs/hour sustained over 24 hours. Peaked at 300\+ simultaneous PRs in parallel testing.

[Full Merge Queue documentation →](./merge-queue/merge-queue)

Expand All @@ -45,35 +47,41 @@ Without flaky test handling, a merge queue backs up every time a test becomes un

## Trusted by

<img className="block dark:hidden" src="/assets/_shared/4x2_Logos_(Light-NoBG).png" alt="" />
<img className="hidden dark:block" src="/assets/_shared/4x2_Logos_(Dark-NoBG).png" alt="" />
<img
className="block dark:hidden"
src="/assets/_shared/4x2_Logos_(Light-NoBG).png"
/>
<img
className="hidden dark:block"
src="/assets/_shared/4x2_Logos_(Dark-NoBG).png"
/>

## Works With Your Stack

* **CI providers**: Works with any CI provider. Common setups include GitHub Actions, GitLab CI, Jenkins, BuildKite, CircleCI, and Azure DevOps. Integrates via CLI that uploads test results from existing pipelines.
* **Languages**: Works with any language. We analyze test output formats, not source code, so there's nothing language-specific to configure.
* **Test frameworks**: Works with any runner that produces JUnit XML, XCResult, or Bazel BEP. That covers Jest, Pytest, XCTest, Cypress, Playwright, RSpec, JUnit, GoogleTest, and most others.
* **Build systems**: Bazel, Nx, Gradle with native impacted-target calculation. API for custom build systems.
* **Integrations**: Full APIs for both products, webhooks with Svix transformations, CLI for local and CI use, Slack notifications, Jira and Linear ticket creation. [API documentation →](./setup-and-administration/apis/)
- **CI providers**: Works with any CI provider. Common setups include GitHub Actions, GitLab CI, Jenkins, BuildKite, CircleCI, and Azure DevOps. Integrates via CLI that uploads test results from existing pipelines.
- **Languages**: Works with any language. We analyze test output formats, not source code, so there's nothing language-specific to configure.
- **Test frameworks**: Works with any runner that produces JUnit XML, XCResult, or Bazel BEP. That covers Jest, Pytest, XCTest, Cypress, Playwright, RSpec, JUnit, GoogleTest, and most others.
- **Build systems**: Bazel, Nx, Gradle with native impacted-target calculation. API for custom build systems.
- **Integrations**: Full APIs for both products, webhooks with Svix transformations, CLI for local and CI use, Slack notifications, Jira and Linear ticket creation. [API documentation →](./setup-and-administration/apis/)

## Why Teams Choose Trunk

**vs. GitHub native merge queue, Bors, Mergify.** Sequential by design. No parallel lane logic, no flake protection, no batching with bisection.

**vs. Datadog, Buildkite Analytics.** They show you flake data but don't quarantine at runtime or integrate with your merge queue. Most stop running quarantined tests entirely, which hides the problem. Trunk keeps running them to collect evidence for root cause analysis.

**vs. building in-house.** Merge queues at scale need parallel graph computation, bisection, and robust GitHub API orchestration. Flaky test detection at 50k+ tests needs real-time ETL, embeddings, and classification. If the engineers who built your internal system leave, you're maintaining deployment-path infrastructure without the knowledge to fix it.
**vs. building in-house.** Merge queues at scale need parallel graph computation, bisection, and robust GitHub API orchestration. Flaky test detection at 50k\+ tests needs real-time ETL, embeddings, and classification. If the engineers who built your internal system leave, you're maintaining deployment-path infrastructure without the knowledge to fix it.

## Getting Started

Most teams schedule a 30-minute call before integrating. We help plan for security reviews, understand your CI architecture, and flag common gotchas.

* [Schedule a call](https://calendly.com/trunk/demo) **← Recommended**
- [Schedule a call](https://calendly.com/trunk/demo) **← Recommended**

Or explore on your own: [Create a Trunk account →](https://app.trunk.io/signup)

* [Flaky Tests Integration Guide](/flaky-tests/get-started)
* [Merge Queue Setup Guide](/merge-queue/getting-started)
- [Flaky Tests Integration Guide](/flaky-tests/get-started)
- [Merge Queue Setup Guide](/merge-queue/getting-started)

We set up a direct Slack Connect channel with our engineers for your team. Feature requests, debugging, planning. Not a vendor you file tickets with.

Expand All @@ -82,24 +90,17 @@ We set up a direct Slack Connect channel with our engineers for your team. Featu
SOC 2 Type II certified. TLS/HSTS in transit, AES-256 at rest. AWS-hosted in U.S. data centers with private VPCs. MFA, least privilege, access logging. Regular vulnerability scans, annual third-party pen tests. 45-day test result retention. We don't access your source code, secrets, environment variables, or customer data. [Request SOC 2 report](mailto:security@trunk.io).

<Info>
**Want to see how it works? Have questions?** [**Schedule time here**](https://calendly.com/trunk/demo) **or email** [**support@trunk.io**](mailto:support@trunk.io)
**Want to see how it works? Have questions?** [**Schedule time here**](https://calendly.com/trunk/demo) **or email** [**support@trunk.io**](mailto:support@trunk.io)
</Info>

## Learn More

<Columns cols={2}>
<Card
title="Merge Queue"
href="./merge-queue/merge-queue"
img="/assets/_shared/Merge.png"
>
<Card title="Merge Queue" href="./merge-queue/merge-queue" img="/assets/_shared/Merge.png">
A merge queue to make merging code in GitHub safer and easier
</Card>
<Card
title="Flaky Tests"
href="./flaky-tests/overview"
img="/assets/_shared/FlakyTests.png"
>

<Card title="Flaky Tests" href="./flaky-tests/overview" img="/assets/_shared/FlakyTests.png">
Detect, quarantine, and eliminate flaky tests from your codebase
</Card>
</Columns>
</Columns>
8 changes: 4 additions & 4 deletions merge-queue/using-the-queue/reference.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ og:title: "Submit and cancel PRs in Trunk Merge Queue"
Install the [Trunk for GitHub Chrome Extension](https://chromewebstore.google.com/detail/trunk-for-github/liggeliamkammmieidmmfmmdnjilabgn) to submit and cancel PRs directly from GitHub without leaving your pull request page.

<Frame>
![Image](/images/image.png)
![Image](/images/image.png "Image")
</Frame>

| State | Description |
Expand All @@ -36,14 +36,14 @@ You can configure a GitHub label that, when applied to a pull request, automatic

### Configure the enqueue label

1. Navigate to **Merge Queue** → **[your repository]** → **Settings**.
1. Navigate to **Merge Queue** → **\[your repository\]** → **Settings**.
2. Under **Enqueue by label**, enter the name of the GitHub label you want to use (for example, `merge-queue` or `ready-to-merge`).
3. Save the setting.

Once configured, applying that label to any open pull request in the repository will enqueue it automatically. Trunk removes the label from the PR once the queue picks it up.

<Info>
The enqueue label only triggers enqueueing when applied to an open PR that is eligible for the queue. PRs that are draft, failing required checks, or otherwise ineligible will not be enqueued.
The enqueue label only triggers enqueueing when applied to an open PR that is eligible for the queue. PRs that are draft, failing required checks, or otherwise ineligible will not be enqueued.
</Info>

### Removing from the queue
Expand All @@ -67,4 +67,4 @@ A PR's lifecycle in the Merge Queue goes through the following states:
| Pending Failure | The PR failed tests. The cause of failures is still indeterminate - it may be due to an upstream PR, or due to the current PR. It will wait until the root cause of tests has been determined, and restart testing on your PR if due to an upstream PR. If you want to manually restart a failed PR, see [manually restarting PRs](./handle-failed-pull-requests#manually-restarting-failed-pull-requests). |
| Merged | The PR successfully merged into the target branch. It will be removed from the queue. |
| Failed | The PR caused a testing failure. It will be removed from the queue. |
| Cancelled | The PR was cancelled, e.g. `/trunk cancel`. It will be removed from the queue. |
| Cancelled | The PR was cancelled, e.g. `/trunk cancel`. It will be removed from the queue. |
55 changes: 20 additions & 35 deletions merge-queue/using-the-queue/stacked-pull-requests.mdx
Original file line number Diff line number Diff line change
@@ -1,51 +1,36 @@
---
title: "Stacked pull requests"
sidebarTitle: "Stacked pull requests"
description: "Merge a chain of dependent pull requests through Trunk Merge Queue by enqueueing each PR with /trunk merge."
---
Trunk Merge Queue supports merging **stacked pull requests**: a chain of PRs where each one builds on the previous, with the bottom PR targeting your merge queue branch. Enqueue each PR with `/trunk merge` and Trunk processes them sequentially, testing and merging each one against the actual state of your merge queue branch.

## What is a stack
Trunk Merge Queue supports GitHub's native stacked pull requests. You can submit any part of a stack the same way you submit a regular PR (API, browser extension, PR comment, or checkbox), and Merge Queue handles moving each segment through the queue and merging it.

A stack is a chain of pull requests connected through their base branches. Each PR targets the branch of the PR below it, and the bottom PR targets your merge queue branch:
<Frame>
![Image](/images/image-1.png "Image")
</Frame>

```
merge queue branch <-- PR #1 (base: merge queue branch)
<-- PR #2 (base: PR #1's branch)
<-- PR #3 (base: PR #2's branch)
```
## How it works

Trunk discovers the stack automatically by walking base branches. No separate configuration is required to mark PRs as stacked.
Given a stack like:

## Step 1: Enqueue every PR in the stack
<Frame>
![Image](/images/image-3.png "Image")
</Frame>

Each PR in the stack must be enqueued separately. Use any of the standard submission methods on every PR:
You can submit from any point in the stack. So it is acceptable to enqueue from mid-stack - for example PR2 or from the top of the stack PR4. You don't have to wait for one part of a stack to merge before enqueuing another part. It is perfectly ok to enqueue from PR2 and from PR4 at the same time. We will sort it out and make sure all the code is tested correctly.

* Comment `/trunk merge` on each PR.
* Check the box in the Trunk comment on each PR.
* Use the CLI: `trunk merge <pr-number>` for each PR.
## Tracking a Stack in the Queue

Enqueuing each PR separately gives you control over which PRs in your stack should be merged versus which might need more work.
When you submit a stack the entry in the Merge Queue UI will reflect all the pull requests that are being tested collectively as seen below

## Step 2: Automatic sequential processing
<Frame>
![Image](/images/image-2.png "Image")
</Frame>

Once enqueued, Trunk handles the rest:
## Performance

1. The **bottom PR** in the stack (base branch = your merge queue branch) enters the queue, runs tests, and merges.
2. When it merges, **GitHub automatically updates** the next PR's base branch from the previous feature branch to your merge queue branch.
3. The **next PR** now targets the merge queue branch, so it proceeds through the queue.
4. This continues until every PR in the stack is merged.
Because the Trunk Merge Queue is stack aware you will achieve CI performance savings and throughput wins when submitting stacks as we will test the stack of PRs as a single block instead of testing each PR in the stack individually. <br /><br />**Things to know**

For example, a stack of 5 PRs with merge queue branch `main`:

* PR #1 (base: `main`) → tests → merges
* PR #2's base automatically changes to `main` → tests → merges
* PR #3's base automatically changes to `main` → tests → merges
* …and so on.

## Considerations

**Sequential testing.** PRs in the stack are tested and merged one at a time in order. The second PR won't begin testing until the first PR has fully merged. This ensures each PR is tested against the actual state of your merge queue branch and results are deterministic, at the cost of speed. A stack of 5 PRs takes substantially longer than 5 independent PRs, since they can't be tested in parallel.

**Enqueued PRs with non-merge-branch bases.** If you enqueue a PR whose base branch is not your merge queue branch and that base never updates, the PR stays in the queue without processing. This typically means the parent PR in the stack was never enqueued or merged. The PR will begin processing as soon as its base branch updates to the merge queue branch.

**No special configuration.** Individual enqueuing requires no additional setup beyond a functioning merge queue. Trunk detects the stack relationship automatically from each PR's base branch.
- **GitHub may not always rebase after a mid-stack merge.** There are some existing issues from GitHub surrounding stacks when performing a mid-stack merge. While GitHub is intending to always rebase stacks correctly - you may still need to manually rebase the existing pieces of your remaining stack after Merge Queue merges the pieces underneath it. GitHub is working on improving this behavior.
- **GitHub's stack merge API can take 90\+ seconds to complete.** Stacks may stay in the "merging" state longer than a regular PR while GitHub finishes the merge.
Loading