Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.qlty.sh/llms.txt

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

When running tests inside Docker containers, you need to extract coverage data from the container to upload it to Qlty. This guide covers two common approaches: using volume mounts and using docker cp.

Method 1: Volume Mounting

Volume mounting is the simplest approach where you mount your project directory into the container, allowing coverage files to be written directly to your host filesystem.

GitHub Actions Example

name: Main
on:
    push:
        branches: [main]
    pull_request:

permissions:
    contents: read
    id-token: write

jobs:
    test:
        runs-on: ubuntu-latest
        steps:
            - name: Checkout repo
              uses: actions/checkout@v4

            - name: Set up Docker Buildx
              uses: docker/setup-buildx-action@v3

            - name: Build Docker image
              run: docker build -t myapp-test .

            - name: Run tests in Docker
              run: |
                  docker run --rm \
                    -v "$(pwd)":/app \
                    -w /app \
                    myapp-test \
                    npm test -- --coverage

            - name: Check coverage file exists
              run: test -f coverage/lcov.info

            - name: Upload coverage to Qlty
              uses: qltysh/qlty-action/coverage@v2
              with:
                  oidc: true
                  files: coverage/lcov.info

Key Points for Volume Mounting

  • Mount your current directory ($(pwd)) to the container’s working directory
  • Use --rm to automatically remove the container after tests complete
  • Coverage files are written directly to your host filesystem
  • Works with any coverage format supported by Qlty

Method 2: Docker Copy

When you can’t use volume mounts (due to security restrictions or container design), you can copy coverage files out of the container after tests complete.

GitHub Actions Example

name: Main
on:
    push:
        branches: [main]
    pull_request:

permissions:
    contents: read
    id-token: write

jobs:
    test:
        runs-on: ubuntu-latest
        steps:
            - name: Checkout repo
              uses: actions/checkout@v4

            - name: Set up Docker Buildx
              uses: docker/setup-buildx-action@v3

            - name: Build Docker image
              run: docker build -t myapp-test .

            - name: Run tests in Docker (retain container)
              run: |
                  docker run --name test-container \
                    -w /app \
                    myapp-test \
                    npm test -- --coverage

            - name: Copy coverage files out of container
              run: |
                  docker cp test-container:/app/coverage/lcov.info coverage.lcov

            - name: Cleanup container
              run: docker rm test-container

            - name: Check coverage file exists
              run: test -f coverage.lcov

            - name: Upload coverage to Qlty
              uses: qltysh/qlty-action/coverage@v2
              with:
                  oidc: true
                  files: coverage.lcov

Key Points for Docker Copy

  • Don’t use --rm flag so the container persists after tests
  • Use --name to give the container a predictable name
  • Copy files using docker cp container_name:/path/to/file destination
  • Clean up the container manually after copying files

Alternative CI Providers

Using Coverage Tokens

If you’re not using GitHub Actions with OIDC, replace the upload step with a coverage token:
- name: Upload coverage to Qlty
  uses: qltysh/qlty-action/coverage@v2
  with:
      token: ${{ secrets.QLTY_COVERAGE_TOKEN }}
      files: coverage/lcov.info

Manual CLI Upload

For other CI providers, install the Qlty CLI and upload manually:
# After extracting coverage files from Docker
curl https://qlty.sh | sh
qlty coverage publish coverage/lcov.info
For some CI providers you may have to add --override-commit-sha and --override-branch flags with commit SHA and branch names.
# After extracting coverage files from Docker
curl https://qlty.sh | sh
qlty coverage publish coverage/lcov.info --override-commit-sha <COMMIT_SHA> --override-branch <BRANCH_NAME>

Multiple Coverage Files

If your Docker container generates multiple coverage files, you can upload them all:

Volume Mount Approach

- name: Upload coverage to Qlty
  uses: qltysh/qlty-action/coverage@v2
  with:
      oidc: true
      files: |
          coverage/unit.lcov
          coverage/integration.lcov

Docker Copy Approach

- name: Copy multiple coverage files
  run: |
    docker cp test-container:/app/coverage/unit.lcov unit.lcov
    docker cp test-container:/app/coverage/integration.lcov integration.lcov

Path Fixing

When running tests in Docker, file paths in coverage reports might not match your repository structure. Use path fixing options:
- name: Upload coverage to Qlty
  uses: qltysh/qlty-action/coverage@v2
  with:
      oidc: true
      files: coverage/lcov.info
      strip-prefix: /app/
Or with the CLI:
qlty coverage publish --strip-prefix=/app/ coverage/lcov.info

Troubleshooting

Coverage File Not Found

  • Ensure your test command actually generates coverage files
  • Check that the coverage output directory matches your copy/mount paths
  • Verify file permissions allow reading from the container

Path Mismatches

  • Use --strip-prefix to remove container-specific path prefixes
  • Use --add-prefix if you need to add a path prefix
  • Check that source paths in coverage reports match your repository structure

Container Cleanup Issues

  • Always clean up named containers when using docker cp
  • Use docker rm -f container_name to force removal if needed
  • Consider using --rm with volume mounts to avoid cleanup

See Also