> ## Documentation Index
> Fetch the complete documentation index at: https://docs.squarecloud.app/llms.txt
> Use this file to discover all available pages before exploring further.

# SDK de Python: deploys desde GitHub

> Haz deploy desde GitHub con client.apps.deploys: configura un webhook, vincula un repositorio con la GitHub App de Square Cloud y consulta el historial.

`client.apps.deploys` conecta una aplicación a GitHub para que un push la despliegue. Hay dos formas de hacerlo: un **webhook** que añades al repositorio, o la **GitHub App de Square Cloud**.

Los ejemplos usan el `client` de [Crear el cliente](/es/sdks/py/client#crear-el-cliente). `app_id` es el id de una de tus aplicaciones: [`client.account.me()`](/es/sdks/py/client#cuenta) las lista.

## Webhook

`deploys.set_webhook(app_id, access_token)` configura los deploys por webhook de GitHub con un token de acceso de GitHub (`ghp_...` o `github_pat_...`) y devuelve la URL del webhook que debes añadir a tu repositorio.

```python theme={"system"}
url = client.apps.deploys.set_webhook(app_id, os.environ["GITHUB_TOKEN"])

print(url)  # add it as a webhook in the repository settings
```

Pasa `"@"` como token para eliminar el webhook. En ese caso, el método devuelve `''`.

```python theme={"system"}
client.apps.deploys.set_webhook(app_id, "@")
```

Un token no válido da 400 `INVALID_ACCESS_TOKEN`.

## GitHub App

`deploys.link_github_app(app_id, repository, branch)` vincula un repositorio instalado a través de la GitHub App de Square Cloud. Necesita el scope `apps:deploy`.

```python theme={"system"}
repo = client.apps.deploys.link_github_app(app_id, "octocat/hello-world", "main")

print(repo["id"], repo["full_name"], repo["branch"])
```

`deploys.unlink_github_app(app_id)` elimina la vinculación. Para vincular otro repositorio o rama, desvincula primero.

```python theme={"system"}
client.apps.deploys.unlink_github_app(app_id)
```

Vincular y desvincular comparten un límite de **3 llamadas cada 60 segundos**.

| Estado | Código | Cuándo |
| - | - | - |
| 400 | `GIT_ALREADY_CONFIGURED` | La aplicación ya tiene un repositorio vinculado: desvincúlalo primero |
| 400 | `GIT_NOT_CONFIGURED` | `unlink_github_app` sin nada vinculado |
| 400 | `BRANCH_NOT_FOUND`, `INVALID_BRANCH_LENGTH` | La rama no existe, o su nombre supera los 256 caracteres |
| 403 | `GITHUB_NOT_CONNECTED` | Tu cuenta no tiene ninguna instalación de la GitHub App |
| 403 | `REPOSITORY_NOT_AVAILABLE` | La GitHub App no está instalada en el repositorio a través de tu cuenta de GitHub |
| 403 | `REPOSITORY_PERMISSION_REQUIRED` | Tu cuenta de GitHub no tiene acceso de escritura al repositorio |
| 404 | `REPOSITORY_NOT_FOUND` | El repositorio no existe o no es visible |
| 409 | `REPOSITORY_BRANCH_ALREADY_CONFIGURED` | Otra aplicación, de cualquier cuenta, ya vincula este repositorio y esta rama. Su id aparece en `message` solo cuando esa aplicación es tuya |
| 502 | `FAILED_TO_FETCH` | GitHub no confirmó la rama: se puede reintentar sin riesgo |

## Configuración actual

`deploys.current(app_id)` devuelve lo que está configurado: `app` para la vinculación con la GitHub App, `webhook` para la URL del webhook. Devuelve `{}` cuando no hay nada configurado.

```python theme={"system"}
current = client.apps.deploys.current(app_id)

if "app" in current:
    print(current["app"]["name"], current["app"]["branch"])  # e.g. "octocat/hello-world" "main"
if "webhook" in current:
    print(current["webhook"])
```

## Historial de deploys

`deploys.list(app_id)` devuelve una **línea de tiempo por deploy**, cada una una lista de eventos, del evento más antiguo al más reciente. Solo se registran los deploys de Git (pushes por webhook y por GitHub App).

```python theme={"system"}
for timeline in client.apps.deploys.list(app_id):
    last = timeline[-1] if timeline else None
    if last is None:
        continue
    print(last["id"], last["state"], last["date"])

    if last["state"] == "error":
        print(last.get("code"), last.get("message"))
```

| Campo | Descripción |
| - | - |
| `id` | El SHA del commit |
| `state` | `pending`, `clone`, `commit`, `restarting`, `success` o `error` |
| `date` | Cuándo ocurrió el evento |
| `source` | Siempre `"git"` |
| `branch` | En los eventos `clone` |
| `files` | En los eventos `commit`: `{ added, removed, modified }` |
| `code` / `message` | En los eventos `error`: por qué falló el deploy (por ejemplo `CLONE_FAILED`) |

## Próximos pasos

<CardGroup cols={3}>
  <Card title="Red" icon="globe" href="/es/sdks/py/network">
    Analíticas, DNS, dominios personalizados y caché.
  </Card>

  <Card title="Referencia de la API de deploys" icon="code" href="/es/api-reference/endpoint/apps/deploy/list">
    Los endpoints REST detrás de estos métodos.
  </Card>

  <Card title="Deploys de GitHub desde la CLI" icon="terminal" href="/es/cli-reference/github-deploys">
    Las mismas acciones desde la terminal.
  </Card>
</CardGroup>
