Early access. Zudo links pull requests to requests, shows what is happening to them, and closes a request when the
work it is waiting on is finished — on merge, or once it has actually deployed. This page says exactly what works now.
You can connect it yourself from Settings → Connections.
Connect
1
Start from Zudo
Go to Settings → Connections, click Add Connection, and choose GitHub. Only owners and admins can add a
connection.
2
Pick the account
Zudo sends you to GitHub to install the app. Choose the personal account or organization whose repositories you want
to connect. If you are not an owner of that organization, GitHub asks an owner to approve the install instead, and
nothing is connected until they do.
3
Choose the repositories
Grant access to All repositories or Only select repositories. This is the access boundary, and it stays
under your control on GitHub — Zudo cannot widen it.
4
Come back to Zudo
GitHub returns you to Settings → Connections. The connection appears with the repositories it can see.
If an owner had to approve it
Installing on a GitHub organization is an owner’s decision. If you are not one, GitHub takes your request to an owner instead of installing, and Zudo tells you it has asked them. When they approve, the app is installed — but GitHub does not send you back to Zudo, and going to the install page again shows you a screen only an owner can submit. So the installation exists and nothing is connected. Use Connect an existing installation, on the GitHub step of Add Connection. It asks GitHub who you are, lists the installations your account can see, and connects the one you pick. No owner needed: installing takes owner rights, connecting an installation that already exists only takes being able to see it. The same path works whenever an owner installed Zudo without you, and whenever an install was interrupted on the way back. You can connect more than one GitHub account to the same Zudo organization. A GitHub App is installed per account, so a company with repositories under two GitHub organizations needs one installation for each, and both appear as separate connections.What Zudo reads
The app requests read-only access to five things, and nothing else:
Zudo never writes to GitHub. It posts no comments, sets no labels, and creates no status checks. It has no permission to do any of those.
Watching repositories
Two different things decide whether Zudo looks at a repository. Access is set on GitHub, under the installation. It is what the app can see at all. Change it with Manage access on GitHub on the connection card. Watch is set in Zudo, per repository. Every repository you grant is watched by default, because you already chose them on the install screen. Turning Watch off stops Zudo looking at that repository without changing anything on GitHub — useful for a repository that is noisy or irrelevant to customer work. If the list in Zudo disagrees with what you granted on GitHub, press Refresh on the connection card to rebuild it.Connecting work to a request
Open any request and you will find a Development card. It shows the branches being followed for that request, the pull requests that satisfy it, and a branch name you can copy.Follow a branch
Follow a branch is the most direct option, and the earliest: pick a watched repository, find the branch, and select it. You do not need the developer to have named anything. The filter searches your repository’s branches rather than only the first screenful, so it finds a branch whatever its name sorts next to. A repository with a great many branches is searched as far as it takes to fill the list — if the one you want is not there, type more of its name. From then on Zudo follows that branch. A pull request opened from it is linked automatically, and its merge — and later its deploy — follow from there. If a pull request is already open from that branch when you start following it, that one is picked up too. This works regardless of your linking settings. Choosing a branch is a decision you already made, so Zudo does not second-guess it.Copy the branch name
Press Copy branch name on the request. You get something likezudo-441-export-times-out: the request’s key, then its title. Start a branch with that name and everything links itself — nothing to remember and nothing to type.
Let Zudo work it out
If automatic linking is on, Zudo works down a ladder and uses the first thing that matches. It records which one it used and shows it on the card, so you can always see why a link exists.
A link, once made, stays until you remove it. Editing a description to fix a typo will not silently unlink anything.
Choosing how linking works
Settings → Connections → GitHub → Linking controls what Zudo will infer. Owners and admins can change it.- Link pull requests automatically — the master switch. Off means Zudo links only what a person links by hand, and the rules below stop applying. Following a branch still works.
-
A request key in the branch, title or description — the
ZUDO-441convention. - A link to the request in the description — a pasted Zudo URL.
-
An account’s External ID in the description — the
!acme-42!convention. - Let an account reference open a new request — separate from the rule above, and worth thinking about on its own. On, a pull request naming accounts with no matching request creates one, with those accounts attached, exactly as a Linear issue does. Off, engineering can link to requests that already exist but cannot raise customer-facing ones unattended. This only ever applies to pull requests as they happen. Neither the import Zudo runs when you first connect, nor the hourly re-check, will open a request — they link to requests that already exist and nothing more. A pull request that merged months ago naming an account is history, not a new thing somebody is waiting for.
ZUDO by default, belongs to your organization rather than to a GitHub connection, because every request has a key whether or not GitHub is connected. Change it in Settings → Organization → Requests; see Changing the prefix. Keys written with an earlier prefix keep linking.
What Zudo will not do
Zudo only links requests in your organization. A key is a request’s number among your own requests, soZUDO-441 in your repository names your request 441 and never another Zudo customer’s. A pasted link to another organization’s request matches nothing at all.
What appears on a request
The Development card shows each linked pull request with its state — open, draft, merged, or closed — the repository and number, and who opened it. The request timeline gains an entry when a branch carrying a request key is pushed, and when a pull request is opened, marked ready for review, merged, closed without merging, or reopened. Individual commits are not shown. Pushing more to an open branch adds nothing to the timeline: it fires constantly, and “someone pushed again” is harder to read than silence.Pull request descriptions
Zudo always reads a pull request’s description, because that is where request keys and account references live. It does not store it unless your organization asks it to. Reading and keeping are separate decisions. Linking works either way; storing the text puts a copy of your repository’s prose in Zudo, which some teams want for context and others would rather avoid. Ask your Zudo contact to turn it on. Titles, branch names and authors are always stored — they are what the Development card shows.When a request closes
A request closes when the work it is waiting on is finished. What counts as “the work” is up to you, because teams genuinely disagree — and the case that forces the question is a request whose Linear issue is marked Done while its pull request is still open. Settings → Organization → Requests controls it, under When a request is finished. Owners and admins can change it. What can hold a request open — Linear issues, GitHub pull requests, or both. A source switched off still appears on the request; it just stops being able to keep it open. When a request has both — wait for both, or let either one settle it.
Two things are always true, whatever you choose:
- A source only counts on requests that actually have work in it. A request with two issues and no pull requests behaves identically under every setting.
- A request with no work at all never closes on its own. Changing this setting cannot empty your request list.
What counts as a pull request being finished
By default, merging it. A pull request closed without merging is never finished — that is work abandoned, not work delivered, so a request whose only pull request was thrown away stays open and waits for a person. An abandoned pull request doesn’t hold anything up once there is other work, though. If a request has any other pull request linked, the closed one drops out: a branch that was thrown away and redone in a second pull request is judged by the second. If merging is too early for you, add a deploy gate under What finishes a pull request. Then a merged pull request is not finished until it has actually gone out:
Name the environments. An empty list matches nothing rather than everything — otherwise turning the gate on before configuring it would mark work as shipped the next time anything deployed to staging.
What a deploy carries
A deploy names one commit, which is the head of what went out rather than all of it. If your team merges several pull requests and deploys once, only one of them has that commit. So Zudo asks GitHub what sits between your previous deploy to the same place and this one, and marks every merged pull request in that range. That’s why the first deploy after connecting only marks what it can see directly — there is no previous deploy to compare against yet. When a range is too long for GitHub to answer, Zudo marks only the deployed commit and leaves the rest at merged. That under-reports on purpose: a request left open is a question someone answers, while a request closed by mistake is an answer nobody questions. If you gate on releases, note that a release records whatever it was created from, which is often a branch rather than a commit. Zudo resolves that to the commit the branch pointed at when the release was published. If it cannot — a deleted branch, say — it records nothing for that release rather than a marker that would move, and the pull requests stay at merged until the next release covers them.Progress on a request
Alongside its status, a request now carries how far the code has got: in progress, in review, merged, or shipped. The least-advanced pull request sets it — a request is only as far along as the piece of it furthest behind. A pull request closed without merging is left out whenever another one is linked; if every one was abandoned, the request reads as in progress. It shows as a Progress column on the Requests list too, and you can filter by it — including No linked work, for the requests nobody has started on. This comes from GitHub alone. A request with no pull requests and no followed branches has no progress shown at all, because a Linear issue marked Done is not a claim that anything was deployed.What works today
- Installing the app and connecting one or more GitHub accounts
- Choosing which repositories Zudo watches
- Following a branch from a request, and picking up the pull requests opened from it
- Linking pull requests by branch name, key, URL, account reference, or by hand
- Choosing which of those rules apply, per connection
- Creating a request from a pull request that names accounts, if you allow it
- Closing a request when the work it is waiting on is finished, under rules you choose
- Waiting for a deploy before counting work as finished, if you want that
- Showing how far the code has got, from the pull requests linked to a request
- Showing pull request state and history on the request
Using GitHub and Linear together
If a request is linked to a Linear issue and to the pull request written for that issue, those are not two pieces of work. Zudo folds the pull request under its issue, so the request waits for it once rather than twice. The pull request still appears on the request with its state and its timeline entries, and it still counts — not as a second thing to wait for, but as part of whether the issue is finished. An issue whose pull request has not shipped is not finished, whatever Linear says about the issue. So if you wait for a deploy, marking the issue Done does not close the request until the code is actually out. Zudo works out that they belong together two ways:- Linear tells it. Linear records a pull request as an attachment on the issue. If your workspace sends attachment events to Zudo, that is the authoritative answer — and it is used even when automatic linking is switched off, because it is a fact Linear reported rather than something Zudo inferred. See the Linear integration for how to turn that on.
- The pull request names the issue.
ENG-812in the branch, title or description, the same thing Linear’s own GitHub integration matches on. This is an inference, so it follows your automatic linking setting.
ZUDO-441 and ENG-812 are the same shape.
Without this, a team using Linear’s GitHub integration would find every request waiting twice for the same work.
Progress is also a segment condition. Requests In Progress, Requests In Review, Requests Merged and Requests Shipped each count an account’s open requests at that stage, so you can build a segment of accounts waiting on a deploy. A flag rule points at a segment, so the same condition can raise a flag as well. See Segments.
What does not work yet
- Individual commits are not tracked. This is deliberate rather than pending: Zudo records the milestones — branch, pull request opened, merged, shipped — because a commit-by-commit feed tells a CSM nothing they would act on.
Disconnecting
Deleting the connection in Zudo removes the repository list and stops Zudo reading anything. It does not uninstall the app from GitHub. That is deliberate — Zudo should not be able to change your GitHub account’s settings. To revoke access fully, remove the Zudo app from your GitHub account or organization under Settings → Applications → Installed GitHub Apps. If you uninstall the app on GitHub without deleting the connection in Zudo, the connection is disabled automatically and its history is kept.If something looks out of date
GitHub webhooks are how Zudo hears about a branch, a pull request or a deploy, and they are almost always immediate. When one goes missing — GitHub retries a failed delivery and eventually gives up — Zudo re-checks every hour: open pull requests in watched repositories, plus anything still linked to a request that is open. If you wait for a deploy, that hourly check also asks GitHub what it has deployed lately, whenever something is still waiting on one. A merged pull request is the case that needs it most: nothing else has any reason to look at it again, so a deploy whose webhook never arrived would otherwise leave its request open indefinitely. It reads back as far as the oldest merge still waiting, rather than a fixed number of recent deploys, so a long gap is caught up rather than only its most recent part. One check reads up to a hundred deploys; if you have more than that outstanding, successive hourly runs work through them. So a merge — or a deploy — whose webhook never arrived is picked up within the hour rather than sitting there. You do not have to do anything, and there is nothing to press. Two things that reconcile does not look at, on purpose: closed pull requests nobody linked to a request, and repositories you are not watching. Neither can change a request, and reading them would turn an hourly check into a crawl of your whole history.Troubleshooting
- “That installation does not belong to your GitHub account” — you were signed in to a different GitHub account than the one that owns the installation. Sign in as the right account and try again.
- “That installation link has expired” — the install link is valid for ten minutes. Start again from Add Connection.
- The repository list looks wrong — press Refresh on the connection card. If a repository is still missing, check it is granted under Manage access on GitHub.
- Nothing happened after approving — if you are not an owner of the GitHub organization, your request goes to an owner for approval. The connection appears once they approve it, and you will need to complete the install again.
