Skip to content
Draft
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
14 changes: 14 additions & 0 deletions merge-queue/optimizations/parallel-queues/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,20 @@ Switching modes can be done from the `Merge Queue Mode` section of your queue's
<img className="hidden dark:block" src="/assets/merge-queue/optimizations/parallel-queues/enable-parallel-mode-dark.png" alt="Enabling parallel mode in the Merge Queue Mode settings" />
</Frame>

## Cutting over from single to parallel mode

In single mode, a pull request only needs to pass branch protection to be tested. In parallel mode it needs one more thing: impacted targets uploaded for the head SHA. A PR stays in the `Queued` state until **both** conditions are met, so the cutover is mostly about making sure every PR that could enter the queue has targets posted for it.

**Land the impacted-targets job before you switch.** You don't have to flip to parallel mode and add the CI job at the same time. While the queue is still in single mode, uploads to [`/setImpactedTargets`](./api#uploading-impacted-targets) are stored but not used for scheduling, so shipping the job early is safe and won't change queue behavior. When you switch to parallel mode, every PR the job has already run for will have its targets ready.

**Backfill open PRs so they don't hang.** A PR that was opened before the job existed — or one that passed CI long ago and never re-ran it — has no impacted targets. After cutover it will sit in `Queued` indefinitely, because there is no timeout that applies a fallback (and applying `ALL` automatically would collapse every lane onto that PR, defeating parallelization). Post targets for these PRs before or right after the switch. Sending `ALL` for each open PR targeting the merge branch is a reasonable one-time backfill; the next time the job runs on a new commit, it overrides the `ALL` with the real list ([last upload wins](./api#last-upload-wins-per-head-sha)).

**Require a recent merge base for new PRs.** Backfilling handles today's open PRs, but a stale branch that passed CI before the job existed can still be enqueued later as long as its status checks stay green. Raising your minimum merge-base / staleness requirement forces those branches to rebase, which re-runs the impacted-targets job and guarantees every newly enqueued PR has targets.

<Warning>
A PR with no uploaded impacted targets stays in `Queued` forever in parallel mode — there is no timeout that falls back to `ALL`. If engineers report PRs that never start testing after the cutover, missing impacted targets is the most likely cause. See [the troubleshooting guide](/merge-queue/reference/troubleshooting).
</Warning>

## Monitoring Parallel Queue Performance

Once you've enabled parallel mode and configured impacted targets, you can analyze how well the parallel workflow performs for different parts of your codebase.
Expand Down
14 changes: 11 additions & 3 deletions merge-queue/reference/troubleshooting.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Visit [Trunk Support](../../setup-and-administration/support) for additional ass
Start here if a PR you submitted isn't merging:

* **Check the status comments for the PR in** the [Trunk Dashboard](https://app.trunk.io/) to see what it's waiting for
* **Stuck in "Queued"**: Usually means branch protection rules haven't passed (missing required status checks or code review) or there are merge conflicts. If the status looks correct but the PR still won't enter the queue, try [removing](/merge-queue/using-the-queue/handle-failed-pull-requests#manually-restarting-failed-pull-requests) and re-adding by commenting `/trunk merge` again on the PR.
* **Stuck in "Queued"**: Usually means branch protection rules haven't passed (missing required status checks or code review) or there are merge conflicts. In [parallel mode](/merge-queue/optimizations/parallel-queues), it can also mean no [impacted targets](/merge-queue/optimizations/parallel-queues#what-are-impacted-targets) were uploaded for the PR's head SHA — the PR waits in `Queued` until they arrive. If the status looks correct but the PR still won't enter the queue, try [removing](/merge-queue/using-the-queue/handle-failed-pull-requests#manually-restarting-failed-pull-requests) and re-adding by commenting `/trunk merge` again on the PR.
* **Fails when attempting to merge**: Check that squash merges are enabled for your repository in GitHub settings (`Settings > General > Allow squash merging`). Trunk Merge Queue requires squash merges to be enabled.
* **"Permission denied" errors**: Review the [Branch Protection](/merge-queue/getting-started/configure-branch-protection#configure-branch-protection-rules) guide to make sure `trunk-temp/*` and `trunk-merge/*` branches aren't protected by wildcard rules like `*/*`.
* **Status checks not running**: Verify your CI is configured to run on draft PRs (or `trunk-merge/**` branches if using push-triggered mode). See the [Branch Protection](/merge-queue/getting-started/configure-branch-protection#configure-branch-protection-rules) guide for details.
Expand All @@ -28,13 +28,21 @@ Start here if a PR you submitted isn't merging:
</Accordion>

<Accordion title='Pull request stuck as "Queued" in the queue'>
**Cause:** Required status checks are not completing or not configured correctly.
A PR stays in `Queued` until it's eligible to be tested. In parallel mode that means two conditions, either of which can block it.

**Solution:**
**Cause 1: Required status checks are not completing or not configured correctly.**

* Click on the pull request in the Trunk Dashboard to see which checks it's waiting for
* Verify those checks are running in your CI provider
* If using Push-triggered mode, make sure the check names in `trunk.yaml` exactly match your CI job names

**Cause 2 (parallel mode): No impacted targets were uploaded for the PR's head SHA.**

In [parallel mode](/merge-queue/optimizations/parallel-queues), a PR isn't scheduled until [impacted targets](/merge-queue/optimizations/parallel-queues#what-are-impacted-targets) have been posted for its current head SHA. There is no timeout — a PR whose impacted-targets job never ran (for example, a stale branch opened before you added the job) waits in `Queued` indefinitely. The PR detail page in the Trunk Dashboard shows whether targets are the blocker.

* Re-run the CI job that posts impacted targets, or push a commit so it runs against the new head SHA
* As a one-off, post targets directly with [`/setImpactedTargets`](/merge-queue/optimizations/parallel-queues/api#uploading-impacted-targets) — sending `ALL` unblocks the PR immediately, though it serializes that PR against the rest of the queue
* If this happens to many PRs right after switching to parallel mode, see [Cutting over from single to parallel mode](/merge-queue/optimizations/parallel-queues#cutting-over-from-single-to-parallel-mode)
</Accordion>

<Accordion title="Required status checks not running">
Expand Down
4 changes: 2 additions & 2 deletions merge-queue/using-the-queue/reference.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,15 @@ Removing the configured label from a PR dequeues it from the merge queue. You ca

## Pull request processing

Once a PR is submitted to the merge queue it goes through several states. First, it starts as _Queued_ until all of the required conditions to submit it are met. Once ready, the PR moves to the _Pending_ state, waiting for a Merge Queue to pick it up, and then enters the _Testing_ state. Once the tests pass the PR may still need to wait for upstream PRs. Once any upstream PRs are complete the PR will be merged and then removed from the Merge Queue. If a PR fails or is canceled then it will go to the failed or canceled state.
Once a PR is submitted to the merge queue it goes through several states. First, it starts as _Queued_ until all of the required conditions to submit it are met. In single mode that means passing branch protection (required status checks and reviews); in [parallel mode](/merge-queue/optimizations/parallel-queues) it also means [impacted targets](/merge-queue/optimizations/parallel-queues#what-are-impacted-targets) have been uploaded for the PR's head SHA. A PR stays in _Queued_ until both are satisfied, and the PR detail page shows which one it's waiting on. Once ready, the PR moves to the _Pending_ state, waiting for a Merge Queue to pick it up, and then enters the _Testing_ state. Once the tests pass the PR may still need to wait for upstream PRs. Once any upstream PRs are complete the PR will be merged and then removed from the Merge Queue. If a PR fails or is canceled then it will go to the failed or canceled state.

## Pull request states

A PR's lifecycle in the Merge Queue goes through the following states:

| State | Description |
| --- | --- |
| Queued | The PR was submitted to Trunk Merge Queue, but the PR isn't eligible for merging yet. Impacted targets may not be uploaded, or readiness checks may not have passed. |
| Queued | The PR was submitted to Trunk Merge Queue, but the PR isn't eligible for merging yet — readiness checks may not have passed, or, in [parallel mode](/merge-queue/optimizations/parallel-queues), impacted targets may not be uploaded for the head SHA. A PR with no impacted targets stays here indefinitely in parallel mode. |
| Pending | The MergeGraph created a node for the PR. Testing will begin if the graph has capacity. |
| Testing | The PR is testing. Required status checks that Trunk Merge Queue must gate on before merging PRs can be specified with in `.trunk/trunk.yaml` or through GitHub branch protection rules as the "Status checks that are required" before merging on your merge branch |
| Tests Passed | The PR successfully passed tests. It may have to wait for upstream PRs to complete tests before merging. |
Expand Down