Skip to Content

GitLab Integration

Pilot integrates with GitLab to receive issues and create merge requests. It supports both GitLab.com and self-hosted GitLab instances.

Setup

1. Create a GitLab Token

  1. Go to GitLabPreferencesAccess Tokens
  2. Create a Personal Access Token or Project Access Token with scopes:
    • api — full API access
    • read_repository / write_repository — for git operations

For self-hosted GitLab, use a Project Access Token scoped to the target project for better security isolation.

2. Configure Pilot

# ~/.pilot/config.yaml gitlab: enabled: true token: ${GITLAB_TOKEN} base_url: https://gitlab.com project: my-group/my-project pilot_label: pilot polling: enabled: true interval: 30s label: pilot

3. Create the pilot Label

In your GitLab project, go to IssuesLabels and create a pilot label.

Configuration Reference

FieldTypeDefaultDescription
enabledboolfalseEnable the GitLab adapter
tokenstringrequiredPersonal or Project Access Token
base_urlstring"https://gitlab.com"GitLab instance URL
projectstringrequiredProject path (namespace/project)
webhook_secretstringToken for webhook verification
pilot_labelstring"pilot"Label that triggers Pilot
polling.enabledboolfalseEnable polling for new issues
polling.intervalduration30sPolling interval
polling.labelstring"pilot"Label to filter issues by
stale_label_cleanup.enabledbooltrueClean up orphaned pilot-in-progress labels
stale_label_cleanup.intervalduration30mHow often to check for stale labels
stale_label_cleanup.thresholdduration1hAge after which a label is considered stale

Polling Mode

When polling is enabled, Pilot periodically lists open issues with the pilot label, sorted by creation date (oldest first). Issues with pilot-in-progress or pilot-done labels are skipped.

Sequential Execution

By default, Pilot processes one issue at a time in sequential mode:

  1. Find the oldest unprocessed issue with the pilot label
  2. Execute the implementation
  3. Create a merge request
  4. Wait for the MR to be merged
  5. Move to the next issue

If the MR has conflicts or times out, Pilot pauses for 5 minutes before retrying.

Webhook Mode

For real-time issue detection, configure a GitLab webhook:

  1. Go to your project → SettingsWebhooks
  2. Set the URL to https://your-pilot.example.com/webhooks/gitlab
  3. Set the Secret token to match your webhook_secret config
  4. Enable Issues events

Signature Validation

GitLab webhooks use a simple token comparison via the X-Gitlab-Token header. This differs from GitHub’s HMAC-SHA256 signature approach.

gitlab: webhook_secret: ${GITLAB_WEBHOOK_SECRET}

If webhook_secret is empty, all incoming webhooks are accepted (development mode only).

Supported Events

EventTriggerBehavior
Issue openedNew issue with pilot labelPilot processes the issue
Issue updatedPilot label added to existing issuePilot processes the issue

Merge Request Management

When Pilot completes work on an issue, it creates a merge request in your GitLab project.

MR Options

OptionDefaultDescription
Remove source branchNoDelete branch after merge
Squash commitsNoSquash into single commit on merge

Merge Waiting

In sequential mode, Pilot waits for the MR to be merged before processing the next issue. It polls MR status every 30 seconds with a 1-hour timeout.

MR StatePilot Behavior
MergedMarks issue complete, processes next
ClosedDoes not mark as processed (may need re-execution)
ConflictsPauses 5 minutes, retries
TimeoutPauses 5 minutes, retries

CI Status Tracking

Pilot monitors GitLab pipeline status on merge requests:

Pipeline StatusDescription
pendingPipeline queued
runningPipeline executing
successAll jobs passed
failedOne or more jobs failed
canceledPipeline was canceled
skippedPipeline was skipped
manualWaiting for manual trigger

Stale Label Cleanup

Pilot automatically removes orphaned pilot-in-progress labels from issues that are no longer being actively processed. This prevents issues from getting stuck if Pilot restarts during execution.

The cleaner runs every 30 minutes (configurable) and removes the label if:

  • No active Pilot execution exists for the issue
  • The label was last updated more than 1 hour ago (configurable)

A comment is posted to the issue explaining the cleanup.

Labels

LabelPurpose
pilotTriggers Pilot to pick up the issue
pilot-in-progressApplied while Pilot is working
pilot-doneApplied after successful completion
pilot-failedApplied if execution fails

Differences from GitHub

AspectGitLabGitHub
Auth headerPRIVATE-TOKENAuthorization: Bearer
Webhook securitySimple token (X-Gitlab-Token)HMAC-SHA256 (X-Hub-Signature-256)
Issue statesopened / closedopen / closed
PR terminologyMerge Request (MR)Pull Request (PR)
Label operationsFetch → merge → PUT (full array)Direct add/remove endpoints
Priority labelspriority::high (scoped)priority:high
CI modelSingle pipeline with statusCommit statuses + check runs
Merge strategiessquash boolean onlymerge / squash / rebase
Task ID formatGL-{iid}GH-{number}