Skip to main content

GitHub Template Sync

Allegro supports syncing templates from a GitHub repository. When connected, templates are automatically synced whenever commits are pushed to the configured default branch.

How It Works

  1. An organization admin installs the Allegro GitHub App on their GitHub account or organization.
  2. After installation, Allegro records a sync link pointing the tenant at that installation.
  3. The admin selects a repository and default branch to sync from, which completes the link and registers a push webhook on the repository.
  4. On every push to that branch, a sync job is queued to update templates from the repository.

A single GitHub App installation can serve many repositories across many tenants. Each tenant syncs from at most one repository, but the same repository can be shared by several tenants. The installation, the per-tenant sync link, and the per-repository webhook are stored separately so one installation (for example on an alleyinteractive organization) can map different repositories to different tenants. See Mapping Repositories at the Platform Level.


Setting Up the GitHub App

1. Create a GitHub App

In your GitHub organization or personal account, go to Settings → Developer settings → GitHub Apps and create a new app with the following settings:

SettingValue
GitHub App nameYour app name (e.g. Allegro Template Sync)
Homepage URLYour Allegro instance URL
Webhook URLhttps://your-app.com/github/webhooks
Webhook secretA random secret string (set as GITHUB_WEBHOOK_SECRET in .env)
Post installation → Setup URLhttps://your-app.com/github/callback
Post installation → Redirect on update✅ Enabled

Permissions required:

  • Repository contents: Read-only

Subscribe to events:

  • Push
  • Installation
  • Installation repositories

2. Configure Environment Variables

After creating the GitHub App, add these values to your .env:

# GitHub App credentials
GITHUB_APP_ID=<your_app_id>
GITHUB_APP_PRIVATE_KEY="<your_pem_private_key>"
GITHUB_WEBHOOK_SECRET=<your_webhook_secret>

# The installation URL shown on the GitHub Sync settings page
# Format: https://github.com/apps/<app-slug>/installations/new
GITHUB_APP_URL=https://github.com/apps/your-app-name/installations/new
note

GITHUB_APP_PRIVATE_KEY should be the full PEM content of the private key generated in your GitHub App settings.


Installation Flow

When an admin visits Organization Settings → GitHub Sync and clicks Connect GitHub Repository:

  1. They are sent to GITHUB_APP_URL?state={encrypted_tenant_id} on GitHub.
  2. They install the app on their GitHub account/organization.
  3. GitHub fires an installation.created webhook to /github/webhooks, which creates a tenant-less GitHubAppInstallation record on the landlord database.
  4. GitHub redirects the user back to /github/callback?installation_id=XXX&state={encrypted_tenant_id}.
  5. The callback decrypts the state to identify the tenant and records a GitHubRepoSync row linking that tenant to the installation (with no repository selected yet).
  6. The admin is redirected to the GitHub Sync settings page where they select the repository and default branch.
  7. Upon submitting the form, the sync link is completed, a push webhook is registered on the repository, and an initial sync is queued.
important

The Setup URL in your GitHub App settings must be set to https://your-app.com/github/callback. Without this, the installation cannot be linked to the tenant.


Mapping Repositories at the Platform Level

The self-serve flow above always returns the admin to the tenant they started from, so it can only ever connect one repository to that one tenant. To map several repositories from a single shared installation to several tenants — for example, when one organization's installation hosts a separate template repository per tenant — super admins use the landlord tenant dashboard.

From Tenants in the landlord navigation, open a tenant's detail page. The GitHub Template Sync section lists every known installation; pick an installation, choose one of its repositories, set the branch, and connect. This creates the same GitHubRepoSync link as the self-serve flow, without a GitHub round-trip, so different repositories under one installation can be assigned to different tenants.

Installations only appear here after the GitHub App has been installed on the organization (which fires the installation.created webhook). There is no manual way to register an installation ID.


Sync Process

Template sync is handled by the SyncGitHubTemplates job. It:

  • Fetches each top-level directory containing an index.html from the repository at the configured branch (with optional index.css, index.js, and template.json).
  • Creates or updates corresponding Template records (matched by github_path).
  • Force-deletes synced templates no longer present in the repository.

Syncs are triggered:

  • Automatically when a push arrives on a configured default branch (via webhook). A push to a shared repository fans out: the job is dispatched once for every tenant whose sync link points at that repository and whose branch matches.
  • Manually via the Sync Now button on the GitHub Sync settings page (rate-limited to once per minute).

Disconnecting

Admins can disconnect GitHub sync from Organization Settings → GitHub Sync → Disconnect. This:

  • Deletes the tenant's GitHubRepoSync link.
  • Deletes the repository's push webhook only if no other tenant still syncs that repository (the webhook is reference-counted per repository).
  • Removes the sync_source from all templates, making them editable again.

Templates are not deleted when disconnecting.

Disconnecting a tenant from the landlord dashboard removes the sync link and reference-counted webhook the same way, but leaves that tenant's templates untouched.

Lifecycle teardown

When the GitHub App is uninstalled (installation.deleted) or loses access to a repository (installation_repositories removed), Allegro tears down the affected sync links and webhooks but never deletes synced templates — they remain in each tenant exactly as they were.


Database Schema

All three tables live on the landlord database. The installation, the per-tenant sync link, and the per-repository webhook are stored separately so one installation can map many repositories to many tenants.

github_app_installations

The GitHub App installation itself — one row per GitHub account/organization.

ColumnTypeDescription
installation_idbigint (unique)GitHub's installation ID
account_loginstring (nullable)GitHub account/org login name

github_repo_syncs

The tenant ↔ repository link — one row per tenant. repository and default_branch are null between installing the app and selecting a repository.

ColumnTypeDescription
tenant_idbigint (unique)The linked Allegro tenant
installation_idbigintGitHub installation this link uses
repositorystring (nullable)Full repository name (e.g. org/repo)
default_branchstring (nullable)Branch to sync from
last_sync_attimestamp (nullable)Time of last successful sync
last_sync_hashstring (nullable)Commit SHA of last sync
last_sync_errorsjson (nullable)Errors from the last sync attempt

github_repo_webhooks

The push webhook registered on a repository — one row per (installation, repository), shared by every tenant syncing that repository and reference-counted on disconnect.

ColumnTypeDescription
installation_idbigintGitHub installation that owns it
repositorystringFull repository name (e.g. org/repo)
webhook_idbigintGitHub's webhook ID on the repository