GitHub integration
Link pull requests to trackica issues and watch development progress from the issue.
Once GitHub is connected, trackica automatically links pull requests based on issue identifiers. Issue detail shows PR state, change size, CI results, and merge conflicts in place.
The GitHub integration only reads the repositories authorized at install time; it never pushes commits, comments, or status checks.
A private trackica deployment can also connect Forgejo, Gitea, or GitLab instances in parallel, with the same PR auto-linking, merge-to-Done, and CI display. The entry point is Settings → Integrations → Git hosting; see Self-hosted Git hosting.
Connect GitHub
A workspace owner or admin can complete the connection:
- Open Settings → GitHub.
- Turn on the GitHub integration master switch.
- Click Connect GitHub.
- In GitHub, pick the account or organization and authorize all repositories or a chosen subset.
- Return to trackica after the installation completes.
The connection status shows on the same page. Regular members can view the status but can't connect, disconnect, or change the switches.
The GitHub connection decides which repositories trackica receives PR events from; the code repositories setting decides which repositories agents can pick when running tasks. They serve different purposes and are configured separately.
Feature switches
Settings → GitHub has four switches:
| Switch | Effect |
|---|---|
| GitHub integration | Master switch. When off, the three below stop working, but the GitHub App stays connected. |
| PR sidebar | Shows linked pull requests in issue detail. |
| Co-authored-by | Adds Co-authored-by: trackica-agent <github@multica.ai> to commits created by agents. |
| Auto-link PRs | Detects issue identifiers in a PR's branch name, title, and body. |
| PR card → CI & mergeability | For each linked PR, trackica fetches an authenticated GitHub API snapshot and mirrors its CI status and mergeability onto the card (see What the PR card shows below). |
Link a PR to an issue
The simplest approach is to put the issue identifier in the branch name or PR title. For example, for issue TRK-123:
mul-123-fix-login-redirectTRK-123 Fix the redirect after logintrackica ignores case and only matches the current workspace's issue prefix. One PR can link to multiple issues.
If the identifier appears only in the PR body, use one of GitHub's close intents:
Closes TRK-123
Fixes TRK-123
Resolves TRK-123A reference-only mention in the body, such as Related to TRK-123, is not shown as a working PR for that issue. Commit messages and PR comments don't trigger linking either.
View PRs on an issue
Once linked, PRs appear in the Pull requests block of issue detail. Each entry shows:
- repository, number, title, and author;
Open,Draft,Merged, orClosedstate;- added and deleted lines and the number of changed files;
- CI status: all passed (with a count), some failed (naming the failing checks), or some in progress; PRs with no checks configured don't show this item — "no checks" is never treated as passing;
- mergeability: mergeable (only when GitHub reports a clean merge state), conflicting, blocked, or behind.
CI status and mergeability come from snapshots trackica pulls from the GitHub API, and the two are independent; merged or closed PRs no longer show either. When GitHub is temporarily unavailable, the card keeps the last snapshot and marks it stale instead of going blank.
Click an entry to open the PR on GitHub. Turning off the PR sidebar only hides this block; it doesn't disconnect anything.
When a merged PR moves an issue to Done
A merged PR doesn't necessarily mean the issue is finished. trackica only moves an issue to Done when all of the following hold:
- at least one merged linked PR used a close intent immediately followed by the identifier, such as
Closes TRK-123(forms with words in between, likeCloses login TRK-123, don't count); - the issue has no other working PR still
OpenorDraft(reference-only mentions in the body don't count); - the issue is not currently
doneorcancelled.
So writing TRK-123 only in the branch name or title establishes the link but doesn't by itself trigger completion. A PR closed without merging doesn't complete the issue either.
The status change is written to the timeline as a system action, and members subscribed to the issue are notified.
Multiple workspaces
The same GitHub App installation can be connected to multiple trackica workspaces. GitHub events flow into each workspace separately and are matched against each workspace's own issue prefix.
For example, a PR that references both TRK-1 and ENG-2 can link in two workspaces with different prefixes. Workspaces never see each other's issues.
Disconnect
Clicking Disconnect in Settings → GitHub only removes the relationship between the current trackica workspace and the installation; it does not uninstall the App from GitHub for you. Existing PR records are kept, and new events stop flowing into that workspace.
To revoke repository authorization on the GitHub side, uninstall the App or adjust its repository scope from your personal or organization GitHub App installations page. After uninstalling, every trackica workspace linked to that installation stops receiving events.
Self-hosting setup
A private deployment administrator must create and configure a GitHub App first.
1. Create a GitHub App
Create the App under GitHub's Developer settings → GitHub Apps and fill in:
| Field | Value |
|---|---|
| Homepage URL | Your trackica frontend address, e.g. https://trackica.example.com |
| Callback URL | Leave blank |
| Setup URL | https://<api-host>/api/github/setup, with Redirect on update enabled |
| Webhook URL | https://<api-host>/api/webhooks/github |
| Webhook secret | A random string you keep long-term |
Repository permissions:
| Permission | Level |
|---|---|
| Metadata | Read-only |
| Contents | Read-only; required by the PR snapshot query, which reads the head commit together with mergeability and the CI rollup |
| Pull requests | Read-only |
| Checks | Read-only; used to show CI status |
| Commit statuses | Read-only; used to aggregate legacy-status CI |
Subscribe to these events:
- Pull request;
- Check suite, Check run, and Status, which trigger CI and mergeability refreshes.
If you don't need CI shown in trackica, you can skip the Checks and Commit statuses permissions and their events. Contents is still required — without it the snapshot query fails outright and the PR card also loses merge state.
This is the Webhook secret, not the OAuth Client secret. If the two sides have different webhook secrets, GitHub deliveries return 401 invalid signature.
2. Set environment variables
Take the slug from the App's public URL. For example, the slug of https://github.com/apps/trackica-acme is trackica-acme.
GITHUB_APP_SLUG=trackica-acme
GITHUB_WEBHOOK_SECRET=<the webhook secret you entered when creating the App>
FRONTEND_ORIGIN=https://trackica.example.comIf either GITHUB_APP_SLUG or GITHUB_WEBHOOK_SECRET is missing, the connect button is disabled and the webhook endpoint refuses to process events.
The next two variables are required for the PR card to show CI status and mergeability — trackica uses them to authenticate as the App and pull snapshots:
GITHUB_APP_ID=<the GitHub App's numeric ID>
GITHUB_APP_PRIVATE_KEY=<full PEM private key, keeping the BEGIN/END lines and newlines>Generate the private key under the GitHub App's Private keys → Generate a private key. Without them the integration degrades gracefully: PRs still mirror, issues still auto-link and move to Done on merge — the PR card just shows no CI or merge state.
3. Update the database and connect
When upgrading an existing deployment, run the regular database migrations first:
make migrate-upRestart the API server, then complete the connection in Settings → GitHub.
Troubleshooting
- Connect button disabled: check that
GITHUB_APP_SLUGandGITHUB_WEBHOOK_SECRETreached the API process. - Webhook returns 401: confirm the GitHub App and the API use the same webhook secret, then redeliver from GitHub's Recent Deliveries.
- PR not linked: check that the repository is in the App's authorized scope, auto-linking is on, and the identifier belongs to the current workspace.
- Identifier in the body but not shown: switch to
Closes TRK-123, or put the identifier in the branch name or PR title. - No CI status: confirm
GITHUB_APP_IDandGITHUB_APP_PRIVATE_KEYare configured, and that the App has read-only Contents, Checks, and Commit statuses permissions with the matching events subscribed. Without Contents the whole snapshot fails, so the PR card shows neither CI nor merge state. After adding permissions to an installed App, each installation's owner must also approve them on GitHub before they take effect. - Issue not completed after the PR merged: confirm the PR used a close intent, and check whether other linked PRs are still Open or Draft.
Next steps
- Issues — how status transitions relate to merge-to-Done.
- Project resources — which repositories agents use when running.
- Environment variables — the full self-hosted GitHub App configuration.