buildkite-agent annotate

The Buildkite Agent’s annotate command allows you to add additional information to Buildkite build pages using CommonMark Markdown.

Screenshot of annotations with test reports

Creating an annotation

The buildkite-agent annotate command creates an annotation associated with the current build.

There is no limit to the amount of annotations you can create. All annotations can be retrieved using the GraphQL API.

Options for the annotate command can be found in the buildkite-agent cli help:


buildkite-agent annotate [body] [options...]


Build annotations allow you to customize the Buildkite build interface to show information that may surface from your builds. Some examples include:

  • Links to artifacts generated by your jobs
  • Test result summaries
  • Graphs that include analysis about your codebase
  • Helpful information for team members about what happened during a build

Annotations are written in CommonMark-compliant Markdown, with "GitHub Flavored Markdown" extensions.

The annotation body can be supplied as a command line argument, or by piping content into the command.

You can update an existing annotation's body by running the annotate command again and provide the same context as the one you want to update. Or if you leave context blank, it will use the default context.

You can also update only the style of an existing annotation by omitting the body entirely and providing a new style value.


$ buildkite-agent annotate "All tests passed! 🚀"
$ cat | buildkite-agent annotate --style "warning"
$ buildkite-agent annotate --style "success" --context "junit"
$ ./script/dynamic_annotation_generator | buildkite-agent annotate --style "success"


--context value #

The context of the annotation used to differentiate this annotation from others

--style success #

The style of the annotation (success, `info`, `warning` or `error`)

--append #

Append to the body of an existing annotation

--job value #

Which job should the annotation come from
Environment variable: $BUILDKITE_JOB_ID

--agent-access-token value #

The access token used to identify the agent

--endpoint value #

The Agent API endpoint (default: "")
Environment variable: $BUILDKITE_AGENT_ENDPOINT

--no-http2 #

Disable HTTP2 when communicating with the Agent API.
Environment variable: $BUILDKITE_NO_HTTP2

--debug-http #

Enable HTTP debug mode, which dumps all request and response bodies to the log
Environment variable: $BUILDKITE_AGENT_DEBUG_HTTP

--no-color #

Don't show colors in logging
Environment variable: $BUILDKITE_AGENT_NO_COLOR

--debug #

Enable debug mode
Environment variable: $BUILDKITE_AGENT_DEBUG

--experiment value #

Enable experimental features within the buildkite-agent

--profile value #

Enable a profiling mode, either cpu, memory, mutex or block
Environment variable: $BUILDKITE_AGENT_PROFILE

Removing an annotation

Annotations can be removed using the buildkite-agent annotation remove command.

Annotation styles

You can change the visual style of annotations using the --style option.

This is an example pipeline showcasing the different styles of annotations:

  - label: ":console: Annotation Test"
    command: |
      buildkite-agent annotate 'Example `default` style' --context 'ctx-default'
      buildkite-agent annotate 'Example `info` style' --style 'info' --context 'ctx-info'
      buildkite-agent annotate 'Example `warning` style' --style 'warning' --context 'ctx-warn'
      buildkite-agent annotate 'Example `error` style' --style 'error' --context 'ctx-error'
      buildkite-agent annotate 'Example `success` style' --style 'success' --context 'ctx-success'

Screenshot of available annotation styles

Supported Markdown syntax

We use CommonMark with GitHub Flavored Markdown extensions to provide consistent, unambiguous Markdown syntax.

GitHub kindly provides a guide to this syntax.

Annotations do not support GitHub-style syntax highlighting, task lists, user mentions, or automatic links for references to issues, pull requests or commits.

CommonMark supports HTML inside Markdown blocks, but will revert to Markdown parsing on newlines. For more information about how HTML is parsed and which tags CommonMark supports please refer to the CommonMark spec.

Supported CSS Classes

A number of CSS classes are accepted in annotations. These include a subset of layout and formatting controls based on Basscss, and colored console output.


Basscss is a toolkit of composable CSS classes which can be combined to accomplish many styling tasks. We accept the following parts of version 8.0 of Basscss within annotations:

An exhaustive list of classes that annotations support can be found below:

bold regular italic caps underline
left-align center right-align justify
align-baseline align-top align-middle align-bottom
list-reset truncate fit

inline block inline-block table table-cell
overflow-hidden overflow-scroll overflow-auto

ml-auto mr-auto mx-auto
flex flex-column flex-wrap flex-auto flex-none
items-start items-end items-center items-baseline items-stretch
self-start self-end self-center self-baseline self-stretch
justify-start justify-end justify-center justify-between justify-around
content-start content-end content-center content-between content-around content-stretch
order-0 order-1 order-2 order-3 order-last

border border-top border-right border-bottom border-left border-none rounded

h1 h2 h3 h4 h5 h6

m0 mt0 mr0 mb0 ml0 mx0 my0 m1
mt1 mr1 mb1 ml1 mx1 my1
m2 mt2 mr2 mb2 ml2 mx2 my2
m3 mt3 mr3 mb3 ml3 mx3 my3
m4 mt4 mr4 mb4 ml4 mx4 my4
mxn1 mxn2 mxn3 mxn4

p0 pt0 pr0 pb0 pl0 px0 py0
p1 pt1 pr1 pb1 pl1 py1 px1
p2 pt2 pr2 pb2 pl2 py2 px2
p3 pt3 pr3 pb3 pl3 py3 px3
p4 pt4 pr4 pb4 pl4 py4 px4

Colored console output

Console output in annotations can be displayed with ANSI colors when wrapped in a Markdown block marked as term or terminal syntax.

\x1b[31mFailure/Error:\x1b[0m \x1b[32mexpect\x1b[0m(new_item.created_at).to eql(now)

\x1b[31m  expected: 2018-06-20 19:42:26.290538462 +0000\x1b[0m
\x1b[31m       got: 2018-06-20 19:42:26.290538000 +0000\x1b[0m

\x1b[31m  (compared using eql?)\x1b[0m

Screenshot of colored terminal output in an annotation

Make sure you escape the backticks (`) that demarcate the code block if you're echoing to the terminal, so it doesn't get interpreted as a shell interpreted command.

The following pipeline prints an escaped Markdown block, adds line breaks using \n and formats test using the red ANSI code \033[0;31m before resetting the remainder of the output with \033[0m. Passing -e to the echo commands ensures that the backslash escapes codes are interpreted (the default is not to interpret them).

  - label: "Annotation Test"
      - echo -e "\`\`\`term\nThis is a \033[0;31mtest\033[0m\n\`\`\`" | buildkite-agent annotate

The results are piped though to the buildkite-agent annotate command:

Screenshot of colored terminal output in an annotation

Or for more complex annotations, pipe an entire file to the buildkite-agent annotate command:

printf '%b\n' "$(cat" | buildkite-agent annotate

If you're using our terminal to HTML tool, wrap the output in <pre class="term"><code></code></pre> tags, so it displays the terminal colour styles but won't process it again:

<pre class="term">
    terminal-to-html output

Embedding & linking artifacts in annotations

Uploaded artifacts can be embedded in annotations by referencing them using the artifact:// prefix in your image source.

  - label: ":console: Annotation Test"
    command: |
      buildkite-agent artifact upload "indy.png"
      cat << EOF | buildkite-agent annotate --style "info"
        <img src="artifact://indy.png" alt="Belongs in a museum" height=250 >

Screenshot of using an artifact in an annotation

You can also link to uploaded artifacts as a shortcut to important files:

  - label: "Upload Coverage Report"
    command: |
      buildkite-agent artifact upload "coverage/*"
      cat << EOF | buildkite-agent annotate --style "info"
        Read the <a href="artifact://coverage/index.html">uploaded coverage report</a>

Using annotations to report test results

Annotations are a great way of rendering test failures that occur in different steps in a pipeline.

We've created a plugin to convert all the junit.xml artifacts in a build into a single annotation:

  - command:
    parallelism: 50
    artifact_paths: tmp/junit-*.xml
  - wait: ~
    continue_on_failure: true
  - plugins:
      - junit-annotate#v1.2.0:
          artifacts: tmp/junit-*.xml