> ## 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 Python: deploy da GitHub

> Fai il deploy da GitHub con client.apps.deploys: imposta un webhook, collega un repository con la GitHub App di Square Cloud e leggi la cronologia dei deploy.

`client.apps.deploys` collega un'app a GitHub in modo che un push ne esegua il deploy. Ci sono due modi per farlo: un **webhook** che aggiungi al repository, oppure la **GitHub App di Square Cloud**.

Gli esempi usano il `client` di [Creare il client](/it/sdks/py/client#creare-il-client). `app_id` è l'id di una delle tue app: [`client.account.me()`](/it/sdks/py/client#account) le elenca.

## Webhook

`deploys.set_webhook(app_id, access_token)` configura i deploy tramite webhook di GitHub con un token di accesso GitHub (`ghp_...` o `github_pat_...`) e restituisce l'URL del webhook da aggiungere al tuo repository.

```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
```

Passa `"@"` come token per rimuovere il webhook. In quel caso il metodo restituisce `''`.

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

Un token non valido produce 400 `INVALID_ACCESS_TOKEN`.

## GitHub App

`deploys.link_github_app(app_id, repository, branch)` collega un repository installato tramite la GitHub App di Square Cloud. Richiede lo 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)` rimuove il collegamento. Per collegare un altro repository o branch, scollega prima quello attuale.

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

Collegamento e scollegamento condividono un limite di **3 chiamate ogni 60 secondi**.

| Status | Codice | Quando |
| - | - | - |
| 400 | `GIT_ALREADY_CONFIGURED` | L'app ha già un repository collegato: scollegalo prima |
| 400 | `GIT_NOT_CONFIGURED` | `unlink_github_app` senza nulla di collegato |
| 400 | `BRANCH_NOT_FOUND`, `INVALID_BRANCH_LENGTH` | Il branch non esiste, oppure il suo nome supera i 256 caratteri |
| 403 | `GITHUB_NOT_CONNECTED` | Il tuo account non ha un'installazione della GitHub App |
| 403 | `REPOSITORY_NOT_AVAILABLE` | La GitHub App non è installata sul repository tramite il tuo account GitHub |
| 403 | `REPOSITORY_PERMISSION_REQUIRED` | Il tuo account GitHub non ha accesso in scrittura al repository |
| 404 | `REPOSITORY_NOT_FOUND` | Il repository non esiste o non è visibile |
| 409 | `REPOSITORY_BRANCH_ALREADY_CONFIGURED` | Un'altra app, di qualsiasi account, collega già questo repository e branch. Il suo id compare in `message` solo quando quell'app è tua |
| 502 | `FAILED_TO_FETCH` | GitHub non ha confermato il branch: puoi riprovare in sicurezza |

## Configurazione attuale

`deploys.current(app_id)` restituisce ciò che è configurato: `app` per il collegamento alla GitHub App, `webhook` per l'URL del webhook. Restituisce `{}` quando non c'è nulla di impostato.

```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"])
```

## Cronologia dei deploy

`deploys.list(app_id)` restituisce una **timeline per ogni deploy**, ciascuna una lista di eventi, dall'evento più vecchio. Vengono registrati solo i deploy Git (push tramite webhook e 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 | Descrizione |
| - | - |
| `id` | Lo SHA del commit |
| `state` | `pending`, `clone`, `commit`, `restarting`, `success` o `error` |
| `date` | Quando è avvenuto l'evento |
| `source` | Sempre `"git"` |
| `branch` | Negli eventi `clone` |
| `files` | Negli eventi `commit`: `{ added, removed, modified }` |
| `code` / `message` | Negli eventi `error`: perché il deploy è fallito (ad esempio `CLONE_FAILED`) |

## Prossimi passi

<CardGroup cols={3}>
  <Card title="Rete" icon="globe" href="/it/sdks/py/network">
    Analytics, DNS, domini personalizzati e cache.
  </Card>

  <Card title="Riferimento API dei deploy" icon="code" href="/it/api-reference/endpoint/apps/deploy/list">
    Gli endpoint REST dietro questi metodi.
  </Card>

  <Card title="Deploy da GitHub con la CLI" icon="terminal" href="/it/cli-reference/github-deploys">
    Le stesse azioni dal terminale.
  </Card>
</CardGroup>
