# Gitlab CI

#### What is Gitlab CI? <a href="#what-is-gitlab-ci" id="what-is-gitlab-ci"></a>

GitLab CI/CD is GitLab's built-in continuous integration and continuous delivery platform that allows you to automatically build, test, and deploy your code. It's configured through a `.gitlab-ci.yml` file in your repository's root, where you define pipelines consisting of stages and jobs. When you push code or trigger a merge request, GitLab runners execute these jobs—running tests, building artifacts, deploying to environments, etc. Its tight integration with GitLab's version control, merge requests, and container registry makes it a seamless choice for teams already using GitLab for source control.

#### **Key features of what can be done with an AI agent in Gitlab CI:** <a href="#key-features-of-what-can-be-done-with-an-ai-agent-in-gitlab-ci" id="key-features-of-what-can-be-done-with-an-ai-agent-in-gitlab-ci"></a>

* **Automated Code Review — The agent can analyze merge requests and provide feedback on code quality, potential bugs, and style issues before human reviewers get involved.**
* **Merge Request Summaries — Automatically generates clear descriptions of what changed, making it easier for reviewers to understand the scope of a MR.**
* **Reduced Review Bottlenecks** — Handles routine feedback automatically, freeing up senior developers to focus on architectural and complex logic reviews.

To connect your [All-in-one AI platform for business](http://nexos.ai/) **API** and **Claude Code** in Gitlab CI for a simple code review bot you can follow these steps:

#### 1. Create your `gitlab-ci.yml` in your project: <a href="#id-1.-create-your-gitlab-ci.yml-in-your-project" id="id-1.-create-your-gitlab-ci.yml-in-your-project"></a>

```
stages:
  - review

claude-code-review:
  variables:
    REVIEW_MARKER: "<!-- claude-code-review -->"
    GIT_DEPTH: 0 # Needed for long history
  tags:
    - claude-review
  stage: review
  image: node:20-alpine
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event" # Makes the job only run in merge requests
  before_script:
    - apk add --no-cache curl jq git # Install used tools
    - mkdir -p /root/.claude/projects # Needed just to not see claude code error in pipeline
    - adduser -D claude && chown -R claude:claude $CI_PROJECT_DIR
  script:
    # Setup
    - npm install -g @anthropic-ai/claude-code @musistudio/claude-code-router
    - mkdir -p ~/.claude-code-router
    # Same config from Claude Code setup guide
    - |
      cat > ~/.claude-code-router/config.json << EOF
      {
        "HOST": "127.0.0.1",
        "PORT": 3456,
        "API_TIMEOUT_MS": "600000",
        "Providers": [
          {
            "name": "nexosai",
            "api_base_url": "https://api.nexos.ai/v1/chat/completions",
            "api_key": "${LLM_API_KEY}",
            "models": [
              "claude-opus-4-1-20250805",
              "claude-haiku-4-5-20251001"
            ],
            "transformer": {
              "use": [
                "OpenAI"
              ]
            }
          }
        ],
        "Router": {
          "default": "nexosai,claude-haiku-4-5-20251001",
          "background": "nexosai,claude-haiku-4-5-20251001",
          "webSearch": "nexosai,claude-haiku-4-5-20251001",
          "think": "nexosai,claude-opus-4-1-20250805",
          "longContext": "nexosai,claude-haiku-4-5-20251001",
          "longContextThreshold": 60000
        }
      }
      EOF

    # Starting router and providing a delay
    - npx @musistudio/claude-code-router start &
    - sleep 3

    # Adding a hidden review marker into the review file which will allow later to edit same note instead of creating multiple
    - echo "$REVIEW_MARKER" > /tmp/review.md
    # Fetching branch and retrieving changed files
    - su claude -c "git fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME"
    - CHANGED_FILES=$(su claude -c "git diff --name-only origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME...HEAD -- '*.go'")

    # Actually calling Claude Code
    - |
      echo "You are a code reviewer. Review the following changed Go files:

      $CHANGED_FILES

      Use View to examine each file.
      Output ONLY raw GitLab-compatible markdown with your findings.
      No preamble, no explanation, no summary - just the markdown review content itself." | \
      su claude -c '
        ANTHROPIC_BASE_URL=http://127.0.0.1:3456 \
        ANTHROPIC_API_KEY=placeholder \
        claude --print --dangerously-skip-permissions \
          --allowedTools "View,GlobTool,GrepTool"
      ' >> /tmp/review.md

    # Posting the note
    - |
      # find existing note ID
      NOTE_ID=$(curl -s --header "PRIVATE-TOKEN: ${GITLAB_API_TOKEN}" \
        "$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests/$CI_MERGE_REQUEST_IID/notes" \
        | jq -r --arg marker "$REVIEW_MARKER" '.[] | select(.body | contains($marker)) | .id' | head -1)

      if [ -n "$NOTE_ID" ]; then
        # Update existing note
        curl --fail --request PUT \
          --header "PRIVATE-TOKEN: ${GITLAB_API_TOKEN}" \
          --header "Content-Type: application/json" \
          --data "$(jq -Rs '{body: .}' /tmp/review.md)" \
          "$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests/$CI_MERGE_REQUEST_IID/notes/$NOTE_ID"
      else
        # Create new note
        curl --fail --request POST \
          --header "PRIVATE-TOKEN: ${GITLAB_API_TOKEN}" \
          --header "Content-Type: application/json" \
          --data "$(jq -Rs '{body: .}' /tmp/review.md)" \
          "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests/${CI_MERGE_REQUEST_IID}/notes"
      fi
```

This snippet is based on the [Claude Code setup guide](https://nexos-ai.atlassian.net/wiki/spaces/NA2/pages/541098001) and launches Claude Code with Claude Code Router inside a GitLab pipeline. However, this is just one implementation—a similar approach should work with other AI coding agents like [Aider](https://aider.chat/).

The configuration is security-conscious: the model is mostly restricted to read-only operations and cannot interact with Bash or the GitLab MCP, though these could be enabled if needed. For posting feedback, the pipeline uses simple GitLab API calls via cURL and updates a single comment on the MR rather than creating a new one each time.

#### 2. Create your access keys and pipeline variables in Gitlab: <a href="#id-2.-create-your-access-keys-and-pipeline-variables-in-gitlab" id="id-2.-create-your-access-keys-and-pipeline-variables-in-gitlab"></a>

For the provider example, the access key is a project scoped access token with the `Reporter` role and `api` scope. It is then set in the CI/CD variables as `GITLAB_API_TOKEN` which is masked to avoid leaking it in the pipeline. The other CI/CD variable is `LLM_API_KEY` which is your nexos.ai API key that will be used by Claude Code.

#### Tip: <a href="#tip" id="tip"></a>

We recommend testing the AI coding agent locally before adding it to your GitLab pipeline. Errors that occur inside the agent during pipeline runs can be difficult to trace, since they may not surface clearly in the logs. Setting it up locally first makes troubleshooting much easier—once everything works as expected, you can confidently integrate it into your pipeline.

&#x20;


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.nexos.ai/gateway-api/integrations/gitlab-ci.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
