---
slug: cli/github
title: afy github — Aetherfy GitHub App and auto-deploy
kind: reference
surface: cli
summary: Reference for afy github in the Aetherfy CLI — connect, disconnect, status, link, and unlink, covering the GitHub App installation, the --branch and --root-dir flags, and the one-time webhook secret.
sources:
  - aetherfy-cli:cmd/github.go
  - aetherfy-cli:internal/api/github.go
---

# afy github

## The afy github command group in the Aetherfy CLI

`afy github` connects a GitHub account to Aetherfy and links repositories to
agents so that a push deploys them.

| Subcommand | Purpose |
|---|---|
| `afy github connect` | Install the Aetherfy GitHub App |
| `afy github disconnect` | Remove the stored installation |
| `afy github status` | Show the current connection |
| `afy github link <agent> <repo>` | Link a repository to an agent |
| `afy github unlink <agent>` | Remove an agent's repository link |

All five subcommands exit 1 on failure, which makes this group safe to use in a
script without inspecting the printed output.

The usual sequence is connect once, then link each Aetherfy agent:

```bash
afy github connect
afy github link catalogue-scraper myorg/agents --branch main --root-dir services/scraper
```

## Connecting GitHub to Aetherfy

`afy github connect` installs the Aetherfy GitHub App. It takes no arguments and
no flags.

```bash
afy github connect
```

The command opens the installation URL in a browser. When it cannot open one, it
prints the URL for you to visit manually.

One installation covers **every repository you grant it access to** during the
GitHub install flow. You do not run `afy github connect` per repository — connect
once, then use `afy github link` for each agent.

## Checking the Aetherfy GitHub connection status

`afy github status` shows the current state of the connection. It takes no
arguments and no flags.

```bash
afy github status
```

It prints whether GitHub is connected, the installation ID, and the time the
connection was made.

## Disconnecting GitHub from Aetherfy

`afy github disconnect` removes the stored installation. It takes no arguments
and no flags.

```bash
afy github disconnect
```

| Property | Behaviour |
|---|---|
| Idempotency | Idempotent — it succeeds even when nothing is connected |
| Existing deployments | Unaffected; already-deployed agents keep running |
| Auto-deploys | Stop |
| Full revocation | Disconnecting on the Aetherfy side does not uninstall the App on GitHub |

To revoke Aetherfy's access completely, also uninstall the Aetherfy GitHub App
from your GitHub account or organisation settings.

## Linking a repository to an Aetherfy agent

`afy github link <agent> <repo>` links a repository to an agent so that pushes
deploy it. It takes exactly two positional arguments.

| Flag | Short | Type | Default | Description |
|---|---|---|---|---|
| `--branch` | `-b` | string | empty | Branch to watch (default: main, or embedded @branch in repo arg) |
| `--root-dir` | | string | empty | Repo-relative folder holding this agent's code and aetherfy.yaml (default: the repository root) |

The `<repo>` argument is `owner/repo` or `owner/repo@branch`. When both an
`@branch` suffix and `--branch` are given, `--branch` wins.

```bash
# Watch main at the repository root
afy github link catalogue-scraper myorg/agents

# Watch a branch, via the @suffix
afy github link catalogue-scraper myorg/agents@production

# Watch a branch and a subdirectory of a monorepo
afy github link catalogue-scraper myorg/agents \
  --branch production \
  --root-dir services/scraper
```

`--root-dir` is what makes a monorepo work on Aetherfy: it points at the folder
holding this agent's code and its `aetherfy.yaml`, so several agents can be
linked to the same repository at different paths.

Linking registers a push webhook. Pushes to the configured branch trigger an
Aetherfy deployment of the code at `--root-dir`.

## The Aetherfy webhook secret printed by link

`afy github link` prints the webhook secret **once**, at link time. Aetherfy does
not store it in retrievable form and no command will show it again.

| Question | Answer |
|---|---|
| Can I read it later? | No |
| How do I rotate it? | Re-run `afy github link` for the same agent |
| Does re-linking break auto-deploy? | No — the new webhook is created before the old one is removed |

Because re-linking creates the replacement webhook first and only then removes
the previous one, there is no window in which pushes to the repository go
unnoticed by Aetherfy.

## Unlinking a repository from an Aetherfy agent

`afy github unlink <agent>` removes the repository link. It takes exactly one
positional argument and no flags.

```bash
afy github unlink catalogue-scraper
```

The command is idempotent — unlinking an agent that has no link succeeds. The
GitHub webhook is deleted on a best-effort basis, so a webhook may survive on the
GitHub side if the deletion call fails; Aetherfy will no longer act on it either
way.

Removing the link stops auto-deploys for that agent. Manual `afy deploy` is
unaffected — see [/cli/deploy](/cli/deploy).

## Choosing between Aetherfy auto-deploy and afy deploy --from-github

Aetherfy offers two paths from a GitHub repository to a running agent, and they
suit different situations.

| | `afy github link` | `afy deploy --from-github` |
|---|---|---|
| Repository visibility | Public or private | Public only |
| Trigger | A push to the watched branch | The command you run |
| Setup | Requires `afy github connect` | None |
| Monorepo subdirectory | `--root-dir` | Not supported |
| Local `git` required | No | Yes |
