Bitbucket repositoty status badges!

In the picture: Nice looking badges at the top of a Bitbucket repository (by the author)

Part 1: Just using this solution

Getting the files

  1. Download the bitbucket-pipelines.yml and status_badge.sh files found in this Github gist and add them to your repository:
    https://gist.github.com/shaypal5/064dd0254a9f32c7549f8d42c26fef90
  2. Create a ci folder at the root of your repository and move the status_badge.sh file there. The bitbucket-pipelines.yml should stay at the root of the repository

Dependecy installation

If your project is essentially a Python package which you install and then test, and you also manage extra_requires test dependecies, then add the following two dependecies to your extra_requires: {'test': …} of your setup.py : pybadges, coverage-badge

Coverage report

This method assumes you run your tests in some way that generate a .coverage report file, which is what the coverage-badge package uses to find out what is your test coverage and generate the badge with.

Setup the required Pipelines variables

Follows steps 1 and 2 here for your repository to populate the BITBUCKET_USERNAME and BITBUCKET_APP_PASSWORD variables:

Updating your README file to show the badges

I use a README.rst file (using the RestructuredText format), so this is how the top of my readme file looks, for a repository named my-project in an organization name myorg .

my-project
##########
|Build-Status| |Coverage|.. |Build-Status| image:: https://bitbucket.org/myorg/my-project/downloads/status.svg
:target: https://bitbucket.org/myorg/my-project/addon/pipelines/home#!/
.. |Coverage| image:: https://bitbucket.org/myorg/my-project/downloads/coverage.svg
:target: https://bitbucket.org/myorg/my-project/addon/pipelines/home#!/
# my-project[![Build-Status](https://bitbucket.org/myorg/my-project/downloads/status.svg)](https://bitbucket.org/myorg/my-project/addon/pipelines/home#!/)
[![Coverage](https://bitbucket.org/myorg/my-project/downloads/coverage.svg)](https://bitbucket.org/myorg/my-project/addon/pipelines/home#!/)

Part 2: Understanding how it works

The required files

The solution is made up of several parts:

  1. bitbucket-pipelines.yml — This is the configuration file for Bitbucket’s CI/CD component, much like Github Actions or independent ones like Travis or Circle CI. Most of the logic goes here.
  2. status_badge.sh — A script generating the appropriate status and coverage badges. I placed this in a directory named ci in the root of my repository.
  3. README.rst (or README.md ) — Here you just reference the right urls for the generated badges.
  4. pytest.ini or arguments you provide to the pytest command — Not really a part of the solution, but the script assumes your testing phase generates a coverage report.

The overall structure

Since most of the work is done through the different steps configured by the bitbucket-pipelines.yml file, let’s start by going over the file, and the short status_badge.sh script it uses:

pipelines:
default:
- <<: *test
branches:
master:
- <<: *test
- <<: *upload-status-badge
- <<: *upload-coverage-badge
- <<: *build-status
  1. Run the test phase, which will run all tests AND generate appropriate status.svg and coverage.svg files AND will save them (and the exit code returned by the pytest command) using the Bitbucket Pipelines artifacts mechanism.
  2. Upload the status badge to the Downloads section of your repository.
  3. Upload the coverage badge to the Downloads section of your repository.
  4. Run a step that will simply exit with the previously-stored exit value returned by pytest. This will make sure the build will fail if pytest fails, but will pass if everything goes fine.
  • The easiest way, at the moment, to upload Bitbucket Pipelines build artifacts to the corresponding repository’s Downloads store/section is using the official bitbucket-upload-file docker/step (see here for details).
  • Bitbucket Pipelines does not, at the moment, support running pipeline steps after a step has failed. As a result, and since upload is done by separate steps, we can’t have the test step — and thus the pytest command — fail, and so we have to add a final step just to make the overall build status correspond to test results. Not very elegant, but it’s the best I could think of.

Dependencies & assumptions

The python code used here has several Python package dependencies:

  • pytest runs the tests.
  • coverage and pytest-cov produce coverage reports on pytest runs
  • pybadges generates the build status badge.
  • coverage-badge generates the coverage badge.

Sources

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store