# swb follow

Makes an installed app follow another of its channels from now on: a
development environment following the branch its people land on, or dev's own
Switchboard following the bolt in hand.

## Synopsis

```
usage: swb follow <app> <channel> --env <env> [--json]
```

## Arguments and flags

| Argument or flag | Takes | Default |
|---|---|---|
| `<app>` | The app's **id** — the app whose install follows the channel. Required. | — |
| `<channel>` | The **channel** to follow: `alpha/<branch>`, `beta`, `stable` or `lts-<name>`. A branch's channel or an LTS channel must have a head: something must have been published onto it. Required. | — |
| `--env` | An environment's **name or id**; a name is matched first. Required. | — |
| `--json` | Nothing. Prints the subscription as the API answered it instead of the one-line summary. | off |
| `--help`, `-h` | Prints the command's help and exits. | off |

## What it does

Calls `Mutation.followChannel` for the app's install in that environment with
a fresh client token, so a repeated call is one change rather than two. The
channel is recorded on the install's subscription, with who chose it and when;
its policy, its gate and any hold stay as they were. Following the channel
already followed changes nothing and still names who set it.

The change shows in the app's [history](/command-line/history), as a
`channel-followed` entry naming the channel and the one followed before, and
deploys the chosen channel's head as a new version of it would: within a minute
the install has a deploy of it, started by `CHANNEL` and requested by you, as
its subscription's policy and gate say — deployed at once under `auto`,
offered under `manual`, to run with [`swb run-deploy`](/command-line/run-deploy),
and waiting for an approver other than you under a gate. It replaces the deploy
the install was offered from the old channel and nobody ran. No deploy is
written where the install already runs the head with nothing waiting, or while
the channel has no head yet. From then on every new version of the chosen
channel reaches the install, and the old channel's pass it by.

A held install stays held: the change writes no deploy, and when the hold is
released with [`swb release-hold`](/command-line/release-hold) the install
goes to the head of the channel it now follows.

Switchboard's own install in the production class, the demo area, follows
only `stable` or an LTS channel, since it moves only when a person promotes a
version. Every other install follows the channel you choose, in the production
class as in any other.

## What it prints

```
switchboard in dev: not held, following alpha/bolt-invited-people
```

— the app, the environment, the version held, who held it and when where it
is held, and the channel the subscription now follows.

`--json` prints the subscription as the API answered it: `installId`,
`appId`, `environmentId`, `channel`, `policy`, `held`, `heldBy` (`kind`, `id`,
`via`, `name`) and `heldAt`.

## The operation and the permission

`Mutation.followChannel`. The caller needs `swb.deploys.run` on the tenant.
`swb follow` also reads `Query.me` once for the tenant and `Query.tenant` to
turn the `--env` name into an id.

## Refusals and exit status

Exit status is 0 once the channel is recorded, and 1 on every refusal below.

| Refusal | When |
|---|---|
| `swb follow takes <app> <channel>` | An argument is missing. |
| `swb follow needs --env <env>` | `--env` was not given. |
| `no environment named "<env>" in tenant <tenant> (have: dev, staging, prod)` | No environment of the tenant has that name or id. |
| `not signed in or token expired — run swb login` | There is no usable credential. |
| `NotFound: Install <app>#<env> not found` | The tenant has not installed the app in that environment. |
| `NotFound: ChannelSubscription <app>#<env> not found` | The install has no subscription. |
| `ValidationFailed: …` naming `channel` | The channel is not `alpha/<branch>`, `beta`, `stable` or `lts-<name>`. |
| `NotFound: Channel <app>#<channel> not found` | A branch's channel or an LTS channel nothing has been published onto. |
| `Refused: <app>#<env> is Switchboard's own install in the production class …` (`guard: release-only`) | Switchboard's own install in the production class, and a channel other than `stable` or an LTS channel. |
| `NotAuthorized: …` | The caller lacks `swb.deploys.run`. |
| `Conflict: …` | A hold, a release or another change of channel landed first; the refusal names the channel and the hold that stand. |

## Example

```console
$ swb follow switchboard alpha/bolt-invited-people --env dev
switchboard in dev: not held, following alpha/bolt-invited-people
```

Follow `beta` again to go back.
