Skip to content

feat: Add GitLab integration for project-level repository linking#7028

Draft
asaphko wants to merge 2 commits intomainfrom
feature/gitlab-integration
Draft

feat: Add GitLab integration for project-level repository linking#7028
asaphko wants to merge 2 commits intomainfrom
feature/gitlab-integration

Conversation

@asaphko
Copy link
Contributor

@asaphko asaphko commented Mar 24, 2026

Hey team! 👋

So... your PM got hold of Claude Code, wanted to test the Superpowers skill, and thought "how hard can it be to add GitLab support?" Famous last words, I know.

Before you reach for the pitchforks: yes, this is AI-generated code. Yes, your PM directed it. No, I don't expect this to be merge-ready without proper engineering review. Think of this as a very detailed, functional, tested PoC that happens to be written in actual code instead of a Google Doc with screenshots.

I'd genuinely appreciate your review — not just "does it work" but "would you architect it this way." The AI follows patterns well but doesn't have your taste. Tear it apart constructively and let's make it production-worthy together.


Product Summary

What: GitLab integration for Flagsmith — the same thing we have for GitHub, but for GitLab.

Why: Our enterprise customers keep asking for it. Many use self-managed GitLab instances and need the same feature flag ↔ issue/MR linking workflow that GitHub customers enjoy.

How it works (user flow):

  1. Go to Project Settings → Integrations → click Add Integration on GitLab
  2. Enter your GitLab instance URL (defaults to https://gitlab.com), a Group/Project Access Token (api scope, Developer role), and an optional webhook secret
  3. Click Save → select which GitLab project to link → enable tagging if desired
  4. Copy the webhook URL + secret and configure it in your GitLab project/group settings (Issues events + Merge request events)
  5. Now you can link GitLab issues and MRs to feature flags from the Links tab on any feature
  6. When you toggle a flag, Flagsmith posts a comment to the linked GitLab issue/MR showing the current state
  7. When an issue/MR changes state in GitLab (opened, closed, merged), the feature flag gets auto-tagged ("Issue Open", "MR Merged", etc.)

Key design decisions:

  • Project-level (not org-level like GitHub) — because GitLab tokens are typically project-scoped, and it's simpler: no org/project selection needed since you're already inside a project
  • Group/Project Access Tokens (not PATs) — enterprise-friendly, not tied to individual users, survives employee turnover
  • Self-managed support from day one — configurable instance URL per integration
  • No OAuth flow — direct token input, simpler setup, works for self-managed instances without registering an OAuth app

Technical Details for Reviewers

Backend (Django)

New Django app: api/integrations/gitlab/

Module What it does
models.py GitLabConfiguration — ForeignKey to Project (not Organisation), stores instance URL, access token, webhook secret, linked GitLab project ID/name, tagging toggle. Conditional unique constraint respecting soft-delete.
client.py GitLab API v4 client — project listing, issue/MR search, comment posting, label management. All calls use PRIVATE-TOKEN header.
gitlab.py Webhook event handling, feature tagging logic, comment body generation (markdown tables matching GitHub's format), call_gitlab_task for async dispatch.
tasks.py @register_task_handler for async comment posting. Parses GitLab URLs to extract project path + resource IID.
views.py GitLabConfigurationViewSet (nested under projects), function-based views for resource browsing (issues, MRs, projects, members), cleanup issue creation, webhook receiver.
serializers.py Model serialisers (separate create vs read to hide access_token in responses), dataclass serialisers for query params.
helpers.py Webhook validation — simple token comparison (not HMAC like GitHub).
permissions.py Project-level permission check via organisation membership.

Modified files:

File Change
features/feature_external_resources/models.py Added GITLAB_ISSUE/GITLAB_MR to ResourceType. Refactored AFTER_SAVE/BEFORE_DELETE hooks to dispatch by type prefix (GitHub vs GitLab). Supports work_items URL format (GitLab's new issue URL scheme).
features/feature_external_resources/views.py Extended list (live metadata fetch from GitLab API) and create (URL validation, label application) for GitLab resource types.
features/models.py Added GitLab comment posting in Feature.create_github_comment and FeatureSegment.create_github_comment hooks.
features/serializers.py + features/versioning/serializers.py Added call_gitlab_task alongside call_github_task for flag update events.
projects/tags/models.py Added GITLAB to TagType enum.
projects/urls.py Registered GitLab viewset and resource browsing paths.
api/urls/v1.py Webhook URL: gitlab-webhook/<project_pk>/

Webhook URL format: /api/v1/gitlab-webhook/<project_id>/ — project ID in the URL so we can look up the config directly (no iterating over all configs to match the secret).

GitLab URL quirk: GitLab recently changed issue URLs from /-/issues/N to /-/work_items/N. The code handles both formats with (?:issues|work_items) regex patterns.

Frontend (React/TypeScript)

New files:

  • services/useGitlabIntegration.ts — RTK Query CRUD for configuration
  • services/useGitlab.ts — RTK Query for project/issue/MR browsing
  • GitLabSetupPage.tsx — Setup modal with credentials form → repo selection → webhook display
  • GitLabResourcesSelect.tsx — Issue/MR search component for the Links tab

Modified files:

  • IntegrationList.tsx — GitLab uses custom modal (not the standard CreateEditIntegrationModal) because it needs repo selection + webhook display
  • ExternalResourcesLinkTab.tsx — GitHub/GitLab toggle when both are configured
  • ExternalResourcesTable.tsx — Handles GitLab resource types
  • create-feature/index.js — Checks for GitLab integration to show Links tab
  • default-flags.ts — GitLab integration entry with form fields
  • utils.tsxgetIntegrationData() now merges defaults so new integrations appear before the remote flag is updated
  • CreateEditIntegrationModal.tsx — Populates default field values on init (fixes pre-existing bug where defaults showed but weren't submitted)

Tests

  • test_unit_gitlab_client.py — 6 tests for API client functions
  • test_unit_gitlab_gitlab.py — 1 test for webhook tagging
  • test_unit_gitlab_views.py — 14 tests for views (config CRUD, webhook, resource browsing)
  • All 152 related tests pass (GitLab + GitHub + external resources)
  • All 749 features tests pass
  • All 355 integrations tests pass

Migration

Single migration 0001_initial.py — creates GitLabConfiguration table with ForeignKey to Project and conditional unique constraint.


What I know needs more work

  • Test coverage — 100% diff coverage is the policy and we're probably not there yet. The AI wrote the happy paths but edge cases need more love.
  • Type checkingmypy --strict hasn't been run. There are likely # type: ignore comments that need proper typing.
  • Lintingmake lint needs a full run in the proper environment.
  • The getIntegrationData merge in utils.tsx — this is a general improvement (new integrations appear before the remote flag is updated) but might have side effects worth discussing.
  • Cleanup issue creation — implemented on the backend but not wired up in the frontend yet.
  • GitLab SVG icon — references /static/images/integrations/gitlab.svg which doesn't exist yet.
  • Documentation — docs.flagsmith.com needs a GitLab integration page.
  • Flagsmith on Flagsmith — the integration_data flag needs the gitlab entry added for production.

How to test locally

# Backend
cd api
make docker-up
DATABASE_URL="postgresql://postgres:password@localhost:5432/flagsmith" .venv/bin/python manage.py migrate
DATABASE_URL="postgresql://postgres:password@localhost:5432/flagsmith" DJANGO_ALLOWED_HOSTS="*" .venv/bin/python manage.py runserver

# Frontend
cd frontend
npm install
ENV=local npm run dev

# Tests
cd api
DATABASE_URL="postgresql://postgres:password@localhost:5432/flagsmith" .venv/bin/pytest tests/unit/integrations/gitlab/ -v

You'll need a GitLab access token with api scope (Developer role) to test the full flow. For webhooks, use ngrok: ngrok http 8000.


Built with Claude Code by a PM who promises to buy the reviewing engineers coffee. Or beer. Probably beer. 🍺

Screenshot 2026-03-24 at 13 18 16 Screenshot 2026-03-24 at 13 17 56 Screenshot 2026-03-24 at 13 17 25 Screenshot 2026-03-24 at 13 17 04 Screenshot 2026-03-24 at 13 16 50

@vercel
Copy link

vercel bot commented Mar 24, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
flagsmith-frontend-preview Ready Ready Preview, Comment Mar 24, 2026 5:32pm
flagsmith-frontend-staging Ready Ready Preview, Comment Mar 24, 2026 5:32pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Ignored Ignored Preview Mar 24, 2026 5:32pm

Request Review

@github-actions github-actions bot added front-end Issue related to the React Front End Dashboard api Issue related to the REST API feature New feature or request labels Mar 24, 2026
@asaphko asaphko force-pushed the feature/gitlab-integration branch from 99872ab to 2185d42 Compare March 24, 2026 13:32
@github-actions github-actions bot added feature New feature or request and removed feature New feature or request labels Mar 24, 2026
@asaphko asaphko force-pushed the feature/gitlab-integration branch from 207da17 to b27e98f Compare March 24, 2026 13:40
@github-actions github-actions bot added feature New feature or request and removed feature New feature or request labels Mar 24, 2026
@asaphko asaphko force-pushed the feature/gitlab-integration branch from 410a6dd to 77ec317 Compare March 24, 2026 14:36
@github-actions github-actions bot added feature New feature or request and removed feature New feature or request labels Mar 24, 2026
@codecov
Copy link

codecov bot commented Mar 24, 2026

Codecov Report

❌ Patch coverage is 99.57653% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 98.29%. Comparing base (ffd2a11) to head (ec1e94f).
⚠️ Report is 6 commits behind head on main.

Files with missing lines Patch % Lines
api/integrations/gitlab/views.py 97.64% 4 Missing ⚠️
api/integrations/gitlab/tasks.py 97.59% 2 Missing ⚠️
api/integrations/gitlab/gitlab.py 99.10% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7028      +/-   ##
==========================================
- Coverage   98.32%   98.29%   -0.03%     
==========================================
  Files        1335     1356      +21     
  Lines       49850    51492    +1642     
==========================================
+ Hits        49013    50615    +1602     
- Misses        837      877      +40     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@asaphko asaphko force-pushed the feature/gitlab-integration branch from b4874c1 to f3e5794 Compare March 24, 2026 15:35
@github-actions github-actions bot added feature New feature or request and removed feature New feature or request labels Mar 24, 2026
@asaphko asaphko force-pushed the feature/gitlab-integration branch from 40afbbc to 555bae5 Compare March 24, 2026 16:07
@github-actions github-actions bot added feature New feature or request and removed feature New feature or request labels Mar 24, 2026
@asaphko asaphko force-pushed the feature/gitlab-integration branch from 2f9a2dd to 181fda0 Compare March 24, 2026 16:15
@github-actions github-actions bot added feature New feature or request and removed feature New feature or request labels Mar 24, 2026
@asaphko asaphko force-pushed the feature/gitlab-integration branch from af2677d to 619885f Compare March 24, 2026 17:21
@github-actions github-actions bot added feature New feature or request and removed feature New feature or request labels Mar 24, 2026
@asaphko asaphko force-pushed the feature/gitlab-integration branch from 199d6d5 to 4cfe5eb Compare March 24, 2026 17:23
@github-actions github-actions bot added feature New feature or request and removed feature New feature or request labels Mar 24, 2026
Add GitLab integration to Flagsmith, allowing users to link GitLab
issues and merge requests to feature flags. Supports both GitLab.com
and self-managed instances via Group/Project Access Tokens.

## Backend
- New Django app `integrations/gitlab/` with models, views, client,
  webhook handling, async tasks, and serialisers
- `GitLabConfiguration` model (per-project) stores instance URL,
  access token, webhook secret, and linked GitLab project
- Webhook receiver at `/api/v1/gitlab-webhook/<project_id>/` handles
  merge request and issue events for automatic feature tagging
- Comment posting to GitLab issues/MRs when feature flags change
- Extend `FeatureExternalResource` with GITLAB_ISSUE and GITLAB_MR
  resource types, with lifecycle hooks dispatching to GitHub or GitLab
- Add `GITLAB` to `TagType` enum for feature tagging

## Frontend
- RTK Query services for GitLab integration and resource browsing
- GitLabSetupPage component with credentials form, repo selection,
  tagging toggle, and webhook URL display with copy-to-clipboard
- GitLabResourcesSelect for linking issues/MRs to feature flags
- Extend IntegrationList, ExternalResourcesLinkTab, and
  ExternalResourcesTable to support GitLab alongside GitHub

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@asaphko asaphko force-pushed the feature/gitlab-integration branch from 7c60f2e to b2edbfd Compare March 24, 2026 17:29
@github-actions github-actions bot added feature New feature or request and removed feature New feature or request labels Mar 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api Issue related to the REST API feature New feature or request front-end Issue related to the React Front End Dashboard

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant