Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.codeant.ai/llms.txt

Use this file to discover all available pages before exploring further.

CodeAnt AI Coverage Upload for GitLab

Upload test coverage reports to CodeAnt AI for comprehensive analysis, visualization, and tracking of your code coverage metrics.

Features

  • 📊 Upload coverage reports in XML format (Cobertura XML, JaCoCo XML)
  • 🔍 Automatic coverage analysis and insights
  • 📈 Track coverage trends over time
  • 🎯 Integration with merge requests
  • 🚀 Easy setup with minimal configuration

Usage

Basic Example

include:
  - remote: 'https://gitlab.com/codeant-pipelines/code-coverage-gitlab/-/raw/main/.gitlab-ci.yml'

stages:
  - test
  - report

test:
  stage: test
  image: python:3.9
  script:
    # Your test command that generates coverage report
    - pytest --cov --cov-report=xml
  artifacts:
    paths:
      - coverage.xml

codeant_coverage:
  extends: .codeant_coverage_upload
  stage: report
  needs: [test]
  variables:
    COVERAGE_FILE: "coverage.xml"

Advanced Example

codeant_coverage:
  extends: .codeant_coverage_upload
  stage: report
  needs: [test]
  variables:
    COVERAGE_FILE: "coverage.xml"
    MODULE: "backend"
    MODULE_PATH: "services/backend"
    # API_BASE, PLATFORM, BASE_URL fall back to sensible defaults; only override
    # them if you're on a private CodeAnt AI deployment or self-hosted GitLab.

Inputs

ACCESS_TOKEN must be added as a project (or group) CI/CD variable so it can be masked — never paste it into your .gitlab-ci.yml. The remaining variables go under variables: inside the upload job. Set as a CI/CD variable
VariableDescriptionRequired
ACCESS_TOKENGitLab access token used to authenticate with CodeAnt AI. The script reads this exact name.Yes
Set under variables: in your .gitlab-ci.yml
VariableDescriptionRequiredDefault
COVERAGE_FILEPath to the coverage XML file (e.g. coverage.xml).Yescoverage.xml
API_BASECodeAnt AI API base URL.Nohttps://api.codeant.ai
PLATFORMGit platform (github, gitlab, bitbucket).Nogitlab
BASE_URLBase URL of the git platform. Leave at the default for self-hosted GitLab — $CI_SERVER_URL is set automatically per pipeline.No$CI_SERVER_URL
MODULEModule name for monorepo setups (e.g. backend, frontend). Required when uploading multiple coverage files for the same commit so reports don’t collide.No-
MODULE_PATHModule path used to resolve files in a monorepo (e.g. services/backend). Defaults to MODULE if omitted.NoMODULE

Supported Coverage Formats

Important: Only XML format is supported for coverage reports.
  • Cobertura XML (.xml)
  • JaCoCo XML

Setup

1. Get Your GitLab Access Token

  1. Log in to your GitLab account
  2. Go to Edit profile (User Settings) > Access Tokens
  3. Create a new token with the api scope (This grants full read/write access to the API and repositories)
  4. Copy the token

2. Generate Coverage Report

First, ensure your test suite generates a coverage report. Here are examples for common languages: Python (pytest)
pytest --cov --cov-report=xml
JavaScript/TypeScript (Jest)
jest --coverage --coverageReporters=cobertura
Java (Maven)
mvn test jacoco:report
Go
go test -coverprofile=coverage.out ./...
gocov convert coverage.out | gocov-xml > coverage.xml

3. Add CI/CD Variables

Add your GitLab Access Token to your GitLab project:
  1. Go to your repository Settings
  2. Navigate to CI/CD > Variables
  3. Click “Add variable”
  4. Key: ACCESS_TOKEN (this is the variable name the included template reads)
  5. Value: Your GitLab Access Token
  6. Protected: Yes (recommended)
  7. Masked: Yes (recommended)

4. Configure Pipeline

Add the template to your .gitlab-ci.yml as shown in the usage examples above.

How It Works

  1. The job fetches the latest coverage upload script from CodeAnt AI
  2. Decodes and prepares the script for execution
  3. Uploads your coverage report along with commit and branch information
  4. CodeAnt AI processes the report and provides analysis

Examples

Python Project

include:
  - remote: 'https://gitlab.com/codeant-pipelines/code-coverage-gitlab/-/raw/main/.gitlab-ci.yml'

stages:
  - test
  - report

test:
  stage: test
  image: python:3.9
  script:
    - pip install pytest pytest-cov
    - pytest --cov=. --cov-report=xml
  artifacts:
    paths:
      - coverage.xml

codeant_coverage:
  extends: .codeant_coverage_upload
  stage: report
  needs: [test]
  variables:
    COVERAGE_FILE: "coverage.xml"

Node.js Project

include:
  - remote: 'https://gitlab.com/codeant-pipelines/code-coverage-gitlab/-/raw/main/.gitlab-ci.yml'

stages:
  - test
  - report

test:
  stage: test
  image: node:18
  script:
    - npm ci
    - npm test -- --coverage --coverageReporters=cobertura
  artifacts:
    paths:
      - coverage/cobertura-coverage.xml

codeant_coverage:
  extends: .codeant_coverage_upload
  stage: report
  needs: [test]
  variables:
    COVERAGE_FILE: "coverage/cobertura-coverage.xml"

Java Project

include:
  - remote: 'https://gitlab.com/codeant-pipelines/code-coverage-gitlab/-/raw/main/.gitlab-ci.yml'

stages:
  - test
  - report

test:
  stage: test
  image: maven:3.8-openjdk-11
  script:
    - mvn clean test jacoco:report
  artifacts:
    paths:
      - target/site/jacoco/jacoco.xml

codeant_coverage:
  extends: .codeant_coverage_upload
  stage: report
  needs: [test]
  variables:
    COVERAGE_FILE: "target/site/jacoco/jacoco.xml"

Multiple Coverage Files (Monorepo)

When a single commit produces several coverage reports — for example one per service in a monorepo — give each upload its own MODULE and MODULE_PATH. CodeAnt AI keeps the reports separate so each module is tracked, displayed, and gated independently. Without MODULE, every upload writes to the same key and later jobs overwrite earlier ones.
  • MODULE is the logical name shown in the UI (e.g. backend, frontend).
  • MODULE_PATH is the directory used to resolve source files referenced in the coverage XML (e.g. services/backend). If your XML’s filename attributes are relative to the module root, set MODULE_PATH to that root.
Instead of duplicating the upload block per module, define it once and fan it out with parallel:matrix. Each matrix entry becomes its own parallel job; adding a new module is one new entry instead of an entire job stanza. The job name codeant_coverage matches the one shipped by the included template, so this definition replaces it. Provide your own test_* jobs that emit each module’s coverage XML at the path referenced by COVERAGE_FILE.
include:
  - remote: 'https://gitlab.com/codeant-pipelines/code-coverage-gitlab/-/raw/main/.gitlab-ci.yml'

stages:
  - test
  - report

# Your own test jobs that emit per-module coverage.xml as artifacts.
test_backend:
  stage: test
  image: python:3.9
  script:
    - cd services/backend
    - pip install pytest pytest-cov && pytest --cov --cov-report=xml
  artifacts:
    paths:
      - services/backend/coverage.xml

test_frontend:
  stage: test
  image: node:18
  script:
    - cd services/frontend
    - npm ci && npm test -- --coverage --coverageReporters=cobertura
  artifacts:
    paths:
      - services/frontend/coverage/cobertura-coverage.xml

# Single upload job; one variant runs per matrix entry.
codeant_coverage:
  extends: .codeant_coverage_upload
  stage: report
  parallel:
    matrix:
      - MODULE: backend
        MODULE_PATH: services/backend
        COVERAGE_FILE: services/backend/coverage.xml
      - MODULE: frontend
        MODULE_PATH: services/frontend
        COVERAGE_FILE: services/frontend/coverage/cobertura-coverage.xml
      - MODULE: api
        MODULE_PATH: services/api
        COVERAGE_FILE: services/api/coverage.xml
GitLab spawns one job per matrix entry — codeant_coverage: [backend, services/backend, services/backend/coverage.xml], codeant_coverage: [frontend, …], etc. — and each one runs the upload independently with its own MODULE, MODULE_PATH, and COVERAGE_FILE.

Alternative: one job per module

If you prefer the explicit form (e.g. you want each module gated by a different upstream needs:), define a job per module:
codeant_coverage_backend:
  extends: .codeant_coverage_upload
  stage: report
  needs: [test_backend]
  variables:
    COVERAGE_FILE: "services/backend/coverage.xml"
    MODULE: "backend"
    MODULE_PATH: "services/backend"

codeant_coverage_frontend:
  extends: .codeant_coverage_upload
  stage: report
  needs: [test_frontend]
  variables:
    COVERAGE_FILE: "services/frontend/coverage/cobertura-coverage.xml"
    MODULE: "frontend"
    MODULE_PATH: "services/frontend"

Troubleshooting

Coverage file not found
  • Ensure the COVERAGE_FILE path is correct and the file exists as an artifact from a previous job.
Authentication failed / Invalid access token
  • Verify that your ACCESS_TOKEN is valid and that its owner has access to the project — the validator calls GET /api/v4/projects/{repo} with the token and rejects anything other than 200. A token can be alive (200 on /api/v4/user) but still 404 on the project if its owner was removed from the project.
  • If you have an ACCESS_TOKEN defined as a project-level CI/CD variable, it overrides any ACCESS_TOKEN set in .gitlab-ci.yml (project-level CI variables take precedence over YAML variables). Update or remove the project-level variable rather than trying to override it from YAML.
Script execution failed
  • Check that the CodeAnt AI API is accessible from your runner environment.

Contributing

Contributions are welcome! Please feel free to submit a Merge Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support