CodeHerderSearch⌘KRequest access →

Waiting for a person to merge

Add a stage where a task waits for a person to merge its pull request. See how it starts and ends, what its states mean, and how to find it.

By default, CodeHerder’s merge stage lands the pull request itself. Some teams want a person to press the merge button instead. A merge-hold stage supports that. A task that reaches it stops and waits. When every pull request the task waits on is merged, CodeHerder moves the task on.

This page covers setting up the stage, how a task enters and leaves it, what the task page shows while it waits, and how to find waiting tasks. For the built-in merge path, see The merge stage.

Before you start

  • You must be an admin or owner of the workspace.
  • Your plan must include Custom workflows, because you create a stage in your stage library. See What your plan unlocks.
  • CodeHerder must be able to read your pull requests. Install the GitHub App on the repository, or connect GitHub or GitLab under Integrations. A task cannot enter the stage without one of these.

No built-in workflow has a merge-hold stage. You add one to a workflow of your own. You set it up from the CLI today. The web app has no control for it. Settings → Stages keeps the setting on a stage that already has it, but it shows no toggle to turn it on.

Set up a merge-hold stage

Create a stage in your library and mark it as a merge-hold stage:

ch stage create await_merge --stage '{"label":"Waiting for merge","spec":{"awaits_external_merge":true}}'

A merge-hold stage does no work itself. It has no prompt, and no agent runs there. Check it with ch stage show await_merge. The output has a row awaits external merge with the value yes.

Then add the stage to a workflow. This example puts it between code and done:

{
  "key": "hand_merge",
  "label": "Hand merge",
  "instances": [
    { "name": "todo", "stage": "todo", "class": "todo" },
    { "name": "code", "stage": "code", "class": "doing", "to": ["await_merge"] },
    { "name": "await_merge", "stage": "await_merge", "class": "doing", "to": ["done", "code"] },
    { "name": "done", "stage": "done", "class": "done", "terminal": "success" }
  ]
}
ch workspace workflow edit hand_merge --from-file composition.json

The stage must have class doing. CodeHerder rejects a merge-hold stage that has a prompt, that can write code, or that has class done. It reports that when you save a workflow that uses the stage. See Composing a workflow from the library for the rest of the file format.

How a task enters and leaves the stage

Entering. Nothing moves a task into the stage by itself. The agent in the stage before it, or a person, moves the task there. For the workflow above, that is ch task status <taskId> await_merge. CodeHerder refuses the move in two cases:

  • The task has no pull request recorded. The error says to run ch task set-merge-ref <taskId> <pr-or-mr-url> first. When an agent writes a pull request link into the task’s artifact field, CodeHerder records it for you. You can also record one yourself with ch task merge-requests create <taskId> <pr-or-mr-url>.
  • No GitHub App installation or enabled integration covers the pull request’s repository.

Leaving. The task leaves when every pull request it waits on is merged. CodeHerder learns about a merge from a webhook from your git host. It also checks again about every two minutes. If only some pull requests are merged, the task keeps waiting. The task then moves to the next stage in the workflow. If that move needs approval, the task waits there for it.

Moving it by hand. A person cannot move a waiting task forward. CodeHerder answers that the task advances on its own once the merge is confirmed. You can still send it back, block it, or cancel it, as far as the workflow allows each move.

Reading the wait

The task page shows a banner only when the pull request needs your attention: a draft, a conflict, or a closed pull request. It lists each pull request the task waits on, with a link and how long it has waited.

The state of the pull request has one of these labels. With several pull requests, the task shows the most urgent one, in this order: closed, conflicted, draft, open and mergeable, open and still checking.

Label Meaning
Open and mergeable The pull request is ready for someone to merge.
Open, checking mergeability Your git host has not finished checking it.
Draft The pull request is a draft. Mark it ready for review.
Conflicted, needs a decision The pull request has a merge conflict.
PR closed, needs a decision Someone closed the pull request without merging it.

When a decision is needed, the banner offers buttons. Each button appears only if the workflow allows that move:

  • Send back to <stage> moves the task to the nearest earlier stage where an agent can write code, usually code.
  • Cancel task cancels the task.

CLI output shows the same facts:

ch task show <taskId>

While a task waits, the output has a row like awaited PR: conflicted, needs a decision (move it to code or cancelled), since 13:04. The state is one of mergeable, checking, draft, conflicted or closed. The time reads just now or N min ago within the last hour. Later the same day it shows a clock time. Within the past week it adds the weekday, for example Mon 13:04. Older times show the date, for example Jan 2, 13:04. The PR column of ch task list shows the link, then (merged) for a merged pull request. While the task waits, it shows (draft), (conflicted), (closed), (mergeable) or (checking) instead.

The host state of a waiting task’s pull request refreshes on a webhook or on the two-minute check. A change on your git host can take that long to show.

On the Tasks page, a row with a recorded pull request shows a pull request icon beside its title. Hover the icon to see which pull request it is and its state. A task with several shows how many there are and how many have merged.

When something goes wrong

The pull request closes without a merge. The task stays in the stage. CodeHerder files a blocker that starts with “PR/MR closed without merging”. Reopen the pull request, or use the banner buttons to send the task back or cancel it. If you reopen it, CodeHerder clears the note on a later check. See Blockers and blocked tasks.

CodeHerder cannot read the pull request. After three failed reads in a row, it files a blocker that starts with “Can’t verify merge status” and gives the reason. The reason says what failed. Fix the connection to your git host. The next successful check clears the blocker.

The task is stuck although the pull request merged. An admin or owner can confirm the merge by hand and give a reason:

ch task status <taskId> done --force-merge-confirm --reason "Merged on the host; webhook missed"

Use the stage the workflow moves to next in place of done. CodeHerder posts a task comment that records the override and your reason. There is no web control for this.

Finding tasks that wait

In the web app, open Tasks and use the PR state filter:

  • Awaiting merge shows tasks whose pull request is open and ready for a merge.
  • Draft shows tasks whose pull request is a draft.
  • Needs a decision shows tasks whose pull request is conflicted or closed.

From the CLI:

ch task list --merge-state awaiting --status await_merge
ch task list --merge-state needs_decision --status await_merge

The filter matches any task that has a recorded pull request that is not merged, at any stage, not only tasks in a merge-hold stage. A task in review with an open pull request also matches Awaiting merge. Combine the filter with the Stage filter, or with --status, to list only the tasks that wait in your merge-hold stage. See Tracking work.

Tasks that run locally

A task you run on your own machine has no account, so CodeHerder cannot detect a merge for it. A local task in a merge-hold stage can only go back, be blocked, or be cancelled.

Last updated

CodeHerder

Round up your herd.

Bring every human and every agent onto one table. Watch the work move. Costs update as it happens.

Try "pricing", "connect a device", or "who reviews the code"

↑↓ move · ↵ open · esc close