# GitHub pull requests

Connect repositories so pull requests show up on the issues they mention, and optionally move issue status or environment. Hydrant never writes to GitHub.

Connect a repository and every pull request that mentions an issue shows up on that issue: draft, open, merged or closed, plus where its review stands. Nobody has to paste links around anymore. Hydrant only reads. It never comments, labels, merges or changes anything on GitHub. A pull request never changes an issue unless an Owner or Admin turns on [status automation](#let-pull-requests-move-issues), which only moves status, or [environment detection](#move-done-issues-through-environments), which only moves a Done issue's environment.

## Before you start

- You're an Owner or Admin of the workspace. Members see linked pull requests but can't connect repositories.
- You authorize with the same GitHub account you sign in to Hydrant with. Hydrant only offers repositories that account can read, even when the app is installed on more of the organization.
- Installing the app on an organization usually takes an organization owner. If you're not one, GitHub sends them a request instead.
- Know who will see what. Everyone in the workspace sees the title, number, author, branches and state of linked pull requests from connected repositories, even people who can't open the repository on GitHub.

## Steps

### Connect repositories

1. Open **Settings › GitHub** and press **Connect repositories**.
2. GitHub asks you to install **Hydrant Connect** and pick repositories. Choose the ones this workspace needs, or all of them. You can change that on GitHub later.
3. GitHub asks you to authorize the app. That's how Hydrant checks it's really you and which repositories you can read. It keeps your GitHub user number and that list of repositories, and throws the authorization itself away.
4. Back in Hydrant, open **Add repositories** under the account and press **Connect** on each repository this workspace should see. A repository belongs to one workspace at a time.

Connecting a repository links its open pull requests straight away. Older ones wait for an import.

### Make pull requests link themselves

A pull request links to an issue when its branch name, title or description mentions the issue in one of these forms:

| Write | Example |
| --- | --- |
| `hyd-` and the issue number | branch `henry/hyd-46-github-links`, or "Fixes hyd-46" |
| `hyd #` and the issue number | "HYD #46" in a title |
| The issue's link | `https://hydrant.dev/your-workspace-abc234defg/issues/46` |

A bare `#46` never counts, because on GitHub that's the pull request's own number. Text inside code blocks doesn't count either. To stop a mention from linking, write `skip hyd-46` or `ignore hyd-46` in the description.

The quickest route is **Copy branch name** in an issue's menu (or the command palette), which gives you `hyd-46-short-title`. The default [agent prompts](/help/agents/copy-prompt) ask agents to name branches that way and to start the pull request description with the issue link, so work done by agents links without anyone thinking about it.

### Link, unlink and refresh by hand

- **Link:** on the issue, press **+** next to **Pull requests** and paste the pull request's address. It has to come from a connected repository.
- **Unlink:** press **×** on the card. An unlinked pull request stays unlinked, even when its branch or description still mentions the issue. **Relink** in the note that appears undoes it.
- **Refresh:** press the refresh button on a card to read GitHub's current state now.

Agents can do the same over MCP. `get_issue` lists linked pull requests, and `update_pull_request_link` links or unlinks.

### Let pull requests move issues

Off until an Owner or Admin turns it on. It only ever changes status.

1. In **Settings › GitHub**, find **Status automation**. It appears once a repository is connected.
2. For each pull request event (opened as a draft, opened, ready for review, review requested, approved, changes requested, merged, closed without merging, reopened), pick where the issue moves, or **No action**. **Use suggested rules** fills in a sensible start: opening moves to In Progress, a change request moves review back to In Progress, and merged stays No action.
3. Set **Only from** to the stages a rule may move issues out of. An issue somewhere else stays put.
4. Need a different rule for a base branch, like `release`? Press **+** on the event's row and name the branch. That rule beats the general one for pull requests into it.
5. Switch off any repository that shouldn't move issues, then press **Save**.

Before saving, **Try it on a pull request** shows what your rules would do to each issue a pull request links to, and why nothing happens when it doesn't. Repository switches count once you save them. It moves nothing.

How it decides:

- **Every linked pull request counts.** An issue with two closing pull requests moves on merge only when both have merged. A pull request that only relates to the issue ("Related to hyd-46") never moves it, and one that doesn't close it ("Part of hyd-46") moves it along but not on merge.
- **Forks and outsiders never move issues.** Pull requests from forks still link and show up, and only reviews from the repository's owners, members and collaborators count. On a public repository anyone can leave a review.
- **People win.** Each event on each pull request decides once. Move an issue by hand and GitHub won't drag it back. Trashed, Done, Canceled and Iced issues never move, and an issue that isn't refined never moves into Ready.
- **Merged isn't Done unless you say so.** Picking a Done stage warns you first, because Done clears snooze and unblocks whatever was waiting.
- **Pause per issue.** **Pause automation** on an issue's **Pull requests** section stops GitHub moving it. **Resume automation** starts it again without replaying anything it skipped. A pause stays while automation is off, and the section still shows it. Agents use `update_pull_request_link` with `pause` or `resume`.
- **Only what happens next.** Turning automation on or changing rules never moves existing issues. Linking or importing a pull request never moves anything either.

### Move Done issues through environments

For teams that promote work through branches, like `testing` → `staging` → `main`. Off until an Owner or Admin turns it on, and it needs [environments](/help/using/status-refined-blocked#where-done-work-has-got-to) switched on first. It only ever moves a Done issue's environment.

1. In **Settings › GitHub**, find **Environment detection**. It appears once a repository is connected and environments are on (Solo Pro).
2. For each repository, type the exact branch each environment lives on. Leave an environment blank if that repository doesn't use it.
3. Switch on **Follow branches** and press **Save**.

GitHub asks each connected account to accept read access to repository contents the first time. Until it does, Settings says so and nothing moves. Hydrant uses that access only to ask GitHub whether a commit is on a branch. It never stores code.

How it decides:

- **Every merged closing pull request counts.** When the merge commits of all of an issue's closing pull requests are on an environment's branch, the issue moves to that environment. Pull requests from forks don't count, and a repository that doesn't map an environment doesn't hold it back.
- **Forward only, once.** It moves an issue to the furthest environment it has reached, even past one in between, like a hotfix that lands on `main` first. It never moves an issue back, and never twice into the same environment, so moving an issue back by hand sticks. When a new closing pull request merges, such as a fix for a reopened issue, or a merged one is newly linked to close it, the environments its repository uses are decided again from all the issue's commits.
- **Finishing counts too.** An issue marked Done starts in the environment its commits have already reached, instead of the first one. Pushes are watched before an issue is Done, so work promoted while still in review starts in the right place.
- **Same pause.** **Pause automation** on an issue stops environment detection too.
- **Promotions that rewrite commits aren't seen.** A cherry-pick or rebase onto the next branch makes new commits, so move those issues by hand. Reverts leave the original commit on the branch, so an issue stays where it is.

### Import older pull requests

1. In **Settings › GitHub**, press **Import past pull requests** next to a repository.
2. Press **Preview**. Hydrant reads the merged and closed pull requests and counts how many would link, how many mention nothing, and how many mention an issue that isn't here. Nothing is saved yet.
3. Press **Import**. It works through the pull requests page by page. If it stops, **Resume import** carries on where it left off, and running it again adds nothing twice.

## What you should see

- A **Pull requests** section on each issue that has links. It lists the repository and number, title, state, review status, author, target branch, where the link came from and when Hydrant last heard from GitHub.
- Issue history entries such as "Linked pull request acme/app#12 (from its branch)", by **GitHub** for automatic links and by the person or agent for manual ones. An import leaves one entry per issue.
- The issue itself unchanged: no new status, assignee or priority because of a pull request, unless status automation is on. Then a move shows in history as a status change by **GitHub** with a line like "Status automation: acme/app#12 merged", and the card says what GitHub last did for that pull request and why.
- **Recent decisions** under Status automation, listing the latest moves and the ones GitHub skipped.
- With environment detection on, a move shows in history as an environment change (by **GitHub**, or in your own save when you mark the issue Done) with a line like "Environment detection: Staging (acme/app#12 is on staging at 1a2b3c4)", and the **Pull requests** section says what GitHub last decided.

## If it goes sideways

- **"Nothing was connected."** You authorized with a different GitHub account from the one you sign in to Hydrant with, or that account can't read any repository in the installation. Switch GitHub accounts and try again, or ask someone with access to connect.
- **A repository is missing from Add repositories.** Only repositories your GitHub account could read when you connected are listed. Grant the app access on GitHub, then press **Connect another account** and pick the same account to refresh.
- **Reconnecting an account that already has Hydrant Connect installed.** GitHub only sends you back to Hydrant after a change. On GitHub, change the repositories Hydrant Connect can access and save. Hydrant connects the account when you land back here.
- **"Request sent."** You asked an organization owner to approve the install. Once they do, press **Connect repositories** again.
- **A repository says "In another workspace".** It's connected elsewhere. Remove it from that workspace's GitHub settings first.
- **A pull request didn't link.** Check the mention: `#46` alone doesn't count, and neither does text in backticks. Or paste the address with **+**.
- **"GitHub is rate limiting refreshes."** Wait a few minutes, then refresh the card again. Nothing is lost.
- **"Repository disconnected."** The repository was removed from Hydrant or from the installation on GitHub. The card keeps the last state Hydrant saw. Reconnect the repository to resume updates.
- **An issue didn't move.** The card and **Recent decisions** give the reason: it's paused, it wasn't in the rule's **Only from** stages, another linked pull request isn't there yet, or the pull request is from a fork. **Try it on a pull request** shows the same reasons before you change anything. Unlinking the pull request an issue was waiting on doesn't move it. The other pull request's change was already decided while it waited, so that move won't happen. Move the issue by hand; later changes on the other pull request are still decided as usual.
- **A Done issue didn't move to the next environment.** Check that every closing pull request has merged, that none is from a fork, and that each branch name matches exactly. Pressing refresh on a pull request's card checks its branches again. An issue that was already moved there once, or moved back by hand, stays put until a new closing pull request from a repository mapped to that environment merges or is newly linked.
- **"Waiting for access." next to a repository.** Its GitHub account hasn't accepted Hydrant's read access to repository contents. Press **Accept it on GitHub** and accept it there.
- **You want Hydrant out completely.** Use **Disconnect** in Settings, then uninstall **Hydrant Connect** on GitHub. Linked pull requests stay on their issues as history.

Contact: bots@hydrant.dev
