GitHub integration
Link pull requests to Clowld Space issues and watch development progress from the issue.
Once GitHub is connected, Clowld Space 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.
Self-hosted Clowld Space can also connect self-hosted Forgejo, Gitea, or GitLab instances in parallel, with the same PR auto-linking, merge-to-Done, and CI display. The entry point is Settings → Code; see Self-hosted Git hosting. Clowld Space does not offer this entry point.
Workspace PR auto-completion controls, per-issue exceptions and association exclusions ship from 1.2.4 and require the corresponding server and client.
Connect GitHub
A workspace owner or admin can complete the connection:
- Open Settings → Code.
- In the GitHub row, click Connect GitHub.
- In GitHub, pick the account or organization and authorize all repositories or a chosen subset.
- Return to Clowld Space 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 Clowld Space receives PR events from; the code repositories setting decides which repositories agents can pick when running runs. They serve different purposes and are configured separately.
Feature switches
The Pull requests & issues section of Settings → Code has these settings. Pause GitHub features in the GitHub row's ⋯ menu stops the three switches below without disconnecting the GitHub App.
| Switch | Effect |
|---|---|
| PR sidebar | Shows linked pull requests in issue detail. |
| Co-authored-by | Adds Co-authored-by: clowld-space-agent <github@clowld.com> to commits created by agents. |
| Auto-link PRs | Links a PR to the issue whose identifier is in its branch name or title, or follows a closing keyword in its body. |
| PR card → CI & mergeability | For each linked PR, Clowld Space fetches an authenticated GitHub API snapshot and mirrors its CI status and mergeability onto the card (see What the PR card shows below). |
In Settings → Code, After PRs merge, move the issue to chooses Done (the default), a started or done status, including custom statuses, or Don’t change. Blocked is excluded. Both providers use the same setting.
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 CS-123:
cs-123-fix-login-redirectCS-123 Fix the redirect after loginClowld Space 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, put it right after a closing keyword:
Closes CS-123
Fixes CS-123
Resolves CS-123A bare mention in the body, such as Related to CS-123, doesn't link the PR at all. Commit messages and PR comments don't trigger linking either.
You can also link a PR by hand: in the issue's Pull requests block, click + and paste the PR URL. To take a PR off an issue, open the ⋯ menu on its row and choose Remove from issue; Clowld Space won't link it again from its title or branch.
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 Clowld Space 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.
The line below the PR list names the target and the PRs still pending. It is hidden when there is no closing keyword, the workspace leaves status unchanged, or the issue is already at its target or terminal.
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
In Settings → Code, After PRs merge, move the issue to chooses Done (the default), a started or done status, including custom statuses, or Don’t change. Blocked is excluded. Both providers use the same setting.
The issue moves to the chosen status only when all of these conditions hold:
- at least one merged linked PR puts a closing keyword right before the identifier in its title or body, such as
Closes CS-123(forms with words in between, likeCloses login CS-123, don't count, and neither does a branch name); - no linked PR is
OpenorDraft; a PR closed without merging stays as history and does not block completion; - the issue is accepted, is neither done nor cancelled, differs from the target, and Pull requests → ⋯ → Keep status when PRs merge is off.
A title or branch identifier alone only links the PR. A closing keyword must be present at merge time; adding it afterwards cannot authorize a transition. A closed, unmerged PR remains history and does not block the move.
Only PR events evaluate this rule: merge, close, link or unlink. Changing settings or reopening an issue does not move it retroactively. Existing workspaces keep their prior enabled/disabled behavior. Status changes are recorded in the timeline and never start an agent run.
Multiple workspaces
The same GitHub App installation can be connected to multiple Clowld Space 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 CS-1 and ENG-2 can link in two workspaces with different prefixes. Workspaces never see each other's issues.
If one identifier matches an issue in more than one of the connected workspaces (possible when they share a prefix), Clowld Space doesn't link it automatically in any of them, so merging the PR can't complete an unrelated issue. Link the PR by hand in the right workspace.
Disconnect
Choosing Disconnect from the GitHub row's ⋯ menu on Settings → Code only removes the relationship between the current Clowld Space 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 Clowld Space workspace linked to that installation stops receiving events.
Self-hosting setup
Clowld Space doesn't need this section. Self-hosting requires creating your own 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 Clowld Space frontend address, e.g. https://clowld.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 |
| Actions | Read-only; used to receive terminal formal Release workflow results and to subscribe to job-level promotion CI failures |
| Checks | Read-only; used to show CI status |
| Commit statuses | Read-only; used to aggregate legacy-status CI |
Subscribe to these events:
- Pull request;
- Workflow run, which writes formal Release results back to the task;
- Workflow job, which writes an early failure notification with the failed job name and job log link when a single promotion CI job fails;
- Check suite, Check run, and Status, which trigger CI and mergeability refreshes.
If you don't need CI shown in Clowld Space, 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.
Without the Workflow job subscription (or without the Actions permission) nothing else changes: promotion failure notification falls back to the existing behavior after the whole Promotion Gate round completes, minus the job-level early warning.
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/clowld-acme is clowld-acme.
GITHUB_APP_SLUG=clowld-acme
GITHUB_WEBHOOK_SECRET=<the webhook secret you entered when creating the App>
FRONTEND_ORIGIN=https://clowld.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 — Clowld Space 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 → Code.
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, the identifier belongs to the current workspace, and nobody removed the PR from the issue.
- Identifier in the body but not linked: put it right after a closing keyword (
Closes CS-123), or in the branch name or PR title, or link the PR by hand. - 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. - The line below the PR list names the target and the PRs still pending. It is hidden when there is no closing keyword, the workspace leaves status unchanged, or the issue is already at its target or terminal.
Next steps
-
Issues — how status transitions relate to merge-to-Done.
-
Topic resources — which repositories agents use when running.
-
Environment variables — the full self-hosted GitHub App configuration.