Skip to content

Getting Started

Quick setup for hosted gondolier.

  • A Forgejo, Gitea, or Codeberg instance (self-hosted or public)
  • A GitHub account (for dashboard login)
  • A bot account or PAT with write scope on your forge instance (needed for the queue engine: it creates mq/* branches, writes statuses, and merges). To enable webhook wakeups and automatic branch protection the token also needs repo-admin scope — see Provisioning below.

Queue execution is live: gondolier reconciles your managed repos every 5 minutes (cron) with the Go Shunt engine, and optionally on forge webhooks.

  1. Go to gondolier.dev
  2. Click Sign in → authorize with GitHub
  3. Create or join an organization
  1. In the dashboard, go to ConnectionsAdd connection
  2. Enter your forge instance URL (e.g. https://git.example.com)
  3. Enter your bot username (e.g. mq-bot)
  4. Paste your PAT or token
  5. Click Add connection — the connection is stored (token encrypted at rest) and verified

Tip: If you’re on self-hosted Forgejo < 1.22, use a PAT. OAuth2 on older Forgejo gives full admin scope (no granular permissions yet).

Requirement Minimum scope
Queue execution (staging, merging, status writes) write
Webhook registration + branch protection (auto-provisioning) repo-admin (or repo + write:repository)
Discover repos (POST /connections/:id/discover) repo:read

If your token lacks repo-admin scope, gondolier will report provisioning items as Needs admin and show manual instructions in the dashboard.

  1. Go to RepositoriesAdd repository
  2. Select an existing connection (or create a new one)
  3. Enter the repository slug (e.g. owner/repo)
  4. Configure:
    • Base branch — usually main or master
    • Merge stylemerge, squash, or rebase
  5. Click Add

After adding, the dashboard shows the provisioning result:

  • WebhookReady | Needs admin | Not required (poll mode)
  • Branch protectionReady | Needs admin | Not configured | Error

If provisioning fails with Needs admin, the dashboard shows manual setup instructions. Grant your bot repo-admin scope and click Provision to retry.

Create .github/workflows/mq-gate.yml in your repo:

name: Merge Queue Gate
on:
pull_request_target:
types: [labeled]
permissions:
contents: read
jobs:
gate:
runs-on: ubuntu-latest
if: github.event.label.name == 'merge-queue'
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Run tests
run: echo "Replace with your test command"
# e.g., make test, go test ./..., npm test
- name: Set status
if: failure()
run: |
gh api repos/${{ github.repository }}/statuses/${{ github.event.pull_request.head.sha }} \
-f state=failure \
-f context=merge-queue \
-f description="Merge queue gate failed"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Each repo has a wakeup mode that controls how gondolier detects new PRs:

Mode Description Setup requirements
poll (default) Cron-driven, every 5 minutes. No webhook needed. None. Works with any token scope.
webhook Low-latency. Forgejo sends events to gondolier via webhook. repo-admin scope to register the webhook automatically, or manual setup (see below).

Change wake mode from the dashboard’s per-repo wake-mode selector. Switching to webhook triggers provisioning automatically.

Provisioning runs in two stages:

  1. On enrollment — best-effort, never blocks repo addition.
  2. On demand — click Provision to retry at any time (e.g. after granting the token more permissions).

What gets set up:

  • Webhook (webhook mode only) — registers a forge webhook pointing to https://api.gondolier.dev/api/v1/webhooks/forgejo with events: push, pull_request, issue_comment, release.
  • Branch protection — protects the base branch so PRs can only merge through the queue.
  • Required check — marks the repo’s status context (default merge-queue) as a required check on the base branch.

If provisioning reports Needs admin, the dashboard shows manual setup instructions (Forgejo webhook URL and branch protection settings). Grant the bot repo-admin scope, click Provision, and gondolier will detect the manual setup as Ready.

When using webhook mode:

  • The webhook URL is https://api.gondolier.dev/api/v1/webhooks/forgejo
  • Required events: push, pull_request, issue_comment, release
  • Content type: json
  • HTTP method: POST
  • The webhook secret is generated automatically per tenant

If you cannot grant repo-admin scope, set up the webhook manually in your forge instance settings using the values above. Gondolier will detect the existing webhook as Ready on the next check.

  1. Create a PR targeting the base branch
  2. Request auto-merge (Forgejo: click “Merge when ready”)
  3. The PR joins the queue automatically

Gondolier will:

  • Batch eligible PRs
  • Stage them on a mq/<branch>/staging branch
  • Wait for CI
  • Bisect on failure
  • Auto-merge on success

Gondolier polls your forge instance every 5 minutes (in poll mode) or receives webhooks (in webhook mode). When it sees eligible PRs, it runs the merge queue algorithm:

  1. Discovery — finds PRs with auto-merge scheduled
  2. Batching — groups them into a rollup (configurable size)
  3. Staging — creates a staging branch with all PRs cherry-picked
  4. Gate — waits for CI to pass on the staging branch
  5. Resolution — bisects on failure, merges on success

All state is re-derived from the forge API each cycle. Gondolier doesn’t persist queue state — it’s ephemeral and survives restarts gracefully.

The dashboard at gondolier.dev/dashboard has two peer sections:

Lists your managed repos with per-repo status:

  • Connection badge — clickable tooltip showing the bot, instance URL, and token type
  • Wake mode — inline selector (webhook | poll) with optimistic save
  • Provisioning — chips for webhook and branch protection status (Ready | Needs admin | Not required | Not configured | Error), hover to see details
  • Reconcile — status (ok | error | unknown) with last run timestamp
  • ActionsReconcile (one-shot), Provision (retry setup), Remove (with confirmation)

Lists your forge connections:

  • Shows bot username, instance URL, and token type
  • Edit — update instance URL, bot username, or rotate the token
  • Remove — with confirmation (managed repos cascade-delete)

Shows a per-repo health panel: queue name, reconcile state, lease state, and a Reconcile button.

For operators, the admin console at gondolier.dev/admin provides:

  • Authentication — enter the admin key (set via ADMIN_KEY secret) once per session
  • Repos tab — searchable list of all repos across all tenants with instance, owner (tenant ID), branch, bot, lease state, and last reconcile outcome
  • Connections tab — list of all connections across all tenants (token fields excluded)
  • Stats — overview counters for total repos and tenants

The admin key is validated via constant-time comparison and fails closed if absent.