GitHub integration

Hiveship links GitHub pull requests to issues, auto-transitions issue status on PR lifecycle events, and surfaces PR review state inline on the issue detail page. The integration is webhook-driven — once configured, it works without human intervention.

What it does

  • PR linking — attach a PR URL to an issue manually (paste the URL on the issue detail page), or let Hiveship auto-link it from the branch name.
  • Branch-name auto-link — a PR opened on branch feat/eng-123-fix-x auto-attaches to issue ENG-123 as soon as GitHub fires the opened webhook. No PR-body magic strings required. Multi-identifier branches (e.g. fix/api-2-and-api-3-rollup) create one link per resolved issue.
  • Status auto-transition — workspace admins map PR lifecycle events to target workflow statuses. PR opened → issue moves to your "In Review" column; all PRs merged → issue moves to your "Done" column.
  • Review-state surfacing — PR approvals + change requests render as a small badge next to the PR status pill on the issue detail page.

Setting up the webhook

GitHub posts signed JSON events to https://hiveship.app/api/webhooks/github for every PR event in connected repos. Configure the webhook on each repo you want connected:

  1. Open the GitHub repo, navigate to Settings → Webhooks → Add webhook.
  2. Payload URL: https://hiveship.app/api/webhooks/github
  3. Content type: application/json
  4. Secret: any random string (Hiveship verifies the signature with the secret configured on the API server — coordinate with your Hiveship admin to keep them in sync).
  5. Events: select Pull requests and Pull request reviews. Other event types are ignored.
  6. Save. GitHub fires a test ping immediately — check the recent-deliveries panel.

The webhook parses each opened PR's branch name with a case-insensitive regex looking for prefix-number tokens (up to 10 per branch, de-duped). Each resolved issue gets one LinkedPR row. The match is workspace-agnostic by design — if the same prefix exists in multiple workspaces (a shared org/repo), the PR auto-links in all of them.

The auto-link only fires on the GitHub opened action. Subsequent events on the same PR (synchronize for new commits, edited for title / body changes, reopened after a manual close, ready_for_review off a draft) flow through different handlers and don't re-attempt the auto-link. If a human detached the link manually after the initial open, the detach stands — the auto- link won't put it back. The link row carries metadata.source = 'branch-autolink' so the project activity feed can distinguish webhook-driven links from human-driven ones.

PR-driven status auto-transition

Workspaces can map two PR lifecycle events to target workflow statuses. Configure them in Workspace settings → PR Automations. Absence = "off" — no surprise transitions on day-one connect.

EventTriggerCoordination rule
PR_OPENEDThe first PR linked to an issue (manual or auto-link).Doesn't re-fire under the default config — the target status is already set, so the no-op guard skips it. A workspace that later changes its PR_OPENED target status could re-fire on the next PR open if the issue isn't already in the new target.
PR_MERGEDA linked PR transitions to merged.Fires only when every sibling LinkedPR is also merged or closed. Closing an issue while a sibling PR is still open would be a category-fit own-goal.

Auto-transitions write an auto_status_transition activity row with source: 'pr-autotransition' in metadata, so the project activity feed renders them as "Auto …" rather than "System …". A 60-second deduplication window guards against duplicate fan-out from concurrent webhook deliveries.

v1 scope. Only PR_OPENED and PR_MERGED are available. PR_CLOSED_UNMERGED is deferred — the right semantics ("revert" vs "back to TODO") depend on workflow norms we want telemetry on before locking in. Per-issue opt-outs and per-project overrides are similarly deferred.

When a PR is closed without merging today, Hiveship updates the linked-PR status pill to closed (red) and emits an issue.pr_status_changed SSE + webhook event — but the issue status itself stays where it is. Move it manually if your workflow calls for it.

Review-state surfacing

The webhook also handles GitHub's pull_request_review events. The latest meaningful review state is denormalised onto each LinkedPR:

GitHub eventRecorded review state
submitted + review.state === 'approved''approved'
submitted + review.state === 'changes_requested''changes_requested'
submitted + review.state === 'commented'no update (comments don't gate)
dismissednull (review withdrawn)

GitHub's per-reviewer nuance (latest non-dismissed review per author) is collapsed to "latest event wins" in v1. Workspaces that need richer signal should look at the PR page itself. The badge only renders on open PRs — once a PR is merged or closed the review history is moot, and the PR status pill already tells the story.

The linked-PR list on the issue detail page

The Linked PRs section on each issue's detail page shows every attached PR with status (open cyan / merged purple / closed red), the repository name, and (on open PRs) the review-state badge. Click any PR to open it on GitHub.

Manually attach a PR by pasting the URL into the form at the bottom of the section. Manually detach by clicking the unlink icon — this is a hard detach: a future auto-link attempt on the same branch will not re-attach (the opened event only fires once per PR).

Limits + caveats

  • Multiple workspaces, same repo. The webhook is workspace-agnostic — if your org connects the same GitHub repo to two Hiveship workspaces, PR auto-link fires in both. This is intentional (shared org/repo scenarios) but worth knowing.
  • Idempotency. A concurrent webhook re-delivery doesn't create a duplicate LinkedPR row (the unique constraint (issueId, provider, prNumber) guards it); only the first successful insert writes an activity row + fires the SSE event.
  • Signature verification. Hiveship verifies the signature GitHub attaches to each delivery against the secret your Hiveship admin configured server-side. The string you paste into GitHub's webhook form must match what's on the server — coordinate with your admin when adding new repos.

Next steps