keelapps Coverage for Bitbucket

keelapps/Coverage for Bitbucket/Documentation

Documentation

Coverage for Bitbucket shows line coverage, the coverage of the lines a pull request changed, and every test result on the Bitbucket Cloud pull request. A pipe in your pipeline writes the results onto the commit; the app reads them and shows them to reviewers. Nothing leaves Bitbucket.

How it works

Setting it up

  1. As a workspace administrator, install Coverage for Bitbucket on your workspace. Atlassian's install page asks which workspace.
  2. In bitbucket-pipelines.yml, add the pipe to the after-script of the step that runs your tests:
- step:
    name: Test
    script:
      - pytest --junitxml=test-results/junit.xml --cov=app --cov-report=xml:coverage.xml
    after-script:
      - pipe: docker://ghcr.io/keelapps/coverage-for-bitbucket:1
        variables:
          COVERAGE_FILE: coverage.xml
          MIN_CHANGED_COVERAGE: '80'
          MAX_DROP: '1'

Use after-script, not script: a failing test stops the script, and the pull request should still show which test failed.

Open a pull request, or push to one. When the pipeline finishes, the results are on the pull request. Workspace settings → Coverage for Bitbucket shows the same steps.

Pipe variables

VariableWhat it does
COVERAGE_FILEthe coverage file: a path, a glob, or several separated by commas. Needed for the coverage report.
TEST_RESULTSJUnit XML files. By default the folders Pipelines itself scans: test-results, test-reports, surefire-reports, failsafe-reports and TestResults. none skips the test report.
COVERAGE_FORMATcobertura, jacoco, lcov or go. Detected from the file when unset.
MIN_COVERAGEthe coverage report fails below this line coverage, in percent
MIN_CHANGED_COVERAGEthe coverage report fails below this coverage of the changed lines, in percent
MAX_DROPthe merge check fails when coverage drops more than this many points against the target branch
DIFF_BASEthe branch or commit to compare with. By default the pull request's destination in pull-request pipelines, otherwise main, then master.
REPORT_LINKa URL the coverage report links to, such as an HTML coverage report you publish
FAIL_STEPtrue also fails the pipeline step when the coverage report fails
DRY_RUNtrue prints the reports instead of sending them

A threshold you leave out is not checked. With no thresholds at all the report shows the numbers and always passes.

Coverage formats

FormatWritten by, for example
Cobertura XMLcoverage.py and pytest-cov (--cov-report=xml), gcovr, Istanbul and nyc (cobertura reporter), coverlet
JaCoCo XMLthe JaCoCo Maven and Gradle plugins, Kover
LCOVIstanbul, c8 and Vitest (lcov reporter), lcov for C and C++, Flutter
Go coverprofilego test -coverprofile=cover.out

Paths in the coverage file are matched to the files in your repository, so reports that name files relative to a source folder or by Go module path still line up with the diff. Several coverage files are merged into one report.

Test results

The pipe reads JUnit XML, the format almost every test runner can write, and lists every test case in the Tests report: failed ones first, then skipped, then passed, each with what it printed. Bitbucket Pipelines also collects JUnit XML itself, but its API lists failed cases only. When a commit has no Tests report, the panel falls back to the counts Pipelines collected and the failed cases it lists.

On the pull request

The change against the target branch compares the pull request with the coverage report on the target branch's latest commit, or on one of the five commits before it when the latest has none yet. Run the pipe on your main branch too, so there is something to compare with.

The panel reads as the person viewing it, so Bitbucket's own repository permissions apply: someone who cannot see the repository sees nothing.

The merge check

Custom merge checks are off in a new workspace. A workspace administrator turns them on once, in Workspace settings → Custom merge checks → Enable. Then, in Repository settings → Custom merge checks, add Coverage meets the bar. It checks the pull request's source commit when someone pushes to it, when a reviewer approves or asks for changes, and again at merge. It fails when:

Its message says which, with the numbers. On Bitbucket Premium, tick required to block the merge until the check passes; on other plans the result is shown on the pull request but does not block it. Premium also lets you turn the check on for a whole workspace or project. Turn it on only where the pipeline runs the pipe, since a commit without a report fails it.

Right after a push the pipeline is usually still running, so the first result says there is no report yet. Bitbucket checks again when a reviewer approves, and you can press Rerun on the check once the pipeline has finished.

Outside Bitbucket Pipelines

The pipe is a container image, so another CI can run it against a Bitbucket Cloud repository. Set BITBUCKET_REPO_FULL_NAME (workspace/repository), BITBUCKET_COMMIT, and BITBUCKET_ACCESS_TOKEN: a repository access token with Pull requests: Write. Run it in a full clone, so it can compare with the target branch.

Limits

Permissions the app requests

ScopeWhy
read:pullrequest:bitbucketa pull request's source and destination commits and branches
read:repository:bitbucketthe Coverage and Tests reports and their annotations on a commit, and the target branch's recent commits for the comparison
read:pipeline:bitbucketthe test counts and failed cases Pipelines collected, when a commit has no Tests report

The app has no write scope and no storage, and there is no permissions.external block: it cannot make an outbound call, which Atlassian enforces at the platform level. The reports are written by the pipe in your own pipeline, not by the app.

Support

Questions, bug reports and feature requests: raise a support request. Security issues: report privately.