---
title: "CI/CD Pipeline Integration"
description: "Complete guide to integrating TraceRTM with CI/CD pipelines for automated traceability validation"
---

# CI/CD Pipeline Integration

Integrate TraceRTM into your CI/CD pipelines to automate traceability validation, enforce coverage requirements, and generate compliance reports as part of your development workflow.

## Overview

### Benefits of CI/CD Integration

Integrating TraceRTM with your CI/CD pipeline provides:

- **Automated Traceability Validation**: Verify requirement-to-test coverage on every commit
- **Quality Gates**: Enforce minimum coverage thresholds before merging
- **Early Detection**: Catch traceability gaps during development, not at release time
- **Compliance Automation**: Generate audit-ready reports automatically
- **Team Visibility**: Share traceability status across the organization
- **Reduced Manual Work**: Eliminate manual traceability checks and report generation

### Integration Points

TraceRTM can be integrated at multiple points in your pipeline:

1. **Pre-commit Hooks**: Validate local changes before pushing
2. **Pull Request Checks**: Block PRs that break traceability
3. **Continuous Integration**: Run full validation on every build
4. **Scheduled Jobs**: Generate periodic compliance reports
5. **Release Gates**: Ensure traceability before deployment

## GitHub Actions Integration

### Complete Workflow Example

Create `.github/workflows/traceability.yml`:

```yaml
name: Traceability Validation

on:
  pull_request:
    branches: [main, develop]
  push:
    branches: [main, develop]
  schedule:
    # Daily compliance report at 9 AM UTC
    - cron: '0 9 * * *'
  workflow_dispatch:

env:
  TRACERTM_VERSION: '1.0.0'
  COVERAGE_THRESHOLD: '80'

jobs:
  validate-traceability:
    name: Validate Traceability Coverage
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0  # Full history for complete analysis

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'
          cache: 'pip'

      - name: Install TraceRTM
        run: |
          pip install tracertm==${{ env.TRACERTM_VERSION }}
          tracertm --version

      - name: Initialize TraceRTM
        run: |
          if [ ! -f ".tracertm/config.yaml" ]; then
            tracertm init --name "${{ github.repository }}"
          fi

      - name: Sync Requirements
        run: |
          tracertm sync requirements ./requirements
          tracertm sync tests ./tests

      - name: Check Traceability Coverage
        id: coverage
        run: |
          tracertm report coverage --format json > coverage.json
          COVERAGE=$(jq -r '.overall_coverage' coverage.json)
          echo "coverage=$COVERAGE" >> $GITHUB_OUTPUT

          if (( $(echo "$COVERAGE < $COVERAGE_THRESHOLD" | bc -l) )); then
            echo "::error::Coverage $COVERAGE% is below threshold $COVERAGE_THRESHOLD%"
            exit 1
          fi

      - name: Validate Links
        run: |
          tracertm validate links --strict

      - name: Check for Orphaned Items
        run: |
          ORPHANS=$(tracertm query orphans --format json | jq '. | length')
          if [ "$ORPHANS" -gt 0 ]; then
            echo "::warning::Found $ORPHANS orphaned items"
            tracertm query orphans
          fi

      - name: Generate Coverage Report
        if: always()
        run: |
          tracertm report coverage --format html > traceability-report.html
          tracertm report matrix --format html > traceability-matrix.html

      - name: Upload Reports
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: traceability-reports
          path: |
            traceability-report.html
            traceability-matrix.html
            coverage.json
          retention-days: 30

      - name: Comment PR
        if: github.event_name == 'pull_request'
        uses: actions/github-script@v7
        with:
          script: |
            const coverage = '${{ steps.coverage.outputs.coverage }}';
            const threshold = '${{ env.COVERAGE_THRESHOLD }}';
            const status = parseFloat(coverage) >= parseFloat(threshold) ? '✅' : '❌';

            const comment = `## ${status} Traceability Report

            **Coverage**: ${coverage}% (threshold: ${threshold}%)

            Download the [full traceability report](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details.
            `;

            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: comment
            });

  impact-analysis:
    name: Impact Analysis
    runs-on: ubuntu-latest
    if: github.event_name == 'pull_request'

    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'

      - name: Install TraceRTM
        run: pip install tracertm==${{ env.TRACERTM_VERSION }}

      - name: Analyze Changed Files
        id: changes
        run: |
          git diff --name-only origin/${{ github.base_ref }}...HEAD > changed_files.txt
          cat changed_files.txt

      - name: Run Impact Analysis
        run: |
          tracertm impact analyze --files changed_files.txt --format json > impact.json
          cat impact.json

      - name: Post Impact Summary
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const impact = JSON.parse(fs.readFileSync('impact.json', 'utf8'));

            const comment = `## 🔍 Impact Analysis

            **Affected Requirements**: ${impact.affected_requirements?.length || 0}
            **Affected Tests**: ${impact.affected_tests?.length || 0}
            **Risk Level**: ${impact.risk_level || 'Unknown'}

            ${impact.affected_requirements?.length > 0 ? '### Impacted Requirements\n' + impact.affected_requirements.map(r => `- ${r}`).join('\n') : ''}
            `;

            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: comment
            });

  compliance-report:
    name: Generate Compliance Report
    runs-on: ubuntu-latest
    if: github.event.schedule || github.event_name == 'workflow_dispatch'

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'

      - name: Install TraceRTM
        run: pip install tracertm==${{ env.TRACERTM_VERSION }}

      - name: Generate Full Reports
        run: |
          tracertm report coverage --format pdf > compliance-report.pdf
          tracertm report matrix --format excel > traceability-matrix.xlsx
          tracertm export --format json > full-traceability.json

      - name: Upload to Release
        if: github.ref == 'refs/heads/main'
        uses: softprops/action-gh-release@v1
        with:
          tag_name: compliance-${{ github.run_number }}
          files: |
            compliance-report.pdf
            traceability-matrix.xlsx
            full-traceability.json
```

## GitLab CI Integration

### Complete Pipeline Example

Create `.gitlab-ci.yml`:

```yaml
stages:
  - validate
  - analyze
  - report
  - publish

variables:
  TRACERTM_VERSION: "1.0.0"
  COVERAGE_THRESHOLD: "80"
  PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"

cache:
  paths:
    - .cache/pip
    - .tracertm/

.tracertm_base:
  image: python:3.11-slim
  before_script:
    - pip install tracertm==$TRACERTM_VERSION
    - tracertm --version
    - |
      if [ ! -f ".tracertm/config.yaml" ]; then
        tracertm init --name "$CI_PROJECT_NAME"
      fi

validate_traceability:
  extends: .tracertm_base
  stage: validate
  script:
    # Sync all items
    - tracertm sync requirements ./requirements
    - tracertm sync tests ./tests
    - tracertm sync code ./src

    # Check coverage
    - tracertm report coverage --format json > coverage.json
    - COVERAGE=$(jq -r '.overall_coverage' coverage.json)
    - echo "Coverage is $COVERAGE%"
    - |
      if (( $(echo "$COVERAGE < $COVERAGE_THRESHOLD" | bc -l) )); then
        echo "ERROR: Coverage $COVERAGE% is below threshold $COVERAGE_THRESHOLD%"
        exit 1
      fi

    # Validate all links
    - tracertm validate links --strict

    # Check for broken links
    - tracertm validate consistency

    # Report orphaned items
    - ORPHANS=$(tracertm query orphans --count)
    - echo "Found $ORPHANS orphaned items"
  artifacts:
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coverage.json
    paths:
      - coverage.json
    expire_in: 30 days
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'

impact_analysis:
  extends: .tracertm_base
  stage: analyze
  script:
    # Get changed files
    - git diff --name-only $CI_MERGE_REQUEST_DIFF_BASE_SHA...HEAD > changed_files.txt

    # Run impact analysis
    - tracertm impact analyze --files changed_files.txt --format json > impact.json

    # Display summary
    - cat impact.json | jq '.'

    # Post to merge request
    - |
      IMPACT_SUMMARY=$(cat impact.json | jq -r '.summary')
      curl --request POST --header "PRIVATE-TOKEN: $CI_JOB_TOKEN" \
        "$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests/$CI_MERGE_REQUEST_IID/notes" \
        --data "body=## Impact Analysis\n\n$IMPACT_SUMMARY"
  artifacts:
    paths:
      - impact.json
    expire_in: 7 days
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'

generate_reports:
  extends: .tracertm_base
  stage: report
  script:
    - tracertm report coverage --format html > traceability-report.html
    - tracertm report matrix --format html > traceability-matrix.html
    - tracertm report gaps --format html > coverage-gaps.html
    - tracertm export --format json > full-export.json
  artifacts:
    paths:
      - traceability-report.html
      - traceability-matrix.html
      - coverage-gaps.html
      - full-export.json
    expire_in: 90 days
  rules:
    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
    - if: '$CI_PIPELINE_SOURCE == "schedule"'

publish_compliance:
  extends: .tracertm_base
  stage: publish
  script:
    - tracertm report coverage --format pdf > compliance-report-$(date +%Y%m%d).pdf
    - tracertm report matrix --format excel > matrix-$(date +%Y%m%d).xlsx
  artifacts:
    paths:
      - compliance-report-*.pdf
      - matrix-*.xlsx
    expire_in: 1 year
  rules:
    - if: '$CI_COMMIT_TAG'
    - if: '$CI_PIPELINE_SOURCE == "schedule"'

pages:
  stage: publish
  dependencies:
    - generate_reports
  script:
    - mkdir -p public
    - cp traceability-report.html public/index.html
    - cp traceability-matrix.html public/matrix.html
    - cp coverage-gaps.html public/gaps.html
  artifacts:
    paths:
      - public
  rules:
    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
```

## Jenkins Pipeline Integration

### Declarative Pipeline Example

Create `Jenkinsfile`:

```groovy
pipeline {
    agent any

    environment {
        TRACERTM_VERSION = '1.0.0'
        COVERAGE_THRESHOLD = '80'
        PYTHON_VERSION = '3.11'
    }

    parameters {
        booleanParam(name: 'STRICT_MODE', defaultValue: true, description: 'Fail on any traceability issues')
        choice(name: 'REPORT_FORMAT', choices: ['html', 'pdf', 'json'], description: 'Report output format')
    }

    stages {
        stage('Setup') {
            steps {
                script {
                    sh '''
                        python3 -m venv venv
                        . venv/bin/activate
                        pip install --upgrade pip
                        pip install tracertm==${TRACERTM_VERSION}
                        tracertm --version
                    '''
                }
            }
        }

        stage('Initialize TraceRTM') {
            steps {
                script {
                    sh '''
                        . venv/bin/activate
                        if [ ! -f ".tracertm/config.yaml" ]; then
                            tracertm init --name "${JOB_NAME}"
                        fi
                    '''
                }
            }
        }

        stage('Sync Items') {
            parallel {
                stage('Sync Requirements') {
                    steps {
                        sh '. venv/bin/activate && tracertm sync requirements ./requirements'
                    }
                }
                stage('Sync Tests') {
                    steps {
                        sh '. venv/bin/activate && tracertm sync tests ./tests'
                    }
                }
                stage('Sync Code') {
                    steps {
                        sh '. venv/bin/activate && tracertm sync code ./src'
                    }
                }
            }
        }

        stage('Validate Traceability') {
            steps {
                script {
                    sh '''
                        . venv/bin/activate

                        # Generate coverage report
                        tracertm report coverage --format json > coverage.json
                        COVERAGE=$(jq -r '.overall_coverage' coverage.json)
                        echo "Traceability Coverage: ${COVERAGE}%"

                        # Check threshold
                        if (( $(echo "$COVERAGE < $COVERAGE_THRESHOLD" | bc -l) )); then
                            echo "ERROR: Coverage ${COVERAGE}% below threshold ${COVERAGE_THRESHOLD}%"
                            if [ "${STRICT_MODE}" = "true" ]; then
                                exit 1
                            fi
                        fi

                        # Validate links
                        tracertm validate links || true

                        # Check consistency
                        tracertm validate consistency || true
                    '''
                }
            }
        }

        stage('Impact Analysis') {
            when {
                changeRequest()
            }
            steps {
                script {
                    sh '''
                        . venv/bin/activate

                        # Get changed files
                        git diff --name-only ${CHANGE_TARGET}...HEAD > changed_files.txt

                        # Run impact analysis
                        tracertm impact analyze --files changed_files.txt --format json > impact.json

                        # Display results
                        cat impact.json | jq '.'
                    '''
                }
            }
        }

        stage('Generate Reports') {
            steps {
                script {
                    sh """
                        . venv/bin/activate

                        # Coverage report
                        tracertm report coverage --format ${params.REPORT_FORMAT} > traceability-coverage.${params.REPORT_FORMAT}

                        # Traceability matrix
                        tracertm report matrix --format html > traceability-matrix.html

                        # Gap analysis
                        tracertm report gaps --format html > coverage-gaps.html

                        # Full export
                        tracertm export --format json > traceability-export.json
                    """
                }
            }
        }

        stage('Archive & Publish') {
            steps {
                archiveArtifacts artifacts: '*.html,*.json,*.pdf', allowEmptyArchive: true
                publishHTML([
                    allowMissing: false,
                    alwaysLinkToLastBuild: true,
                    keepAll: true,
                    reportDir: '.',
                    reportFiles: 'traceability-coverage.html',
                    reportName: 'Traceability Report'
                ])
            }
        }

        stage('Quality Gate') {
            steps {
                script {
                    def coverage = sh(
                        script: '. venv/bin/activate && jq -r .overall_coverage coverage.json',
                        returnStdout: true
                    ).trim()

                    if (coverage.toFloat() < env.COVERAGE_THRESHOLD.toFloat()) {
                        if (params.STRICT_MODE) {
                            error("Coverage ${coverage}% is below threshold ${env.COVERAGE_THRESHOLD}%")
                        } else {
                            unstable("Coverage ${coverage}% is below threshold ${env.COVERAGE_THRESHOLD}%")
                        }
                    }
                }
            }
        }
    }

    post {
        always {
            cleanWs()
        }
        success {
            script {
                if (env.CHANGE_ID) {
                    // Post success comment to PR
                    def coverage = sh(
                        script: '. venv/bin/activate && jq -r .overall_coverage coverage.json',
                        returnStdout: true
                    ).trim()

                    pullRequest.comment("✅ Traceability validation passed! Coverage: ${coverage}%")
                }
            }
        }
        failure {
            script {
                if (env.CHANGE_ID) {
                    pullRequest.comment("❌ Traceability validation failed. Check the build logs for details.")
                }
            }
        }
    }
}
```

## Azure DevOps Pipeline

Create `azure-pipelines.yml`:

```yaml
trigger:
  branches:
    include:
      - main
      - develop
  paths:
    include:
      - requirements/*
      - tests/*
      - src/*

pr:
  branches:
    include:
      - main
      - develop

schedules:
  - cron: "0 9 * * *"
    displayName: Daily compliance report
    branches:
      include:
        - main

variables:
  TRACERTM_VERSION: '1.0.0'
  COVERAGE_THRESHOLD: 80

stages:
  - stage: Validate
    displayName: 'Validate Traceability'
    jobs:
      - job: ValidateCoverage
        displayName: 'Check Coverage'
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - task: UsePythonVersion@0
            inputs:
              versionSpec: '3.11'
            displayName: 'Use Python 3.11'

          - script: |
              pip install tracertm==$(TRACERTM_VERSION)
              tracertm --version
            displayName: 'Install TraceRTM'

          - script: |
              tracertm sync requirements ./requirements
              tracertm sync tests ./tests
            displayName: 'Sync Items'

          - script: |
              tracertm report coverage --format json > $(Build.ArtifactStagingDirectory)/coverage.json
              COVERAGE=$(jq -r '.overall_coverage' $(Build.ArtifactStagingDirectory)/coverage.json)
              echo "##vso[task.setvariable variable=COVERAGE]$COVERAGE"

              if (( $(echo "$COVERAGE < $(COVERAGE_THRESHOLD)" | bc -l) )); then
                echo "##vso[task.logissue type=error]Coverage $COVERAGE% below threshold $(COVERAGE_THRESHOLD)%"
                exit 1
              fi
            displayName: 'Check Coverage Threshold'

          - script: |
              tracertm validate links --strict
            displayName: 'Validate Links'

          - task: PublishBuildArtifacts@1
            inputs:
              pathToPublish: '$(Build.ArtifactStagingDirectory)'
              artifactName: 'traceability-reports'
            displayName: 'Publish Reports'

  - stage: Report
    displayName: 'Generate Reports'
    dependsOn: Validate
    condition: succeeded()
    jobs:
      - job: GenerateReports
        displayName: 'Create Reports'
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - task: UsePythonVersion@0
            inputs:
              versionSpec: '3.11'

          - script: |
              pip install tracertm==$(TRACERTM_VERSION)
            displayName: 'Install TraceRTM'

          - script: |
              tracertm report coverage --format html > $(Build.ArtifactStagingDirectory)/coverage.html
              tracertm report matrix --format html > $(Build.ArtifactStagingDirectory)/matrix.html
            displayName: 'Generate HTML Reports'

          - task: PublishBuildArtifacts@1
            inputs:
              pathToPublish: '$(Build.ArtifactStagingDirectory)'
              artifactName: 'compliance-reports'
```

## Notification Integration

### Slack Notifications

Add to your GitHub Actions workflow:

```yaml
- name: Notify Slack
  if: always()
  uses: slackapi/slack-github-action@v1
  with:
    payload: |
      {
        "text": "Traceability Check: ${{ job.status }}",
        "blocks": [
          {
            "type": "section",
            "text": {
              "type": "mrkdwn",
              "text": "*Traceability Validation*\n*Repository*: ${{ github.repository }}\n*Branch*: ${{ github.ref_name }}\n*Coverage*: ${{ steps.coverage.outputs.coverage }}%\n*Status*: ${{ job.status }}"
            }
          }
        ]
      }
  env:
    SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
```

### Email Notifications

Add to Jenkins pipeline:

```groovy
post {
    always {
        emailext(
            subject: "Traceability Report: ${currentBuild.fullDisplayName}",
            body: """
                <h2>Traceability Validation Results</h2>
                <p><strong>Build:</strong> ${env.BUILD_NUMBER}</p>
                <p><strong>Status:</strong> ${currentBuild.result}</p>
                <p><strong>Coverage:</strong> ${coverage}%</p>
                <p><a href="${env.BUILD_URL}Traceability_Report">View Full Report</a></p>
            """,
            to: "${env.TEAM_EMAIL}",
            attachmentsPattern: 'traceability-coverage.html'
        )
    }
}
```

## Best Practices

### 1. Coverage Thresholds

Set appropriate thresholds based on project phase:

```yaml
# Early development
COVERAGE_THRESHOLD: 60

# Feature complete
COVERAGE_THRESHOLD: 80

# Release candidate
COVERAGE_THRESHOLD: 95

# Safety-critical systems
COVERAGE_THRESHOLD: 100
```

### 2. Incremental Validation

Only validate changed items on pull requests:

```bash
# Get changed requirements
git diff --name-only origin/main...HEAD | grep "requirements/" > changed_items.txt

# Validate only changed items
tracertm validate links --items-from changed_items.txt
```

### 3. Parallel Execution

Speed up validation with parallel jobs:

```yaml
jobs:
  validate:
    strategy:
      matrix:
        component: [requirements, tests, code, documentation]
    steps:
      - run: tracertm sync ${{ matrix.component }} ./${{ matrix.component }}
```

### 4. Cache Configuration

Cache TraceRTM data between runs:

```yaml
- name: Cache TraceRTM
  uses: actions/cache@v3
  with:
    path: .tracertm/
    key: tracertm-${{ hashFiles('requirements/**', 'tests/**') }}
```

### 5. Quality Gates

Implement progressive quality gates:

```yaml
stages:
  - name: Validate Coverage
    run: tracertm validate coverage --threshold 80

  - name: Validate Links
    run: tracertm validate links --strict

  - name: Check Orphans
    run: tracertm query orphans --fail-if-found

  - name: Validate Consistency
    run: tracertm validate consistency --strict
```

### 6. Report Retention

Configure appropriate retention for compliance:

```yaml
artifacts:
  reports:
    expire_in:
      # Development builds
      - 7 days (feature branches)
      # Release builds
      - 2 years (main branch)
      # Compliance audits
      - 7 years (release tags)
```

### 7. Security Considerations

Protect sensitive traceability data:

```yaml
# Use encrypted secrets for API tokens
env:
  TRACERTM_API_TOKEN: ${{ secrets.TRACERTM_API_TOKEN }}

# Restrict artifact access
artifacts:
  access_level: private

# Use read-only permissions where possible
permissions:
  contents: read
  pull-requests: write
```

## Troubleshooting

### Common Issues

**Issue**: Coverage check fails intermittently

```bash
# Solution: Use explicit sync before validation
tracertm sync all --force
tracertm report coverage
```

**Issue**: Large repositories timeout

```bash
# Solution: Use incremental sync
tracertm sync requirements --incremental
tracertm sync tests --changed-since last-build
```

**Issue**: Reports missing data

```bash
# Solution: Verify all items are synced
tracertm status --verbose
tracertm validate consistency
```

## Next Steps

- [Configure Pre-commit Hooks](/docs/development/git-integration)
- [Set Up Automated Reporting](/docs/user/reports)
- [Integrate with Jira](/docs/integrations/jira)
- [API Reference](/docs/api/cli-reference)
