# Set up the GitHub App

> Create the instance's GitHub App from /setup, what it asks for and why, and installing it.

Tack talks to GitHub through a GitHub App that you own. `/setup` creates it from a manifest: GitHub fills in the permissions, events and URLs, and you confirm.

## Create the app

1. Visit `/setup` on your instance. If it says “Tack needs a secret first”, set [`TACK_SECRET`](https://tack.social/self-hosting/deploy.md#secrets): the page offers one, made in your browser (it never leaves it), with the command to set it. Then choose **I’ve set it: check again**.

2. **Who owns the app?** Choose **My account**, or **An organisation** and type its login. Choose the account that owns the repositories you’ll plan with: GitHub only lets a private app be installed on the account that owns it.

3. **App name**: something like `Tack (tack.example.com)`. It has to be unique across GitHub, and is at most 34 characters.

4. Choose **Create GitHub App**. GitHub shows the app it’s about to create; confirm it there.

5. GitHub sends you back, and Tack signs you in with the new app: “Your GitHub App is ready. You’re this instance’s admin.”

The app is created **private**, with its webhook pointed at `https://your-instance/webhooks/github`, sign-in at `/auth/callback`, and installs returning to `/setup/installed`. Tack keeps its credentials (the app’s private key, client secret and webhook secret) in the instance’s storage, encrypted with `TACK_SECRET`.

Whoever created the app becomes the first admin when they sign in, which happens straight away (the claim lasts 24 hours, in that browser). For an app owned by a personal account, that account’s owner becomes admin on signing in, as long as there’s no admin yet.

## What it asks for, and why

| Permission           | Access         | Why                                                                                                                                            |
| -------------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| Metadata             | Read           | Required by GitHub: repositories, their visibility, which are installed                                                                        |
| Issues               | Read and write | Issue cards; creating issues, labels, milestones, assignees, closing and reopening, sub-issues, blocked-by links, and comments                 |
| Pull requests        | Read and write | Pull request cards, reviews and mergeability; opening ADR pull requests                                                                        |
| Contents             | Read and write | Numbering decision records from `docs/decisions/`, and committing a new record to its own branch                                               |
| Discussions          | Read and write | Discussion cards; labelling, closing, reopening and commenting on them; decisions and digests posted as Discussions                            |
| Checks               | Read           | CI on pull request cards                                                                                                                       |
| Commit statuses      | Read           | CI on pull request cards                                                                                                                       |
| Actions              | Read           | Workflow runs, for CI on pull request cards                                                                                                    |
| Organisation members | Read           | Checking membership of organisations on the instance’s [access list](https://tack.social/self-hosting/access.md), including private membership |

It asks for no permissions on people’s own accounts. Signing in uses the app’s own OAuth, with no extra scopes: people see what GitHub lets them see.

The app subscribes to these webhook events: **issues**, **issue comment** (for [comment commands](https://tack.social/automation/comment-commands.md)), **sub-issues** (so cards know which [parent issue](https://tack.social/writing-back/actions.md#when-some-already-have-a-parent) they have), **pull request**, **pull request review**, **check run**, **check suite**, **status**, **workflow run**, **discussion** and **discussion comment** (so discussion cards stay live), and **repository** (for renames, transfers and visibility changes). GitHub always sends installation events too.

Everything Tack writes is staged and pushed by a person, so the write permissions are only used when someone [pushes](https://tack.social/writing-back/pushing.md), as themselves or as the app.

### Apps set up before discussions were cards

An app made before Tack showed discussions as cards may not have the **Discussions** permission, or the **Discussion comment** event. Until it does, a discussion’s card says the app needs the permission, with **Review permissions**, and “Where it’s installed” says **Live · no Discussions**. To add them:

1. Open the app’s settings on GitHub (**App settings** on `/setup`), then **Permissions & events**.
2. Under Repository permissions, set **Discussions** to **Read and write**.
3. Under Subscribe to events, tick **Discussion** and **Discussion comment**, and save.
4. Each account the app is installed on gets a request to accept the new permission: an owner accepts it from the account’s Settings → Applications → Installed GitHub Apps → Configure. Its discussions’ cards load once they do.

## Install on repositories

On `/setup`, choose **Install on repositories**, then pick the repositories on GitHub. Back on `/setup`: “Installed. Cards from those repositories now update live.”

You don’t have to install it everywhere. **Public repositories work without it**, read-only and not live; installing it makes their cards live, lets Tack write to them, and makes private repositories visible to the people who can read them. See [Repositories, live and not](https://tack.social/self-hosting/repositories.md).

People can also install it from a board: a card that’s **Not live** links to **Install the app**, as does a read-only repository in the Share dialog, and comes back to the board afterwards. If they’re not an owner of the organisation, GitHub asks an owner to approve it: “Installation requested. An organisation owner needs to approve it on GitHub.”

To change which repositories the app is installed on later, open **App settings** from `/setup`, or the app’s page under the account’s Settings → Applications → Installed GitHub Apps → Configure.

## After setup

`/setup` stays as the instance’s settings page, for admins: **Install on repositories**, **App settings** (the app on GitHub), **Webhooks**, **Where it’s installed**, and [who can use the instance](https://tack.social/self-hosting/access.md). Admins also find it in the account menu, as **Instance settings**.

### The checklist

At the top of `/setup`, a checklist says where the instance stands, one step at a time: **Secret**, **GitHub App**, **Webhooks**, **Repositories** and **People**. Each step is checked when the page opens, and links to its part of the page. A step with a **!** is worth a look, and one with a **×** needs fixing; the next thing to do is ringed. “All set” means webhooks are arriving, every repository the app is installed on can be pushed to, and people besides the admins can sign in.

Before a planning session, open `/setup` and check it says All set, and that every repository you’ll plan with is under **Where it’s installed**.

### Webhooks

**Webhooks** asks GitHub how its latest deliveries to the instance went (from the app’s delivery log, so it sees the ones that never arrived) and whether the app sends them to this instance’s address:

| It says                   | What it means, and what to do                                                                                                                                                                                            |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Arriving**              | The latest delivery reached Tack. Ones that failed recently are redelivered by the cron trigger                                                                                                                          |
| **Waiting for the first** | Nothing’s been delivered yet. GitHub sends a delivery when something happens in a repository the app is installed on: open an issue to try it. If nothing arrives, check the webhook is **Active** in the app’s settings |
| **Not arriving**          | GitHub couldn’t connect. Check the instance answers at the webhook’s address: a custom domain that doesn’t resolve yet, or a Worker that isn’t deployed                                                                  |
| **Refused**               | Tack refused the delivery: its signature didn’t match. The webhook secret in the app’s settings must be the one Tack was set up with; if you changed it there, set the same value as `GITHUB_WEBHOOK_SECRET`             |
| **Failing**               | Tack answered with an error. The [logs](https://tack.social/self-hosting/observability.md) say why: look for `webhook.failed`                                                                                            |
| **Going elsewhere**       | The app sends its webhooks to another address, as after moving to a custom domain. Change the **Webhook URL** in the app’s settings to `https://your-instance/webhooks/github`                                           |
| **Off while local**       | The instance is on your machine, where GitHub can’t reach it. See [Local development](https://tack.social/self-hosting/local-development.md)                                                                             |

**Check again** asks GitHub afresh.

### Where it’s installed

**Where it’s installed** lists every account the app is installed on, the repositories each covers, and whether Tack can push there: “Live · Tack can push”, “Live, read-only” (the account hasn’t accepted the permissions Tack asks for), “Live · no Discussions” (it hasn’t accepted the Discussions permission, so discussions can’t be cards there), or “Suspended”.

Below them, **On boards, without the app** lists repositories Tack has looked for the app on (cards on boards, mostly) and not found it. Their cards still show if they’re public, but don’t update live, and Tack can’t push to them: install the app on any you’ll plan with.

There’s one app per instance: setup can’t be run again once it’s done.
