The Concourse Continuous Integration (CI) server has an API endpoint that displays a badge which shows health of your project:

http(s)://concourse-server/api/v1/pipelines/pipeline-name/jobs/job-name/badge

0. Abstract

Open Source projects that have CI (e.g. Bootstrap, Node.js) often feature status badges (also known as images or icons) to display the health of their projects. CI servers such as Travis CI offer status badges. Concourse CI also offers status badges.

The status badge is a Scalable Vector Graphics (SVG) image available from the Concourse API. [Concourse versions]

1. Real World Example

The sslip.io project has a Concourse CI pipeline consisting of one job.

The pipeline is sslip.io (same name as the project, a simple naming scheme), and the job’s name is check-dns.

In the project’s [README.md] (https://github.com/cunnie/sslip.io/blob/276311f219882c2d7228d271109f21c6e7b0698a/README.md), the following line displays the status badge and links to the Concourse server’s pipeline:

[![ci.nono.io](https://ci.nono.io/api/v1/pipelines/sslip.io/jobs/check-dns/badge)](https://ci.nono.io/?groups=sslip.io)

2. It’s at the Job Level, not the Pipeline Level

The badges display at the job level, which leads to a conundrum: which job best represents the health of the project?

Let’s assume a simple pipeline with two jobs: unit and integration. The integration job is only run if the unit job has succeeded.

A reasonable choice to represent the health of the project would be the integration job, but there is a problem: The integration job’s badge might show “passing” (that the code is good) when the unit tests have failed (see figure below). The badge would show the build as passing when in reality the build has failed:

Similarly with choosing the unit job to represent the health of the project: the unit job may have passed but the integration job may have failed. Again, the badge would show the build as passing when the build has failed.

One way to address this would be to display several badges, one for each job — Bootstrap has demonstrated that it’s reasonable to have more than one badge on a project’s page. [Bootstrap badges]

For example:

JobStatus
unit
integration

This begs the question: why not have badges at the pipeline level and not at the job level? The short answer is this: Concourse’s jobs have a status, but the pipelines don’t. The pipelines weren’t designed to have a status, and thus implementing a badge at the pipeline level is not a trivial task.

3. The Five Types of Badges

BadgeSignificance
ci.nono.ioThe most recent run of the job passed — you want this.
ci.nono.ioThe most recent run of the job failed. There is probably a bug in your code.
ci.nono.ioYou aborted the most recent run of the job; maybe it was stuck.
ci.nono.ioThe job has never been run.
ci.nono.ioConcourse ran into an error and couldn’t complete the job.

Acknowledgements

Chris Brown wrote much of the code during his lunch hour. Kris Hicks shepherded the pull request through the acceptance process, refashioning the code along the way. He also reviewed this post. Any excellence is theirs, gnarliness, mine.

shields.io was used to generate the initial badges.


Assets

A pipeline that displays all five types of badges, and its YAML.

A pipeline that has two jobs (unit and integration), and its YAML.

Footnotes

[Concourse versions]The badge API endpoint was added in Concourse v1.3.0.

The badge API endpoint was changed briefly in v2.0.0 and then reverted in v2.0.1.

If your server is v2.0.0, this is the API endpoint:

http(s)://concourse-server/api/v1/teams/main/pipelines/pipeline-name/jobs/job-name/badge

[Bootstrap badges]An open source developer once remarked, “Bootstrap’s project page has more badges than a Third World General!”

We’d like to commend the Bootstrap developers for their commitment to CI, cross-platform compatibility, and just about everything that makes an open source project successful — they’ve set a high bar to which all of us aspire.