> ## 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.

# Bitbucket Pipelines

> Set up Bitbucket Pipelines workflow for coverage reporting.

## Overview

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

**Reference Repository**: [codeant-coverage](https://bitbucket.org/codeantworkspace/codeant-coverage/src/main/)

## Features

* 📊 Upload coverage reports in XML format (Cobertura XML, JaCoCo XML)
* 🔍 Automatic coverage analysis and insights
* 📈 Track coverage trends over time
* 🎯 Integration with pull requests
* 🚀 Easy setup with minimal configuration
* 🏢 Support for self-hosted/enterprise instances

## Setup

### 1. Create a CodeAnt Token

In CodeAnt AI, open the user menu (click your email at the bottom-left) and select **API Tokens**, click **Create token**, and copy the generated token (it starts with `cdt_` and is shown only once). See [API Tokens](/settings/api-tokens) for the full walkthrough. This single token authenticates the upload - you don't need a Bitbucket access token or app password.

### 2. Configure Repository Variables

Before using the pipe, configure this repository variable in **Repository Settings → Pipelines → Repository variables**:

* `CODEANT_TOKEN` - Your CodeAnt token (`cdt_…`)

## Basic Usage

### Example 1: Basic Coverage Upload

```yaml theme={null}
image: python:3.11

pipelines:
  default:
    - step:
        name: Run tests and generate coverage
        script:
          - pip install pytest pytest-cov
          - pytest --cov=. --cov-report=xml:coverage.xml

    - step:
        name: Upload coverage to CodeAnt AI
        script:
          - pipe: docker://public.ecr.aws/d2p9q4a9/codeant-coverage:latest
            variables:
              ACCESS_TOKEN: $CODEANT_TOKEN
              COVERAGE_FILE: coverage.xml
```

### Example 2: Pull Request Coverage Analysis

```yaml theme={null}
image: python:3.11

pipelines:
  pull-requests:
    '**':
      - step:
          name: Test and Coverage
          caches:
            - pip
          script:
            - pip install pytest pytest-cov
            - pytest --cov=. --cov-report=xml:coverage.xml

      - step:
          name: Upload to CodeAnt AI
          script:
            - pipe: docker://public.ecr.aws/d2p9q4a9/codeant-coverage:latest
              variables:
                ACCESS_TOKEN: $CODEANT_TOKEN
                COVERAGE_FILE: coverage.xml
```

### Example 3: Advanced Configuration with Debug Mode

```yaml theme={null}
- step:
    name: Upload coverage to CodeAnt AI
    script:
      - pipe: docker://public.ecr.aws/d2p9q4a9/codeant-coverage:latest
        variables:
          ACCESS_TOKEN: $CODEANT_TOKEN
          COVERAGE_FILE: coverage.xml
          API_BASE_URL: https://api.codeant.ai
          PLATFORM: bitbucket
          FAIL_ON_ERROR: 'true'
          DEBUG: 'false'
```

## Configuration Variables

| Variable        | Required | Default                  | Description                                                                                                                                                                 |
| --------------- | -------- | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CODEANT_TOKEN` | Yes      | -                        | CodeAnt API token (`cdt_…`) for authentication - see [API Tokens](/settings/api-tokens) (set as repository variable and pass as `ACCESS_TOKEN: $CODEANT_TOKEN` in pipeline) |
| `COVERAGE_FILE` | Yes      | `coverage.xml`           | Path to the coverage XML file (e.g., coverage.xml)                                                                                                                          |
| `API_BASE_URL`  | No       | `https://api.codeant.ai` | CodeAnt AI API base URL (for self-hosted instances)                                                                                                                         |
| `PLATFORM`      | No       | `bitbucket`              | Git platform (github, gitlab, bitbucket)                                                                                                                                    |
| `FAIL_ON_ERROR` | No       | `true`                   | Fail the build if coverage upload fails                                                                                                                                     |
| `DEBUG`         | No       | `false`                  | Enable debug logging                                                                                                                                                        |

## Supported Coverage Formats

> **Important:** Only XML format is supported for coverage reports.

* Cobertura XML (`.xml`)
* JaCoCo XML

## Language-Specific Examples

### Python with pytest

```yaml theme={null}
image: python:3.11

pipelines:
  pull-requests:
    '**':
      - step:
          name: Test and Coverage
          caches:
            - pip
          script:
            - pip install pytest pytest-cov
            - pytest --cov=. --cov-report=xml:coverage.xml

      - step:
          name: Upload to CodeAnt AI
          script:
            - pipe: docker://public.ecr.aws/d2p9q4a9/codeant-coverage:latest
              variables:
                ACCESS_TOKEN: $CODEANT_TOKEN
```

### JavaScript with Jest

```yaml theme={null}
image: node:18

pipelines:
  pull-requests:
    '**':
      - step:
          name: Test and Coverage
          caches:
            - node
          script:
            - npm install
            - npm test -- --coverage --coverageReporters=cobertura

      - step:
          name: Upload to CodeAnt AI
          script:
            - pipe: docker://public.ecr.aws/d2p9q4a9/codeant-coverage:latest
              variables:
                ACCESS_TOKEN: $CODEANT_TOKEN
                COVERAGE_FILE: coverage/cobertura-coverage.xml
```

### Java with Maven

```yaml theme={null}
image: maven:3.8-openjdk-11

pipelines:
  pull-requests:
    '**':
      - step:
          name: Test and Coverage
          caches:
            - maven
          script:
            - mvn clean test jacoco:report

      - step:
          name: Upload to CodeAnt AI
          script:
            - pipe: docker://public.ecr.aws/d2p9q4a9/codeant-coverage:latest
              variables:
                ACCESS_TOKEN: $CODEANT_TOKEN
                COVERAGE_FILE: target/site/jacoco/jacoco.xml
```

### Go with go-cover

```yaml theme={null}
image: golang:1.21

pipelines:
  pull-requests:
    '**':
      - step:
          name: Test and Coverage
          script:
            - go test -coverprofile=coverage.out ./...
            - go install github.com/axw/gocov/gocov@latest
            - go install github.com/AlekSi/gocov-xml@latest
            - gocov convert coverage.out | gocov-xml > coverage.xml

      - step:
          name: Upload to CodeAnt AI
          script:
            - pipe: docker://public.ecr.aws/d2p9q4a9/codeant-coverage:latest
              variables:
                ACCESS_TOKEN: $CODEANT_TOKEN
                COVERAGE_FILE: coverage.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 steps 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.

### Recommended: `parallel` steps

Bitbucket Pipelines doesn't have a `matrix` directive, but [`parallel`](https://support.atlassian.com/bitbucket-cloud/docs/parallel-steps/) lets each module upload run concurrently in its own step. Adding a new module is one new step in the `parallel` block.

```yaml theme={null}
pipelines:
  pull-requests:
    '**':
      - step:
          name: Test all modules
          script:
            - cd services/backend && pytest --cov --cov-report=xml && cd -
            - cd services/frontend && npm ci && npm test -- --coverage --coverageReporters=cobertura && cd -
            - cd services/api && pytest --cov --cov-report=xml
          artifacts:
            - services/backend/coverage.xml
            - services/frontend/coverage/cobertura-coverage.xml
            - services/api/coverage.xml

      - parallel:
          - step:
              name: Upload backend coverage
              script:
                - pipe: docker://public.ecr.aws/d2p9q4a9/codeant-coverage:latest
                  variables:
                    ACCESS_TOKEN: $CODEANT_TOKEN
                    COVERAGE_FILE: services/backend/coverage.xml
                    MODULE: backend
                    MODULE_PATH: services/backend
          - step:
              name: Upload frontend coverage
              script:
                - pipe: docker://public.ecr.aws/d2p9q4a9/codeant-coverage:latest
                  variables:
                    ACCESS_TOKEN: $CODEANT_TOKEN
                    COVERAGE_FILE: services/frontend/coverage/cobertura-coverage.xml
                    MODULE: frontend
                    MODULE_PATH: services/frontend
          - step:
              name: Upload api coverage
              script:
                - pipe: docker://public.ecr.aws/d2p9q4a9/codeant-coverage:latest
                  variables:
                    ACCESS_TOKEN: $CODEANT_TOKEN
                    COVERAGE_FILE: services/api/coverage.xml
                    MODULE: api
                    MODULE_PATH: services/api
```

### Alternative: sequential uploads in one step

If you'd rather upload every module inside a single step (e.g. to avoid extra step minutes), call the pipe multiple times in the same `script:` block:

```yaml theme={null}
- step:
    name: Upload coverage to CodeAnt AI
    script:
      - pipe: docker://public.ecr.aws/d2p9q4a9/codeant-coverage:latest
        variables:
          ACCESS_TOKEN: $CODEANT_TOKEN
          COVERAGE_FILE: services/backend/coverage.xml
          MODULE: backend
          MODULE_PATH: services/backend
      - pipe: docker://public.ecr.aws/d2p9q4a9/codeant-coverage:latest
        variables:
          ACCESS_TOKEN: $CODEANT_TOKEN
          COVERAGE_FILE: services/frontend/coverage/cobertura-coverage.xml
          MODULE: frontend
          MODULE_PATH: services/frontend
```

## Coverage Configuration

### Python Coverage Configuration

Create a `.coveragerc` file in your project's root folder to include all source files in the test coverage calculation:

```ini theme={null}
[run]
# include every Python file under the repo root
source = .

# exclude tests, virtualenvs, build artifacts, etc.
omit =
    */tests/*
    */.venv/*
    */build/*
    */dist/*
```

When you assign source to `.`, it checks for every Python file in the root folder and its subdirectories. You can omit directories by placing them in the omit section.

## How It Works

1. The pipe fetches the latest coverage upload script from CodeAnt AI
2. Automatically decodes and prepares the script for execution
3. Uploads your coverage report along with commit and repository information
4. CodeAnt AI processes the report and provides analysis on your pull requests
5. Lines executed by your tests are marked as "covered"
6. Coverage percentage is calculated and status checks are performed on every push

## Troubleshooting

### Enable Debug Mode

Set `DEBUG: 'true'` to see detailed logs:

```yaml theme={null}
- pipe: docker://public.ecr.aws/d2p9q4a9/codeant-coverage:latest
  variables:
    ACCESS_TOKEN: $CODEANT_TOKEN
    DEBUG: 'true'
```

### Coverage File Not Found

**Issue**: Coverage file not found error

**Solution**: Ensure the coverage file is generated before upload and verify the `COVERAGE_FILE` path is correct. Use artifacts to pass files between steps if needed.

### Upload Fails But Pipeline Continues

**Issue**: Upload fails but pipeline continues

**Solution**: Set `FAIL_ON_ERROR: 'false'` to continue the pipeline even if upload fails (default is `true`).

### Authentication Errors

**Issue**: Authentication errors during upload

**Solution**: Verify your `CODEANT_TOKEN` holds a valid CodeAnt token (`cdt_…`) that hasn't been revoked, belongs to the same organization as the repository, and is marked as secured in Repository Variables. You can re-issue tokens under **API Tokens** (in the user menu - your email at the bottom-left) in CodeAnt AI - see [API Tokens](/settings/api-tokens).

### Low Coverage Reporting

**Issue**: Coverage reporting is lower than expected

**Solution**: Check your coverage configuration file (e.g., `.coveragerc`), ensure all source files are included, and verify omit patterns aren't excluding too much code.

## Support

* 📧 Email: [support@codeant.ai](mailto:support@codeant.ai)
* 📚 Documentation: [https://docs.codeant.ai](https://docs.codeant.ai)
* 🐛 Repository: [https://bitbucket.org/codeantworkspace/codeant-coverage/src/main/](https://bitbucket.org/codeantworkspace/codeant-coverage/src/main/)

## License

MIT License - see LICENSE file for details## Token permission

This pipeline authenticates with a CodeAnt API token (`cdt_…`). If the token is **scoped**, give it the **Codeant CI/CD** role - it covers scans, quality gates, and test-coverage upload - scoped to the repositories this pipeline runs on (or **All repositories**). A token missing the required permission is rejected with an HTTP `403` `token_scope_forbidden` error that names the permission it needs. See [API token permissions](/settings/api-tokens#permissions-and-scopes).
