Claude
Skills
Sign in
Back

graphite-setup

Included with Lifetime
$97 forever

Configure a GitHub repository for Graphite — branch protection, merge queue, CI triggers, and stack-aware CI optimizations. Use when the user is onboarding a repo to Graphite, mentions Graphite branch protection / required checks / signed commits / merge queue, sees CI failing on `graphite-base/*` branches, asks about merge-queue choice (Graphite vs GitHub vs external), or wants to reduce CI cost for stacked PRs (CI Optimizations, stack-aware CI, `needs.optimize_ci.outputs.skip`). Triggers on `.github/workflows/*.yml` changes for repos using Graphite, the phrases "stack CI", "stacking and CI", "graphite-base", and any branch-protection or merge-queue discussion in a Graphite repo.

Cloud & DevOps

What this skill does


# Graphite — Repository Setup & CI Configuration

This skill is the counterpart to the `graphite` skill (CLI workflow). It covers the one-time and ongoing **repository / GitHub / CI** configuration that lets `gt` stacks merge cleanly. If the user is driving `gt` locally, use the `graphite` skill instead.

Source docs (cite when proposing changes):
- [GitHub configuration guidelines](https://graphite.com/docs/github-configuration-guidelines)
- [Setup: merge queue integration](https://graphite.com/docs/setup-merge-queue-integration)
- [Setup: recommended CI settings](https://graphite.com/docs/setup-recommended-ci-settings)
- [Stacking and CI](https://graphite.com/docs/stacking-and-ci)

## Onboarding a repo — do this in order

Work top-down. Each step has a checkpoint; if it fails, fix that step before moving on — a later step won't compensate for an earlier misconfiguration.

1. **Repo settings** — disable the single-push branch limit, enable auto-delete head branches ([GitHub repository settings](#github-repository-settings)).
   - ✅ Checkpoint: `gt submit --stack` on a 2-branch test stack pushes both branches without a "too many branches in one push" error.
2. **Branch protection** — turn off the four Graphite-breaking settings; keep the recommended safe ones (tables below).
   - ✅ Checkpoint: open a test PR, approve it, then push an amend — the approval is **not** dismissed and the PR stays mergeable.
3. **CI triggers** — add `branches-ignore: "**/graphite-base/**"` and ensure CI runs on every stacked PR, not just trunk ([CI configuration](#ci-configuration)).
   - ✅ Checkpoint: push a 2-PR stack; both PRs get CI runs, and no job fails with "branch not found" on a `graphite-base/*` ref.
4. **Merge queue** — pick exactly one mode ([Merge queue: pick one](#merge-queue-pick-one)); skip if you aren't using a queue.
   - ✅ Checkpoint: only one queue is active — if you chose Graphite's, GitHub's native queue is off in branch protection.
5. **(Optional) CI Optimizations** — only for teams with tall stacks and ≥~10 active stackers ([CI Optimizations](#ci-optimizations-stack-aware-skipping)).
   - ✅ Checkpoint: a known-skippable intermediate PR shows its CI skipped, while the base and top PRs still run.

## When to reach for this skill

- The user just installed Graphite on a new repo and asks "what do I need to configure?"
- A stack failed to push or merge with branch-protection / required-check errors.
- A CI job is failing on a branch named `graphite-base/<something>` (often "branch not found" right after a merge).
- The user is choosing between GitHub's native merge queue, Graphite's merge queue, or an external one.
- The user wants to cut CI cost on tall stacks (CI Optimizations / stack-aware skipping).
- The user wants signed commits, IP allowlisting, or enterprise GitHub App access for Graphite.

## GitHub repository settings

### Critical (Graphite won't work correctly without these)

- **Allow many branches per push** — disable GitHub's "limit how many branches can be updated in a single push" restriction. `gt submit --stack` pushes every branch in the stack atomically; the cap breaks that.
- **Automatically delete head branches** — enable. When a parent PR merges, downstack PRs need their base re-pointed; auto-delete avoids stale base branches blocking the rebase.

### Branch protection — must be off

These look helpful but break Graphite's automatic rebases:

| Setting | Required state | Why |
|---|---|---|
| Dismiss stale approvals on new push | **Disabled** | Graphite rebases during merge — every rebase counts as a new push and would dismiss approvals. (Graphite ships an open-source GitHub Action as an alternative if your org needs dismissal behavior.) |
| Require approval of the most recent push | **Disabled** | Graphite re-targets the base branch before merge; that re-targeting is a reviewable push and blocks the merge. |
| GitHub native merge queue | **Disabled** | Use Graphite's merge queue (or none) — GitHub's queue doesn't understand stacks and can merge out of order. |
| Deployment checks as required status | **Disabled** | Not supported by Graphite today. |
| Signed commits | **Off, unless** every engineer has uploaded a signing key in Graphite | Otherwise Graphite's server-side rebase will produce unsigned commits and fail the check. |

### Branch protection — recommended

Safe defaults that don't conflict with Graphite:

- Require PRs before merging to trunk.
- Require **at least one approval**.
- Require **conversation resolution** before merging.
- Required status checks for the critical CI jobs (see CI section — be careful which jobs you mark "required" once you turn on CI Optimizations).
- **Linear history** — keep on; matches the stack model and makes bisect/blame readable.
- **Allow administrators to bypass** — keep on, for incident response.

## Merge queue: pick one

Graphite supports three modes. The right answer depends on org constraints, not preference.

| Mode | When to pick it | What to configure |
|---|---|---|
| No merge queue | Small team, low merge contention, no required checks that depend on a queued state | Nothing extra — `gt submit --merge` / "Merge stack" in Graphite UI just merges directly. |
| Graphite merge queue | You want stack-aware batching, parallel CI, and ordered merges | Enable in Graphite settings; disable GitHub's native queue in branch protection. |
| External / non-Graphite merge queue | Org standardizes on a third-party queue (e.g. mergify, kodiak, custom) | Per-repo "External Merge Queue Integration (Beta)" wiring so Graphite knows who to hand the PR off to. |

Do not enable both Graphite's queue and GitHub's native queue — they will fight over who owns the merge.

Source: [setup-merge-queue-integration](https://graphite.com/docs/setup-merge-queue-integration).

## CI configuration

### Ignore `graphite-base/*` branches

Graphite materializes temporary branches under `graphite-base/<something>` during rebase/merge. They get deleted seconds later. CI that targets them will fail with "branch not found" mid-run.

GitHub Actions:

```yaml
on:
  pull_request:
    types: [opened, reopened, synchronize]
    branches-ignore:
      - "**/graphite-base/**"
```

Avoid `pull_request: types: [edited]` — it fires every time a base branch is re-pointed, which Graphite does often.

### Run CI on the whole stack, not just trunk

Graphite gates merge on the required checks for the PR's **target branch** (usually `main`). If those checks only run on `pull_request` against `main`, the upstack PRs won't have results until their parent merges — meaning a tall stack merges one PR at a time, with full CI waits between each.

Configure workflows to run on any branch except `graphite-base/*`. The exception above (`branches-ignore`) already handles this for `pull_request`; mirror it for `push` triggers if you have them.

Source: [setup-recommended-ci-settings](https://graphite.com/docs/setup-recommended-ci-settings).

## CI Optimizations (stack-aware skipping)

For repos with tall stacks, Graphite can skip CI on intermediate PRs and only run it on a few branches per stack. Per-repo config:

- **Number of PRs at the base of the stack** that should run CI (e.g. 1 or 2).
- Whether to **also run on the top of the stack**.

Mechanism: a wrapper job calls Graphite's API and emits a boolean. Dependent jobs gate on it.

**GitHub Actions sketch:**

```yaml
jobs:
  optimize_ci:
    runs-on: ubuntu-latest
    outputs:
      skip: ${{ steps.check.outputs.skip }}
    steps:
      - id: check
        run: |
          # Set steps.check.outputs.skip from Graphite's CI-optimization endpoint.
          # Prefer Graphite's official CI-optimization Action over a hand-rolled
          # API call — see the stacking-and-ci doc (linked above) for the current
          # action name, its inputs, and the exact output field to read.
          ...

  test:
    needs: optimize_ci
    if: needs.optimize_ci.outputs.skip != 'true'
    runs-on: ubuntu

Related in Cloud & DevOps