Jira status that follows your pull requests
Pull Request Status Sync reads your pull requests on Bitbucket Cloud, GitHub, or GitLab (any mix) and moves Jira tickets along for you: once every linked PR has enough real approvals, the ticket goes to the next status and the next person. It also lists tickets whose status disagrees with their PRs, and, only if you want it, can block moving tickets by hand before approval.
What it does
| Feature | Where | What happens |
|---|---|---|
| Auto-promote | Within seconds with webhooks; hourly otherwise | Tickets in your review status whose PRs are all approved move to the next status and person, per project, with a comment listing the PRs. Nothing moves until you add a rule. |
| Approvals panel | "PR approvals" on each ticket | Lists the ticket's pull requests, the approvals that count against the required number, why any didn't count, and where the ticket goes next. |
| Drift report | "PR status drift" page in each project | Lists tickets that are out of step: a PR is open but the ticket isn't in review, the ticket is Done with a PR still open, every PR is approved but the ticket is still waiting, or the ticket is in review with no PR. |
| Approval gate (optional, off by default) | Workflow validator "All linked PRs approved" | Blocks moving a ticket by hand until every open or merged PR that mentions it has enough counted approvals. The error names each PR that falls short and why. |
Use only what you need
Each feature has its own switch on the settings page: moving tickets is under Move tickets; the drift report and the optional block are under Advanced. Nothing stops people moving tickets by hand unless you turn the gate on.
- Auto-promote is on by default, but nothing moves until you add a rule. Switching it off stops all moves.
- Drift report is on by default. Switching it off removes the "PR status drift" page from every project within a few minutes.
- Approval gate is off by default. Turn it on, and add the validator to a workflow, to block hand moves until PRs are approved.
Permissions at a glance
The app only reads from your code host. It never pushes, comments, approves or merges there.
| Where | What the app can do | Why |
|---|---|---|
| Bitbucket Cloud | Read repositories and pull requests (a workspace OAuth client with Pull requests: Read, which includes Repositories: Read) | Find each ticket's PRs and their approvals |
| GitHub | Read pull requests and metadata, on the repositories you pick (fine-grained, read-only) | Same |
| GitLab | Read the API (read_api) | Same |
| Jira | Read tickets; move, reassign and comment on them, only in the projects your rules cover; look up users by name | Moving tickets along, and resolving "assign to" |
Tokens are stored encrypted, only ever sent to their own host, never shown again after saving, and deleted when you disconnect that host.
What counts as an approval
Bitbucket's approval count includes approvals that aren't really reviews. The app leaves these out, and every error message says which rule applied:
- The author's own approval. Bitbucket lets authors approve their own PRs. Off by default.
- Approvals from before the latest commit. On Bitbucket's Free plan, approvals survive new pushes. The app treats them as stale, so reviewers must approve code they have actually seen. On by default.
- Bot and CI approvals. List their Bitbucket account IDs in the settings.
- Approvals from an earlier review round. If a ticket leaves review (for example, it fails QA) and comes back, approvals given before it re-entered review don't count.
A merged PR always counts as satisfied. Declined PRs are ignored. If any PR or repository can't be read, the answer is "unknown": the gate blocks with the reason, and auto-promote holds the ticket. A Bitbucket outage never reads as "zero approvals" or as "approved".
How PRs are linked to tickets
A PR belongs to a ticket when the ticket key appears in it: on Bitbucket, in the title or source branch (PROJ-123 Fix login, feature/proj-123-login); on GitHub and GitLab, in the title or description, since their search doesn't cover branch names. Keys match whole, so PROJ-1 doesn't match PROJ-12. One ticket can have PRs in several repositories, and all of them must pass.
Set up
1. Connect your code host
Connect one or more. A ticket's PRs are gathered from every connected host, and all of them must pass.
Bitbucket Cloud: in Bitbucket, open Workspace settings → Apps and features → OAuth clients → Create OAuth client. Give it a name; on Authorization tick only Client credentials; on Scopes tick only Pull requests: Read (it includes Repositories: Read). Save, then paste the client ID and secret into the app. The client belongs to the workspace rather than to a person, so no one's Atlassian account password or API token is ever given to the app, and the app never writes to Bitbucket.
GitHub (github.com): create a fine-grained token with read-only Pull requests and Metadata access to the repositories to check, and enter the organization or user that owns them. Only reviews from people with write access count, and an approval only counts on the commit it was given for.
GitLab (gitlab.com): create a token with read_api and enter the group path (subgroups are included).
Avoid GitHub "classic" tokens: they can't be limited to read-only.
Self-hosted GitHub Enterprise Server and GitLab Self-Managed can't be reached: Atlassian's platform only lets the app call a fixed list of addresses.
2. Configure the app
In Jira, go to Settings → Apps → Pull Request Status Sync settings (Jira admins only). Fill in the card for each host you use, then click Save. The page checks each connection and reports what it can see. Optionally list the repositories to scan. That's faster for large workspaces.
| Setting | Default | Notes |
|---|---|---|
| Features | Gate on, auto-promote off, drift report on | Each can be switched off independently |
| Approval gate | Off | Opt in under Advanced |
| Block only in projects | All | Wherever the validator is added |
| Bypass label | None | For example hotfix |
| Approvals required per PR | 2 | 1 to 10 |
| Review status | Code Review | Used for the re-review rule and the drift report |
| Ignore approvals before the latest commit | On | |
| Count the author's own approval | Off | |
| Bot/CI approver account IDs | None | Comma-separated Bitbucket account IDs |
| Repositories by project | None | For example APP: api, web-ui. Needed on workspaces with more than about 30 repositories |
| Promotion rules | Code Review → Ready for QA or Ready for UAT, assignee unchanged | See step 4 |
3. Set up promotion rules
Each rule covers a set of projects and says where approved tickets go and who gets them next:
| Field | Example | Notes |
|---|---|---|
| Projects | APP, WEB | Blank means every project |
| From | Code Review | The review status for these projects |
| To (in order) | Ready for QA, Ready for UAT | The first status the ticket's workflow offers wins, so projects with a QA step go to QA and the rest go to UAT |
| Then assign to | A specific person, project lead, reporter, unassigned, or leave as is | For example, the team's QA engineer. Type a name or email and the app looks up the account. |
If a ticket matches several rules, the first one wins. If none of the target statuses can be reached, the ticket is held and the reason lists the transitions that were available.
4. Go live
Before saving a rule, click Preview to see what it would do, ticket by ticket. Save, and tickets start moving. Each run's result is shown under Activity on the settings page.
5. Optional: instant moves with webhooks
Without webhooks, approved tickets move on the next hourly run. With them, seconds after the last approval. On the settings page, click Show webhook URL and secret, then add a webhook in each code host:
- GitHub (organization or repository → Settings → Webhooks): payload URL, content type
application/json, the secret, and the events Pull requests and Pull request reviews. - GitLab (project, or group on paid plans → Settings → Webhooks): the URL, the secret as the Secret token, and Merge request events.
- Bitbucket (repository → Repository settings → Webhooks): the URL, the secret, and the pull request events Created, Updated, Approved, Approval removed, Merged.
Every delivery must be signed with the secret; anything else is rejected. The settings page lists recent deliveries and what each one did. Regenerate secret if it ever leaks, then update the webhooks.
6. Optional: block hand moves until approved
Under Advanced, tick Block moving a ticket by hand. Then edit a company-managed workflow, select the transition to guard (for example Code Review → Done), add the validator All linked PRs approved, and publish the workflow.
You decide how strict it is:
- Block only in projects: list the projects the gate applies to. Everywhere else, people can move tickets freely, even on a shared workflow.
- Bypass label: set a label such as
hotfix. Any ticket carrying it can move without approvals. It's visible on the ticket, so bypasses stay auditable. - Untick it to allow every hand move again, without editing workflows. Auto-promote never skips approvals, whatever the label.
Team-managed projects don't support app-provided validators, so the gate is company-managed only. Everything else works in both.
Limits
- Cloud-hosted code only: Bitbucket Cloud, github.com and gitlab.com. Bitbucket Data Center, GitHub Enterprise Server and GitLab Self-Managed aren't supported.
- Without webhooks, auto-promote runs hourly. The gate always checks live when someone makes the transition.
- Each check must finish within Jira's time and request limits. The gate reads up to 60 repositories, and the drift report and preview up to 30. On larger workspaces, list each project's repositories under Repositories by project; checks over the limit are blocked with that instruction rather than guessed. The hourly sweep reads up to 500 repositories.
- Bitbucket allows about 1,000 API requests an hour per account (more on large paid workspaces). Mapping projects to their repositories keeps busy sites well under it.
- The drift report and auto-promote look at open PRs and at PRs merged in the last 30 days. The drift report checks up to 200 tickets per project (open, or updated in the last 14 days).
- If the site's paid license lapses, the gate lets transitions through and auto-promote pauses, so an expired subscription never locks your workflow.