# Auto-Deploy on Git Push

Wire up `git push` → ORB build. One POST, no humans.

## What this does

You call `POST /v1/computers/{id}/github/bootstrap` with a short-lived GitHub token. ORB:

1. Commits `.github/workflows/orb-deploy.yml` to your repo.
2. Stashes an `ORB_API_KEY` secret in that repo's GitHub Actions settings.
3. Triggers a first build.
4. Discards the token.

From that point on, every push to the configured branch runs the workflow, which curls `POST /v1/computers/{id}/build` with the stashed key. ORB pulls the latest commit, reruns your `build.steps`, redeploys your agent.

To turn it off: `POST /v1/computers/{id}/github/disconnect` with a fresh token. ORB deletes the workflow file and the secret.

## We never store your GitHub token

The token you pass in `pat` is held in memory for the single request it arrived on. It is never written to disk, never logged, never returned in a response, never kept after the request completes. Every bootstrap or disconnect call requires a fresh token.

If we lose your token, you lose nothing, generate another the same way you got the first one.

## Bootstrap

```
POST /v1/computers/{id}/github/bootstrap
Authorization: Bearer orb_YOUR_KEY
Content-Type: application/json

{
  "pat": "gho_...",          // required. used-and-discarded.
  "api_key": "orb_...",      // optional. if omitted, ORB generates a scoped key.
  "branch": "main"           // optional. defaults to source.branch from orb.toml.
}
```

Response:

```json
{
  "workflow_path": ".github/workflows/orb-deploy.yml",
  "workflow_commit_sha": "abc123...",
  "secret_name": "ORB_API_KEY",
  "api_key_id": "key_...",
  "first_build_id": "build_..."
}
```

Errors:
- `400`, computer has no `source.git`, or `pat` missing scopes (`repo`, `workflow`).
- `401`, ORB API key invalid.
- `404`, computer id doesn't exist.
- `422`, `source.git` isn't a GitHub repo ORB understands.
- `502`, GitHub API returned an error. Body contains GitHub's response verbatim.

## Disconnect

```
POST /v1/computers/{id}/github/disconnect
Authorization: Bearer orb_YOUR_KEY
Content-Type: application/json

{
  "pat": "gho_..."           // required. used-and-discarded.
}
```

Response:

```json
{
  "workflow_deleted": true,
  "secret_deleted": true
}
```

If ORB generated a scoped API key during bootstrap, the key itself stays in your keys list, disconnect doesn't revoke it. Delete it via `DELETE /v1/keys/{id}` if you want it gone.

## Suggested ways to obtain inputs

These are hints for the agent driving the request, not rules.

**PAT**, a GitHub token with `repo` + `workflow` scopes:
```bash
gh auth token                                    # if gh CLI is installed and logged in
cat ~/.config/gh/hosts.yml | grep oauth_token    # fallback: read the gh config directly
```
Otherwise: create at <https://github.com/settings/tokens> (classic, `repo` + `workflow` scopes) or use a fine-grained PAT with *Contents: write*, *Actions: write*, *Secrets: write* on the target repo.

**Repo**, ORB parses `owner/repo` from the computer's saved `source.git`. You don't pass it separately.

**Branch**, optional. Defaults to `source.branch`. If the agent wants to deploy a different branch than what's in `orb.toml`, pass `branch` explicitly.

**ORB API key**, optional. If you pass nothing, ORB creates a fresh key named `github-actions:<owner>/<repo>` and stashes that one. If you pass your existing key, ORB uses it verbatim.

## The workflow ORB commits

```yaml
name: Deploy to ORB
on:
  push:
    branches: ["<BRANCH>"]
  workflow_dispatch:

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - env:
          ORB_API_KEY: ${{ secrets.ORB_API_KEY }}
        run: |
          curl -fSs -X POST \
            https://api.orbcloud.dev/v1/computers/<COMPUTER_ID>/build \
            -H "Authorization: Bearer $ORB_API_KEY" \
            -H "Content-Type: application/json" \
            -d '{}'
```

`<BRANCH>` and `<COMPUTER_ID>` are substituted at bootstrap time. Edit the file in your repo after bootstrap if you want a different shape (additional branches, cache, secrets, notifications). ORB doesn't re-manage the file once it's committed, your repo owns it.

## Scopes the PAT needs

Classic PAT: `repo` + `workflow`.

Fine-grained PAT (preferred for paranoia, scoped to one repo):
- Contents: write, to commit the workflow file.
- Secrets: write, to stash `ORB_API_KEY`.
- Actions: write, to trigger workflows (optional; only needed if you call bootstrap again to re-trigger).
- Workflows: write, to commit files under `.github/workflows/`.

## Rotating the ORB API key

The `ORB_API_KEY` in GitHub Actions secrets is just a normal ORB API key. Rotate it like any other:

1. Create a new key: `POST /v1/keys`.
2. Update the secret via the GitHub UI or API: `PUT /repos/{owner}/{repo}/actions/secrets/ORB_API_KEY`.
3. Revoke the old one: `DELETE /v1/keys/{id}`.

Or run bootstrap again, ORB overwrites the secret with whatever you pass (or a new scoped key).

## When not to use this

- **One-off deploys.** Just call `POST /v1/computers/{id}/build` directly with `org_secrets.GITHUB_TOKEN` for the clone. No workflow file, no GitHub Actions.
- **You want us to keep the token.** We don't. If that's a dealbreaker for your threat model, use the `source.token` + `org_secrets` path, same token, but you choose when it's injected (it still isn't persisted beyond the build).
- **Your repo lives outside GitHub.** Bootstrap is GitHub-only for now. GitLab / Bitbucket are out of scope.
