Getting Started with Gondolier
Getting Started
Section titled “Getting Started”Quick setup for hosted gondolier.
Prerequisites
Section titled “Prerequisites”- A Forgejo, Gitea, or Codeberg instance (self-hosted or public)
- An email address (for Supabase magic-link sign-in)
- A bot account or PAT with write scope on your forge instance (needed for
the queue engine: it creates
gondolier/*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.
Step 1: Sign in
Section titled “Step 1: Sign in”- Go to gondolier.dev
- Click Sign in → enter your email for a magic link
- Click the magic link in your email to sign in
Your account is created automatically on first sign-in.
Step 2: Connect your forge
Section titled “Step 2: Connect your forge”- In the dashboard, go to Connections → Add connection
- Enter your forge instance URL (e.g.
https://git.example.com) - Enter your bot username (e.g.
mq-bot) - Paste your PAT or token
- Click Add connection — the connection is stored (token encrypted at rest) and verified
Token scopes
Section titled “Token scopes”| 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.
Step 3: Add a repo
Section titled “Step 3: Add a repo”- Go to Repositories → Add repository
- Select an existing connection (or create a new one)
- Enter the repository slug (e.g.
owner/repo) - Configure:
- Base branch — usually
mainormaster - Merge style —
merge,squash, orrebase
- Base branch — usually
- Click Add
After adding, the dashboard shows the provisioning result:
- Webhook —
Ready|Needs admin|Not required(poll mode) - Branch protection —
Not protected|Ready|Needs admin|Needs bot username|Waiting on setup PR|Error
If provisioning fails with Needs admin, the dashboard shows manual setup instructions. Grant your bot repo-admin scope and click Provision to retry.
Enrollment does not change your repository’s merge rules. Provisioning configures the webhook (in
webhookwake mode) and nothing else. Your base branch is untouched until you click Protect base branch, and you can stop Gondolier managing it at any time — the rule stays on your forge for you to remove yourself, so a branch is never silently reopened.Before protecting, make sure the repository has CI that runs on
gondolier/**pushes. The CI gate below is the assisted way to set that up; it is optional if your existing CI already covers those refs.
Step 4: Configure and verify the CI gate
Section titled “Step 4: Configure and verify the CI gate”Each batch is pushed to gondolier/<base>/staging-<timestamp>-<sequence>. Its
Forgejo Actions push run is the gate, so it must match gondolier/**.
On the dashboard’s repository row, choose either Copy CI YAML or Open
setup PR. The setup PR adds a separate
.forgejo/workflows/gondolier-gate.yaml; it never edits an existing workflow,
writes the base branch, or auto-merges.
Its initial workflow is intentionally fail-closed:
name: Gondolier gateon: push: branches: ["gondolier/**"]permissions: {}jobs: gate: runs-on: ubuntu-latest steps: - name: Configure this gate run: | echo "Replace this failing stub with this repository's full test command." exit 1Merge the setup PR, then replace the stub with the repository’s full validation
command (and checkout/setup steps as required). Keep the push trigger and do
not apply paths-ignore: a new staging branch can have an empty changed-file
set, which can suppress the gate entirely. Gondolier leaves its automatic
branch protection in Awaiting CI gate until verification so this setup PR is
not blocked by the required check it creates. Existing repository restrictions
still require an allowed maintainer to merge the setup PR.
Click Verify CI gate after that change. Gondolier creates a one-file commit
on an isolated gondolier/<base>/verify-... ref, deletes the ref, then reports
the Gondolier gate run for that exact commit. No PR is queued or merged. A
verified state requires a successful run; a failing or pending run remains
non-ready.
Do not post a gondolier status from CI: gondolier posts that status on
each PR only after the staged run passes.
Step 5: Provisioning and wake mode
Section titled “Step 5: Provisioning and wake mode”Wake mode
Section titled “Wake mode”Each repo has a wakeup mode that controls how gondolier detects new PRs:
| Mode | How the repository becomes due | Setup requirements |
|---|---|---|
poll (default) |
The reconciliation tick picks it up on a schedule that backs off while it is quiet | None. Works with any token scope. |
webhook |
A forge event marks it due immediately, so the next tick takes it | 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.
How long until my PR is picked up?
Section titled “How long until my PR is picked up?”Worth being exact, because the two modes differ by more than the labels suggest.
Gondolier reconciles on a five-minute tick. Neither mode processes a pull request the instant it becomes ready — what a webhook changes is when a repository becomes due, not how fast a due repository is handled.
| Mode | Typical | Worst case |
|---|---|---|
webhook |
~2.5 minutes | 5 minutes |
poll, active repository |
~2.5 minutes | 5 minutes |
poll, quiet repository |
grows with idleness | 60 minutes |
A poll repository that has seen no queue activity backs off — 5, 10, 20, 40,
then 60 minutes — so a pull request opened on a repository that has been idle
for an hour can wait up to an hour to be noticed. That is the case webhook mode
exists to remove: a forge event resets the schedule to now, so the next tick
takes it regardless of how long the repository has been quiet.
If your repository is busy, the two modes perform identically. If it is bursty — quiet for hours, then several PRs at once — webhook mode is the difference between a two-minute wait and an hour-long one.
Why not dispatch on the webhook itself? Because batching is the point. Waiting for the tick is what lets several ready pull requests land in one CI run instead of several, which is where the cost saving comes from. A queue that reacted instantly to every event would be testing one PR at a time.
Provisioning
Section titled “Provisioning”Provisioning runs in two stages:
- On enrollment — best-effort, never blocks repo addition.
- 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/forgejoforpushandpull_requestevents. - Branch protection — not configured at enrollment. Protecting the base branch changes how every pull request in your repository merges, so Gondolier asks first: the repository shows Not protected with a Protect base branch button. Clicking it adds your status context (default
gondolier) as a required check, and Gondolier keeps it configured from then on. CI-gate verification is optional assistance and is not a prerequisite; the one exception is that while Gondolier’s own CI-gate setup PR is open, protection is deferred (Waiting on setup PR) so that PR is not blocked by the check it exists to add. - Required check — after verification, marks the repo’s status context (default
gondolier) as a required check on the base branch.
Provisioning registers the webhook only in webhook wake mode. CI-gate
bootstrap is a separate explicit action in Step 4:
it can copy a fail-closed workflow or open a normal target-repository setup PR.
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.
Wake mode webhook guidance
Section titled “Wake mode webhook guidance”When using webhook mode:
- The webhook URL is
https://api.gondolier.dev/api/v1/webhooks/forgejo - Required events:
push,pull_request - 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.
Step 6: Queue a PR
Section titled “Step 6: Queue a PR”- Create a PR targeting the base branch
- Request auto-merge (Forgejo: click “Merge when ready”)
- The PR joins the queue automatically
Gondolier will:
- Batch eligible PRs
- Stage them on a
gondolier/<branch>/staging-...branch - Wait for CI
- Bisect on failure
- Auto-merge on success
What happens next?
Section titled “What happens next?”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:
- Discovery — finds PRs with auto-merge scheduled
- Batching — groups them into a rollup (configurable size)
- Staging — creates a staging branch with all PRs cherry-picked
- Gate — waits for CI to pass on the staging branch
- Resolution — bisects on failure, merges on success
Queue order and in-flight batch state persist via a Supabase-backed checkpoint store, so the engine resumes in-flight batches across restarts rather than re-staging.
Dashboard overview
Section titled “Dashboard overview”The dashboard at gondolier.dev/dashboard has two peer sections:
Repositories
Section titled “Repositories”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 - Actions — Reconcile (one-shot), Provision (retry setup), Remove (with confirmation)
Connections
Section titled “Connections”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)
Queue status
Section titled “Queue status”Shows a per-repo health panel: queue name, reconcile state, lease state, and a Reconcile button.
Where to go next
Section titled “Where to go next”- How the queue works — what batching, gating, bisecting, and bouncing actually do.
- Troubleshooting — organised by the symptom you can see in the dashboard.
- Security and data handling — what your token is used for and how it is stored.
- Billing — plans, overage, and what happens if a payment fails.