Skip to content

feat(gitlab): Phase 1 GitLab support via CI/CD Component#93

Merged
factory-nizar merged 29 commits into
devfrom
feat/gitlab-support
Jun 3, 2026
Merged

feat(gitlab): Phase 1 GitLab support via CI/CD Component#93
factory-nizar merged 29 commits into
devfrom
feat/gitlab-support

Conversation

@factory-nizar
Copy link
Copy Markdown
Contributor

@factory-nizar factory-nizar commented Jun 2, 2026

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 single include: 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-level templates/ per GitLab Catalog requirement), plus templates/README.md documenting the directory contract.
  • gitlab/examples/factory/droid-review.yml + gitlab/examples/.gitlab-ci.yml — two-file drop-in sample, with gitlab/examples/README.md explaining 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_TOKENOVERRIDE_GITLAB_TOKENCI_JOB_TOKEN).
  • prompts/candidates.ts, validator.ts, types.ts for 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 — exposes submit_review (batched summary note + inline diff discussions anchored via diff_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 to README.md.
    Tests
  • New suites under test/gitlab/ and test/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

# factory/droid-review.yml (dropped by the /install-code-review skill)
include:
  - project: "factory-components/droid-action"
    ref: main
    file: "/templates/droid-review.yml"
    inputs:
      automatic_review: "true"
      automatic_security_review: "false"
      review_depth: "deep"
droid-review:
  variables:
    FACTORY_API_KEY: $FACTORY_API_KEY
    GITLAB_TOKEN: $GITLAB_TOKEN
# .gitlab-ci.yml (project root — append the one include if file already exists)
include:
  - local: "factory/droid-review.yml"

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:

What Link
Test MR ruby_repo-with-space MR !4
Initial review validation #2568924325 — 8m 14s, 26 turns, 12 inline findings (P0 SQL injection, mass assignment, missing transaction, nil deref)
Post-rebase re-validation #2571511473
Review + Fill after templates/ move + mirror swap #2571627128 — both jobs green; fill rewrote MR description in 60s
445 tests pass, tsc --noEmit clean.

Related Issues

  • Companion: Factory-AI/factory-mono#14243 — updates /install-code-review skill for GitLab (two-file write, gitlab.com mirror).
  • Stacked follow-up: #94 — `` for GitLab.
    Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>

factory-nizar and others added 21 commits June 2, 2026 10:43
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>
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>
@factory-nizar factory-nizar force-pushed the feat/gitlab-support branch from 9ef6f30 to 6f05311 Compare June 2, 2026 17:44
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>
@factory-droid
Copy link
Copy Markdown
Contributor

factory-droid Bot commented Jun 2, 2026

Droid finished @factory-nizar's task —— View job


factory-nizar and others added 4 commits June 2, 2026 14:09
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>
@factory-nizar factory-nizar marked this pull request as ready for review June 2, 2026 21:41
@factory-droid
Copy link
Copy Markdown
Contributor

factory-droid Bot commented Jun 2, 2026

Droid finished @factory-nizar's task —— View job


Security Review

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 stages, ref/SHA cloning semantics) or make posting unreliable / unsafe (Pass-1 tool blast radius, forced MCP trust, unanchored comments, and the 30-comment cap mismatch).

Comment thread templates/droid-review.yml Outdated
Comment thread templates/droid-review.yml
Comment thread templates/droid-review.yml
Comment thread src/entrypoints/gitlab-prepare.ts
Comment thread src/gitlab/token.ts Outdated
Comment thread src/mcp/gitlab-mr-server.ts Outdated
Comment thread src/mcp/gitlab-mr-server.ts Outdated
…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>
@factory-droid
Copy link
Copy Markdown
Contributor

factory-droid Bot commented Jun 2, 2026

Droid finished @factory-nizar's task —— View job


- 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>
@factory-nizar factory-nizar merged commit 84946f2 into dev Jun 3, 2026
1 check passed
@factory-nizar factory-nizar deleted the feat/gitlab-support branch June 3, 2026 17:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants