claude/smbcloud-github-app-k9641p
smbCloud GitHub App
The smbCloud GitHub App connects a GitHub repository to an smbCloud project so
that pushes to the production branch deploy automatically — no smb deploy
needed. Deploy results are reported back to GitHub as commit statuses
(context: smbcloud/deploy).
How it works
- You install the app on your GitHub account or organization and grant it access to one or more repositories.
smb github connectlinks a repository (and a production branch) to your smbCloud project's deploy repo.- On every push, GitHub delivers a
pushwebhook tohttps://api.smbcloud.xyz/v1/github/webhook. The server verifies the webhook signature, matches the repository, installation, and branch against a connection, then builds and deploys the project's apps. - The server records a deployment (visible via
smb project deployment) and sets a commit status on the pushed SHA:pendingwhile building, thensuccessorfailure.
The webhook receiver and build pipeline are server-side; this repository ships the app manifest, the CLI commands, and the client-side API contract.
CLI usage
All commands accept --project-id <id>; without it they use the current
project (smb project use --id <id>). The project must have a deploy repo —
run smb deploy once to initialize it.
smb github install # open the app installation page, wait for it to complete
smb github connect # pick an installation + repository interactively
smb github connect --repo <owner>/<repo> --branch main # non-interactive, CI-friendly
smb github status # show the current connection
smb github disconnect # remove the connection (asks for confirmation)
smb github install opens the browser and polls the API until a new
installation appears. A GitHub App's setup URL is fixed app-wide and cannot
point at localhost, so a local callback server (as used for OAuth login) is
not possible here — polling is the intended flow. If the poll times out, just
finish the installation in the browser and run smb github connect.
Registering the app (operator, one-time)
The app is registered from github-app/manifest.json
using GitHub's manifest flow:
- Serve a small HTML form that POSTs a
manifestfield containing the JSON tohttps://github.com/settings/apps/new?state=<random>(orhttps://github.com/organizations/<org>/settings/apps/new?state=<random>for an org-owned app). - GitHub redirects to the manifest's
redirect_urlwith a temporarycode. - Exchange it within one hour:
POST https://api.github.com/app-manifests/<code>/conversions. The response contains the app id, slug, webhook secret, private key, and OAuth credentials — store these in your server configuration. - If the granted slug differs from
smbcloud, updateGH_APP_SLUGincrates/smbcloud-networking/src/constants.rs(the debug build uses a separatesmbcloud-devapp whose webhook targets a dev API).
Permissions and events
| Manifest entry | Why |
|---|---|
contents: read |
Fetch the repository at the pushed commit to build it. |
metadata: read |
Mandatory baseline for every GitHub App; powers repository listing. |
statuses: write |
Report deploy state as a commit status (one POST per state change). The Checks API adds no value for v1; upgrading to checks: write later is additive. |
default_events: ["push"] |
The only event auto-deploy needs. installation and installation_repositories events are always delivered to App webhooks without subscription — that is how the server tracks installs. |
API contract
Endpoints the CLI calls (all under the standard authenticated v1/ API;
implemented server-side):
| Method | Path | Request | Response |
|---|---|---|---|
| GET | v1/github/installations |
— | [GithubInstallation] — installations belonging to the authenticated user (correlated via their linked GitHub account) |
| GET | v1/github/installations/{installation_id}/repositories |
— | [GithubRepository] |
| GET | v1/deploy_repos/{deploy_repo_id}/github_connection |
— | GithubConnectionStatus — always 200, connected: false when absent |
| POST | v1/deploy_repos/{deploy_repo_id}/github_connection |
GithubConnectionCreate |
GithubConnection — upsert; omitted production_branch defaults to the repository's default branch |
| DELETE | v1/deploy_repos/{deploy_repo_id}/github_connection |
— | null (200, idempotent) |
| POST | v1/github/webhook |
GitHub webhook payload | server-only; never called by the CLI |
Response bodies must use 200/201 (not 204). The serde models live in
crates/smbcloud-model/src/github.rs; a connection may also arrive embedded in
a DeployRepo payload as github_connection.