Running ByteMatch

Creating the GitHub App

This guide is for instance operators. One GitHub App gives a ByteMatch instance:

  • webhooks, so CI results are ingested as soon as a workflow run finishes;
  • installation tokens, to download artifacts from repositories the App is installed on;
  • pull request comments;
  • Sign in with GitHub for the manage pages, through the App's OAuth client.

Without an App, ByteMatch still works by polling, but it needs a GITHUB_TOKEN to download artifacts (GitHub requires authentication even for public repositories), there are no PR comments, and nobody can sign in.

<host> below is your instance's public domain, the same as PUBLIC_URL.

1. Create the App

Go to GitHub → Settings → Developer settings → GitHub Apps → New GitHub App (or the same under an organization's settings to own it as the organization).

FieldValue
GitHub App nameAnything, e.g. ByteMatch (<host>). Its slug becomes GITHUB_APP_SLUG.
Homepage URLhttps://<host>
Callback URLhttps://<host>/auth/callback
Request user authorization (OAuth) during installationOff
Webhook: ActiveOn
Webhook URLhttps://<host>/api/github/webhook
Webhook secretA long random string, e.g. openssl rand -hex 32. Also goes in GITHUB_WEBHOOK_SECRET.
Where can this GitHub App be installed?Any account, so other projects can install it.

Repository permissions

PermissionAccess
ActionsRead-only
MetadataRead-only (mandatory)
Pull requestsRead and write

Leave every other permission at "No access".

Subscribe to events

  • Workflow run
  • Installation and Installation repositories (installation events are always sent)
  • Repository

Turn off user token expiry

On the App's page, open Optional features and opt out of User-to-server token expiration. ByteMatch keeps a signed-in user's GitHub token for the length of the session (30 days) to check which repositories they administer. With expiry on, GitHub revokes it after 8 hours and those checks start failing.

2. Generate the private key

On the App's page, under Private keys, choose Generate a private key. GitHub downloads a .pem file.

GITHUB_APP_PRIVATE_KEY holds the PEM contents. In .env you can keep it on one line with literal \n sequences:

awk 'NF {printf "%s\\n", $0}' bytematch.private-key.pem

Paste the output in double quotes:

GITHUB_APP_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nMIIE...\n-----END RSA PRIVATE KEY-----\n"

Keep the key out of the repository (*.pem is ignored by .gitignore), and delete the downloaded file once it is stored.

3. Create a client secret

On the App's page, under Client secrets, choose Generate a new client secret. Note the Client ID shown on the same page.

4. Fill in the environment

VariableWhere to find it
GITHUB_APP_IDApp page, "App ID"
GITHUB_APP_PRIVATE_KEYThe PEM from step 2
GITHUB_APP_SLUGThe last part of the App's public URL, https://github.com/apps/<slug>. Used for the "Install the App" link.
GITHUB_WEBHOOK_SECRETThe webhook secret from step 1
GITHUB_CLIENT_IDApp page, "Client ID"
GITHUB_CLIENT_SECRETThe client secret from step 3
SECRET_KEYopenssl rand -hex 32. Encrypts signed-in users' GitHub tokens. Sign-in is disabled without it.
PUBLIC_URLhttps://<host>, matching the URLs entered above

Optionally also set GITHUB_TOKEN to a fine-grained personal access token with public repository read access. It is used for repositories where the App is not installed.

Restart the web and worker processes after changing .env (yarn pm2:reload, or recreate the containers).

5. Check it

  1. Open https://<host> and sign in with GitHub.
  2. Install the App on a repository from a project's manage page, or from https://github.com/apps/<slug>.
  3. On the App's page, Advanced → Recent Deliveries shows webhook deliveries and their response codes. A failed signature check means GITHUB_WEBHOOK_SECRET does not match.

Notes

  • If PUBLIC_URL changes, update the webhook URL and callback URL on the App too.
  • Repository admins install the App on their own repositories; operators do not need access to them.
Next
Architecture