GitLab CI/CD: Architecting, Deploying, and Optimizing Pipelines

Continuous Integration with GitLab

Pipeline Configure Coverage and Archive Reports

In this guide, you’ll learn how to set up a parallel code coverage job alongside unit tests in GitLab CI/CD, archive reports, and surface coverage metrics in the UI.

Base Unit Testing Job

This unit_testing job runs in the test stage, installs dependencies, executes tests, and collects JUnit reports:

stages:
  - test

variables:
  MONGO_URI: 'mongodb+srv://superCluster.d83jj.mongodb.net/superData'
  MONGO_USERNAME: superuser
  MONGO_PASSWORD: $M_DB_PASSWORD

unit_testing:
  stage: test
  image: node:17-alpine3.14
  before_script:
    - npm install
  script:
    - npm test
  artifacts:
    when: always
    expire_in: 3 days
    name: Moca-Test-Result
    paths:
      - test-results.xml
  reports:
    junit: test-results.xml

Adding a Parallel Code Coverage Job

Create a code_coverage job that reuses the Node.js image and installs dependencies. The npm run coverage command (powered by NYC) generates a Cobertura XML report.

code_coverage:
  stage: test
  image: node:17-alpine3.14
  before_script:
    - npm install
  script:
    - npm run coverage
  artifacts:
    name: Code-Coverage-Result
    when: always
    expire_in: 3 days
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coverage/cobertura-coverage.xml
  coverage: '/All files[^|]*\|[^|]*\s+([0-9.]+)%/'

Supported Artifact Report Types

GitLab CI/CD supports multiple report formats under artifacts:reports. Use the table below to choose the appropriate type:

Report TypeDescriptionExample
junitJUnit XML test reportsreports:\n junit: test-results.xml
coverage_reportCobertura coverage resultsreports:\n coverage_report:\n coverage_format: cobertura\n path: coverage/cobertura-coverage.xml
codequalityStatic code analysis (Code Quality)reports:\n codequality: gl-code-quality-report.json
dependency_scanningDependency vulnerability reportreports:\n dependency_scanning: gl-dependency-scanning-report.json

The image shows a GitLab documentation page about CI/CD artifact report types, detailing how to use `artifacts:reports` for collecting various reports in jobs. The page includes a sidebar with navigation links and a list of report types on the right.

Coverage Report Configuration

To enable GitLab’s built-in coverage display, specify the Cobertura format and the XML path in artifacts:reports:

artifacts:
  reports:
    coverage_report:
      coverage_format: cobertura
      path: coverage/cobertura-coverage.xml

Extracting Coverage Percentage

GitLab can parse test logs and extract a coverage percentage using a regular expression. For NYC’s “All files” summary line, use:

coverage: '/All files[^|]*\|[^|]*\s+([0-9.]+)%/'

Note

Make sure your coverage tool prints a summary line matching this pattern. Adjust the regex if your output differs.

The image shows a GitLab documentation page detailing test coverage examples with regex patterns for various programming languages and tools. The sidebar includes navigation links related to code coverage and testing.

Full CI Configuration with a Dependent Sample Job

Combine both jobs and add a sample-job that depends on code_coverage. This ensures downstream work only runs if coverage passes (or you enable allow_failure).

stages:
  - test

variables:
  MONGO_URI: 'mongodb+srv://superCluster.d83jj.mongodb.net/superData'
  MONGO_USERNAME: superuser
  MONGO_PASSWORD: $M_DB_PASSWORD

unit_testing:
  stage: test
  image: node:17-alpine3.14
  before_script:
    - npm install
  script:
    - npm test
  artifacts:
    when: always
    expire_in: 3 days
    name: Moca-Test-Result
    paths:
      - test-results.xml
  reports:
    junit: test-results.xml

code_coverage:
  stage: test
  image: node:17-alpine3.14
  before_script:
    - npm install
  script:
    - npm run coverage
  artifacts:
    name: Code-Coverage-Result
    when: always
    expire_in: 3 days
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coverage/cobertura-coverage.xml
  coverage: '/All files[^|]*\|[^|]*\s+([0-9.]+)%/'

sample-job:
  stage: test
  needs:
    - code_coverage
  image: node:17-alpine3.14
  script:
    - echo "Running sample job"

Once you push this .gitlab-ci.yml, the GitLab pipeline graph clearly shows unit_testing, code_coverage, and sample-job in parallel:

The image shows a GitLab Pipeline Editor interface with a successful pipeline status and a visualization of jobs including "unit_testing," "code_coverage," and "sample-job."

Pipeline Execution and Coverage Failure

If the coverage threshold defined in your package.json isn’t met, the code_coverage job fails and downstream jobs are skipped by default.

Warning

A failed coverage check will block any jobs that depend on it. To continue the pipeline regardless of coverage, you can set allow_failure: true on the coverage job.

The image shows a GitLab CI/CD pipeline interface for a NodeJS project named "Solar System," where a job named "code_coverage" has failed, while "unit_testing" has succeeded.

Example logs from NYC:

> nyc --reporter cobertura --reporter lcov --reporter text --reporter json-summary mocha app-test.js --timeout 10000 --exit
...
ERROR: Coverage for lines (88.88%) does not meet global threshold (90%)
| File       | % Branch | % Funcs | % Lines | Uncovered Line #s |
|------------|----------|---------|---------|-------------------|
| All files  | 88.88    | 50      | 87.50   | 88.88             |

Your package.json might include:

{
  "scripts": {
    "coverage": "nyc --reporter cobertura --reporter lcov --reporter text --reporter json-summary mocha app-test.js"
  },
  "nyc": {
    "check-coverage": true,
    "lines": 90
  }
}

Coverage Percentage in the GitLab UI

With the coverage regex in place, GitLab extracts the percentage (e.g., 88.88%) and displays it in the pipeline view:

The image shows a GitLab pipeline interface for a NodeJS project, indicating a failed pipeline with 11 tests, all of which passed successfully.

In this scenario, coverage is below the 90% threshold, causing code_coverage to fail and skipping sample-job:

The image shows a GitLab CI/CD pipeline interface for a NodeJS project named "Solar System," displaying job statuses including one failed, one passed, and one skipped job. The "code_coverage" job has a coverage percentage of 88.88%.


Next, we’ll look at strategies to allow selective failures and continue pipeline execution even when coverage checks fail.

Watch Video

Watch video content

Previous
Artifacts Unit Test Reports