feat(gitlab): Phase 1 GitLab support via CI/CD Component#93
Merged
Conversation
Adds a minimal gitlab/templates/review.yml job that prints a hello-world message. Used to verify that a GitLab CI pipeline can pull the template over HTTPS from raw.githubusercontent.com before we layer in the Docker image and real review entrypoints. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Pure-addition first slice of GitLab support. Mirrors the shape of src/github/ so subsequent entrypoints can swap adapter by PLATFORM env. - src/gitlab/context.ts parses CI_* env vars into a normalized ParsedGitlabContext with MR + commit + user + inputs - src/gitlab/token.ts reads GITLAB_TOKEN with OVERRIDE/CI_JOB_TOKEN fallbacks; throws a clear error when missing - src/gitlab/api/client.ts is a thin fetch wrapper around GitLab v4 exposing getMr/getMrChanges/listNotes/createNote/updateNote/ createDiscussionOnDiff/updateMrDescription - src/gitlab/types.ts defines GitlabMr, GitlabNote, GitlabDiscussion, GitlabPosition - 16 new unit tests; full existing suite (381 -> 397) still passes No GitHub code paths touched. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
src/mcp/gitlab-mr-server.ts mirrors src/mcp/github-pr-server.ts in shape so the review prompt can stay platform-agnostic at the tool layer. Tools registered: - get_mr / get_mr_changes / list_mr_notes - create_mr_note / update_mr_note (sticky tracking comment lifecycle) - update_mr_description (for @droid fill) - submit_review: posts an optional summary note plus N inline discussions anchored to diff positions; per-comment errors are collected so one bad position doesn't abort the batch. Position objects are built from the MR's diff_refs (base/head/start SHA) and switch new_line vs old_line based on RIGHT vs LEFT side, matching the GitHub PR review tool's contract. 5 new unit tests cover summary, inline anchoring, LEFT-side mapping, and partial-failure batching. Full suite: 402/402. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
…y-note logic Implements the sticky tracking note lifecycle for GitLab MR pipelines: prepare creates (or reuses) the running-state note before droid exec runs; update-comment-link rewrites it with success/failure + pipeline links after droid exec completes. - src/gitlab/operations/tracking-note.ts builds the note body with a hidden <!-- droid-tracking-note --> marker so retries find and update the same note instead of creating duplicates. Renders pipeline/job links, security badge (when automatic_security_review is on), and an error-details <details> block on failure. - src/entrypoints/gitlab-prepare.ts parses CI env, gates on merge_request_event + automatic_review, writes a JSON state file (DROID_STATE_FILE) for downstream steps. - src/entrypoints/gitlab-update-comment-link.ts reads the state file and PUTs the final body. Skips cleanly when no review ran. 7 new tracking-note tests; full suite 402 -> 409. Also tightened two gitlab-mr-server tests to satisfy noUncheckedIndexedAccess. Cross-SCM include:remote was validated end-to-end against gitlab.com pipeline #2568334623 (passed) before this commit. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Replaces the hello-world include-test template with a real droid-review job. No Docker image dependency for v1; instead the job: 1. Uses the public oven/bun:1.2.11 image (Bun preinstalled) 2. apt-get installs git/curl/ca-certificates on top 3. Shallow-clones Factory-AI/droid-action at $DROID_ACTION_REF 4. bun install --frozen-lockfile 5. Runs src/entrypoints/gitlab-prepare.ts (creates sticky tracking note) 6. droid exec placeholder (real prompt + MCP wiring next commit) 7. after_script always runs src/entrypoints/gitlab-update-comment-link.ts so failures still rewrite the note to the failure state Template uses GitLab's spec.inputs so it works equally well via `include: component:` (post-Catalog publish) and `include: remote:` (today). Inputs: automatic_review, review_depth, review_model, reasoning_effort, droid_action_repo, droid_action_ref, stage. Required CI variables on the consumer side: FACTORY_API_KEY, GITLAB_TOKEN. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
The template now installs the Droid CLI, registers the gitlab-mr MCP server with the runtime CI env, and runs `droid exec` against a review prompt that gitlab-prepare writes to /tmp/droid-prompts/droid-prompt.txt. - src/gitlab/review-prompt.ts: minimal v1 review prompt builder embedding the MR diff and instructions to call submit_review with a single batched set of inline comments (max 8). Returns LGTM body when no issues found. - src/entrypoints/gitlab-prepare.ts: after creating the sticky note, fetches MR + diff via the GitLab API and writes the prompt file; exposes promptPath on the state JSON. - gitlab/templates/review.yml: * Installs Droid CLI via curl https://app.factory.ai/cli | sh * Skips droid exec if prepare set shouldRunReview=false * Registers MCP server: droid mcp add gitlab_mr <bun run server> --env ... * Runs: droid exec -f $DROID_PROMPT_FILE --output-format stream-json --skip-permissions-unsafe (plus optional --model/--reasoning-effort) * after_script reads /tmp/droid-error.txt for failure details - 3 new prompt-builder tests; suite at 412 passing. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Previously, review_depth was a declared spec.input that was parsed and
threaded through gitlab-prepare but never consumed by the prompt
builder or the template -- so customers passing review_depth: shallow
silently still got Droid's default model.
This wires it end-to-end:
- gitlab-prepare now calls resolveReviewConfig({reviewModel,
reasoningEffort, reviewDepth}) from src/utils/review-depth.ts (which
already had the preset table: shallow -> kimi-k2-0711, deep -> gpt-5.2
+ high reasoning), reusing the same logic the GitHub flow uses.
- Explicit review_model / reasoning_effort still beat the depth preset
(resolveReviewConfig handles priority).
- Resolved values are written to /tmp/droid-prompts/resolved-env.sh as
shell exports (RESOLVED_MODEL / RESOLVED_REASONING_EFFORT), plus
echoed into the state.json for visibility.
- Template sources the shim before constructing droid exec args and
uses the RESOLVED_* values for --model / --reasoning-effort.
Adds 6 unit tests covering: default deep preset, shallow preset,
explicit model override, explicit effort override, both overrides
simultaneously, unknown depth fallback. Suite at 418 passing.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Replaces the v1 single-pass bespoke prompt with the same two-pass flow the GitHub Action uses: Pass 1 generates review_candidates.json without posting; Pass 2 validates each candidate, writes review_validated.json, and submits approved findings in a single batched call. The /review skill (loaded by Droid at runtime) drives both passes; the prompts here are the runtime harness that selects which pass + which tools. Why two droid exec calls rather than one: 1. Tool gating — Pass 1 has NO access to gitlab_mr___submit_review so the model can't shortcut by posting raw candidates. --enabled-tools is fixed at process start, so a single exec can't switch mid-run. 2. Fresh-eyes context — Pass 2 re-reads the diff without memory of why each candidate was generated, dropping ~30-60% false positives. 3. Hard output checkpoint on disk between passes (resumable, debuggable). 4. Clean failure semantics — half-baked Pass 1 won't pollute Pass 2. New files: * src/gitlab/data/review-artifacts.ts — fetch + write mr.diff, existing_comments.json, mr_description.txt (mirror of GitHub's precomputed PR artifacts). * src/gitlab/prompts/types.ts — shared prompt-context shape. * src/gitlab/prompts/candidates.ts — Pass 1 prompt, ported from GitHub's review-candidates-prompt.ts with MR/project terminology. * src/gitlab/prompts/validator.ts — Pass 2 prompt, ported from GitHub's review-validator-prompt.ts; uses gitlab_mr___submit_review and the new gitlab_mr___update_tracking_note tool. * src/entrypoints/gitlab-prepare-validator.ts — overwrites the prompt file with Pass 2 between the two droid exec calls. * test/gitlab/prompts.test.ts + test/gitlab/review-artifacts.test.ts — 14 new tests covering the two prompts and artifact computation. MCP additions: * src/mcp/gitlab-mr-server.ts — new update_tracking_note tool that reads DROID_MR_IID + DROID_TRACKING_NOTE_ID from env, symmetric with GitHub's github_comment___update_droid_comment. Template changes (gitlab/templates/review.yml): * Sources resolved-env.sh once up front (now includes DROID_MR_IID + DROID_TRACKING_NOTE_ID). * Registers the MCP server with those env vars exposed. * Pass 1 droid exec: --enabled-tools excludes submit_review. * Runs gitlab-prepare-validator between the two execs. * Pass 2 droid exec: --enabled-tools includes gitlab_mr___submit_review and gitlab_mr___update_tracking_note. * Artifacts archive bumped to include review_candidates.json, review_validated.json, droid-prompt.txt for debugging. Removed: * src/gitlab/review-prompt.ts (v1 single-pass bespoke prompt). * test/gitlab/review-prompt.test.ts. Refactoring src/gitlab/prompts/ + src/create-prompt/ into a shared src/core/review/ tree is queued as a follow-up PR. All 432 tests pass; tsc + prettier clean. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Adds the same `settings` input the GitHub action exposes: * spec.input on the CI/CD Component (JSON string OR path to JSON file). * Plumbed via DROID_SETTINGS env var to gitlab-prepare. * gitlab-prepare reuses base-action/src/setup-droid-settings.ts (zero GitHub deps, fully portable) to write ~/.factory/droid/settings.json before either droid exec call. Always sets enableAllProjectMcpServers=true to match the GitHub flow. * context.inputs.settings surfaces the raw value. * 2 new context tests; 434 tests pass. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
…etry, draft skip, stderr capture - 1.6b Copy bundled .factory/droids from droid-action checkout into runner ~/.factory/droids before droid exec, mirroring the GitHub action's Setup Custom Droids step. - 1.6c Stage debug artifacts (/tmp/droid-prompts/*, droid-error.txt) into .droid-debug/ inside CI_PROJECT_DIR in after_script so GitLab can upload them on failure (GitLab artifacts cannot reach outside CI_PROJECT_DIR). - 1.6d Capture droid exec stream-json output to per-pass JSONL log files via tee + pipefail; parse session_id / numTurns / durationMs (+ legacy cost_usd) from the last completion event of each pass; render a <sub> summary line (44 turns • 11m 40s • $0.42) and a collapsible session-IDs block in the sticky tracking note. - C7 Skip Draft: / WIP: MRs at the rules: level (GitLab-native equivalent of GitHub's draft == false workflow if:). - C9 On droid exec failure, tail 60 lines of the per-pass log into /tmp/droid-error.txt so the existing error-details block in the sticky note surfaces real failure context instead of a generic message. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Adds the include_suggestions spec input to the GitLab review template. Threading was already in place: gitlab-prepare reads the INCLUDE_SUGGESTIONS env var, stores it in the on-disk state, gitlab-prepare-validator restores it, and both candidate + validator prompts already consume includeSuggestions to gate suggestion-block guidance. This commit just exposes the toggle as a customer-facing input. Mirrors the GitHub action's include_suggestions input. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Adds a cache: block keyed on droid_action_ref so bun's package cache survives across MR pipelines. BUN_INSTALL_CACHE_DIR is pinned to CI_PROJECT_DIR/.bun-cache because GitLab's cache mechanism can only persist paths inside the project directory. policy: pull-push lets every job benefit from prior downloads and contribute newly-fetched packages back to the cache. Mirrors the actions/cache pattern in the GitHub action. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Wraps every GitlabClient.request call with retry-on-transient-failure logic, mirroring the implicit retry behaviour the GitHub action gets from Octokit. Retries are limited to a configurable maxRetries (default 5) for: 408, 429, 500, 502, 503, 504, and raw fetch network errors. On 429 the client honours the Retry-After header when present (seconds or HTTP-date), and otherwise uses exponential backoff with jitter clamped to maxDelayMs. Non-retryable 4xx errors (401, 403, 404, etc.) surface immediately as GitlabApiError. The retry knobs are exposed via a third constructor argument so tests can use sub-millisecond delays without needing fake timers. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Adds a private paginate<T>() helper that follows GitLab's standard pagination either via the X-Next-Page header (newer GitLab) or Link rel="next" (older GitLab + GitLab.com responses) with per_page=100 to minimise round-trips. listNotes now uses it and a new listDiscussions method is exposed for use cases that need to inspect existing diff discussions. Mirrors Octokit's implicit paginate-everything behaviour that the GitHub action gets for free. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
This reverts commit 7c721d1.
…t (C1)" This reverts commit d70dbd7.
This reverts commit 0d6c73b.
Removes two GitLab-only behaviours that don't exist in the GitHub action: - Draft/WIP `rules: when: never` block. GitHub leaves draft handling to the user's workflow `if: ... draft == false` condition and doesn't bake it into the action. Customers who want to skip drafts can add the same condition to their own .gitlab-ci.yml. - Stderr tail-60 capture into droid-error.txt. GitHub uses core.setFailed(error.message) which surfaces in the Actions run summary, not in the PR comment body — the comment just shows an actionFailed flag. Revert to the plain "droid exec pass N failed" message for parity. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Wires the automatic_security_review toggle through the GitLab CI/CD Component. When set to "true", the security-reviewer subagent already bundled in .factory/droids/security-reviewer.md is spawned in parallel with the code-review subagents during Pass 1 (the conditional block in src/gitlab/prompts/candidates.ts already handles this via the securityReviewEnabled flag). Security findings are prefixed with [security] and flow through the same Pass-2 validator path as code-review findings, ultimately posted via a single batched submit_review call. No plugin install is required: the security-review skill that the subagent invokes as its first action is built into the Droid CLI binary. Mirrors the GitHub action's automatic_security_review input for the per-MR flow only; the scheduled full-repo scan (which additionally uses threat-model-generation / commit-security-scan / vulnerability-validation skills from the security-engineer plugin) is a separate feature. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Matches GitHub action's input surface for security_block_on_critical (default "true") and security_block_on_high (default "false"). Like the GitHub action, the inputs are parsed into context but not currently consumed by production code — they exist for surface-level parity and forward compatibility when blocking logic lands. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
… Component Documents the manual installation flow for the new GitLab CI/CD Component (`gitlab/templates/review.yml`): prerequisites, full inputs table, what the pipeline produces, how the two-pass review works, what is intentionally not yet supported (comment triggers, fill mode, scheduled scans), and troubleshooting steps. README now has a short GitLab section that points to the full guide. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
9ef6f30 to
6f05311
Compare
Adds two consumer-facing sample files plus a README so users have a
canonical reference for what a Component-consuming .gitlab-ci.yml looks
like:
* gitlab/examples/.gitlab-ci.minimal.yml — shortest possible, every
default accepted, only the two required CI/CD variables wired.
* gitlab/examples/.gitlab-ci.example.yml — annotated, every input
spelled out with safe-default guidance, plus an optional
@droid fill block (commented out) showing how to add fill.
* gitlab/examples/README.md — table mapping each file to its use case
and the variable-setup story.
Also updates docs/gitlab-setup.md:
* Points readers at gitlab/examples/ instead of just inlining the
snippet, so customers can clone the project, copy the file, done.
* Drops the stale 'service account provisioning' reference now that
the install-code-review skill no longer provisions SAs.
* Tightens the GITLAB_TOKEN row to make the poster-identity story
explicit: the token owner IS the poster, no API impersonation.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Contributor
|
Droid finished @factory-nizar's task —— View job |
Customer-facing surface cleanup before GA:
* gitlab/templates/review.yml: change droid_action_ref default from
"dev" to "main" so customers who don't set it track stable.
Description annotated 'Internal: most users leave at the default'.
* docs/gitlab-setup.md: drop droid_action_ref, droid_action_repo,
stage from the Inputs table — they're for self-hosted GitLab
mirrors / advanced overrides, not standard customer config.
* docs/gitlab-setup.md: drop everything from 'How it works' onward
(How it works, What's not yet supported, Troubleshooting,
Self-hosted GitLab). Those belong in deeper docs / runbooks; the
setup page should be exactly setup.
* docs/gitlab-setup.md: drop the 'pin to a release tag (e.g. v1)'
advice — droid-action doesn't tag yet, and the @main URL pin is
the canonical pattern.
* gitlab/examples/.gitlab-ci.example.yml: drop droid_action_ref from
the inputs block + drop the same line from the optional fill
snippet. Update the comment to just explain the @main pin.
* gitlab/examples/README.md: drop the 'custom stage' reference now
that stage isn't documented as a user-facing knob.
The hidden inputs still exist in the template with sensible defaults,
so air-gapped customers mirroring droid-action can still override
droid_action_repo or pin droid_action_ref to a private SHA — they just
aren't part of the documented surface.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Customer-facing surface should describe what is supported, not what isn't. Caveats belong in deeper docs / runbooks if anywhere, not in the README quick-start. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
…le pattern Component template renamed from gitlab/templates/review.yml to gitlab/templates/droid-review.yml. Customer drops a self-contained factory/droid-review.yml in their project and adds a single `include: - local:` line to their .gitlab-ci.yml, mirroring the GitHub action's `.github/workflows/droid-review.yml` model. Examples restructured to reflect the two-file layout. Docs + README snippets updated accordingly. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Contributor
|
Droid finished @factory-nizar's task —— View job Validated 7 high-confidence findings. Overall the GitLab CI/CD Component approach is solid, but there are a few correctness and security footguns that can break consumer pipelines (top-level |
…compatibility GitLab CI/CD Catalog requires components to live at top-level templates/. Move gitlab/templates/droid-review.yml to templates/droid-review.yml so the repo is ready for Catalog publish (gitlab.com/factory-ai/droid-action) without future renames. Add templates/README.md explaining the directory ownership (mandated by Catalog, parallel to action.yml + .github/workflows/ for GitHub) and a headline comment in droid-review.yml. Update all existing include URLs (README, docs, examples) to the new path. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Switch the customer-facing include form from a raw GitHub URL to GitLab's native include: project: form pointing at the gitlab.com pull-mirror of this repo. Customers no longer need github.com egress to fetch the template — gitlab.com is sufficient. Also flip the runtime droid_action_repo default from github.com/Factory-AI/droid-action.git to gitlab.com/factory-components/droid-action.git so the at-job clone of the runtime source also goes through gitlab.com. Customers behind a firewall that only permits gitlab.com + app.factory.ai can now run the full flow. Updated: - README.md GitLab quick-start snippet (include: project: form) - docs/gitlab-setup.md Step 2 snippet - gitlab/examples/factory/droid-review.yml - templates/README.md — documents include: project: (default), future include: component: form once Catalog-tagged, and a raw GitHub URL fallback for projects that can't reach gitlab.com - templates/droid-review.yml headline comment + droid_action_repo default Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Contributor
|
Droid finished @factory-nizar's task —— View job |
jonathan-factory
previously approved these changes
Jun 3, 2026
- templates/droid-review.yml: remove top-level `stages:` block so the Component doesn't leak its stage list into the consuming project. Job-level `stage: $[[ inputs.stage ]]` is unchanged; consumers add the stage to their own `stages:` list (or omit it for the default). - templates/droid-review.yml: tighten droid_action_ref docstring to "tag/branch" since the clone uses `git clone --branch` (SHAs would silently fail). - src/gitlab/token.ts: drop CI_JOB_TOKEN fallback. It was always set in CI so the MissingGitlabTokenError never fired, producing confusing 401s on first API call instead of a clear "set GITLAB_TOKEN" message. CI_JOB_TOKEN also lacks scopes for notes/discussions. - src/mcp/gitlab-mr-server.ts: require a line anchor on ReviewComment (line for RIGHT, old_line for LEFT) via .refine(); GitLab rejects unanchored diff discussions. - src/mcp/gitlab-mr-server.ts: remove `.max(30)` cap on comments so large MRs don't fail the entire submit_review call. Tests: 445/445 pass; tsc clean. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
jonathan-factory
approved these changes
Jun 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds first-class GitLab support to droid-action via a GitLab CI/CD Component, mirroring the GitHub action's UX. Customers drop
factory/droid-review.yml(one self-contained config file) and add a singleinclude:line to their.gitlab-ci.yml— they get automated code review on every merge request with inline MR comments, a sticky tracking note, and an optional parallel security-reviewer subagent.Changes
CI/CD Component & examples
templates/droid-review.yml— the GitLab CI/CD Component (top-leveltemplates/per GitLab Catalog requirement), plustemplates/README.mddocumenting the directory contract.gitlab/examples/factory/droid-review.yml+gitlab/examples/.gitlab-ci.yml— two-file drop-in sample, withgitlab/examples/README.mdexplaining the layout.Pipeline lifecycle scripts (
src/entrypoints/)gitlab-prepare.ts— Pass-1 prepare: context parsing, review-config resolution, artifact precomputation, and state file emission.gitlab-prepare-validator.ts— Pass-2 prepare: reconstructs prompt context from the state file and rewrites the shared prompt file for the validator pass (no GitLab API calls).gitlab-update-comment-link.ts— post-run tracking-note update with pipeline/job links and telemetry.GitLab integration layer (
src/gitlab/)api/client.ts+api/config.ts— REST client (MR fetch, changes, notes, diff discussions, description update) and config.context.ts,types.ts,token.ts— GitLab event context parsing, shared types, and token resolution (GITLAB_TOKEN→OVERRIDE_GITLAB_TOKEN→CI_JOB_TOKEN).prompts/—candidates.ts,validator.ts,types.tsfor the two-pass review prompts.data/review-artifacts.ts,data/exec-telemetry.ts— artifact staging and Droid Exec telemetry parsing.operations/tracking-note.ts— sticky tracking note build/find with security badge, telemetry summary, and session IDs.MCP server (
src/mcp/)gitlab-mr-server.ts— exposessubmit_review(batched summary note + inline diff discussions anchored viadiff_refs) and tracking-note tooling to Droid Exec, with per-comment error collection.Docs
docs/gitlab-setup.md— full setup, inputs reference, and troubleshooting; new GitLab section added toREADME.md.Tests
test/gitlab/andtest/mcp/covering the API client, context parsing, telemetry, prompts, review config resolution, token resolution, tracking note, review artifacts, and the MR MCP server.Customer-facing surface
Testing
End-to-end exercised against a real GitLab MR with two-pass review, sticky note, telemetry, security subagent, and
.droid-debug/staging all running against the live GitLab API + a real runner:templates/move + mirror swaptsc --noEmitclean.Related Issues
Factory-AI/factory-mono#14243— updates/install-code-reviewskill for GitLab (two-file write, gitlab.com mirror).Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>