v1.2.0
  1. ds
  2. Operations
  3. CI pipeline

CI pipeline

Stages and jobs from commit to deploy.

Pipeline #4821 maina41f9c2Retry webhook deliveries with jitter running for 6m 12s
Show code
<div class="pipe-head">
  <span class="sg lg" data-state="running"></span><b>Pipeline #4821</b>
  <span>main</span><code>a41f9c2</code><span>Retry webhook deliveries with jitter</span>
  <span class="meta">running for 6m 12s</span>
</div>
<div class="pipeline">
  <div class="stage">
    <span class="label">Build</span>
      <a class="job" href="#"><span class="sg" data-state="success" role="img" aria-label="Success"></span><span>compile</span><small>1m 48s</small></a>
      <a class="job" href="#"><span class="sg" data-state="success" role="img" aria-label="Success"></span><span>lint</span><small>42s</small></a>
  </div>
  <div class="stage">
    <span class="label">Test</span>
      <a class="job" href="#"><span class="sg" data-state="success" role="img" aria-label="Success"></span><span>unit</span><small>3m 12s</small></a>
      <a class="job" href="#"><span class="sg" data-state="running" role="img" aria-label="Running"></span><span>integration</span><small>2m 01s</small></a>
      <a class="job" href="#"><span class="sg" data-state="success" role="img" aria-label="Success"></span><span>contract</span><small>58s</small></a>
  </div>
  <div class="stage">
    <span class="label">Package</span>
      <a class="job" href="#"><span class="sg" data-state="queued" role="img" aria-label="Queued"></span><span>docker-image</span></a>
      <a class="job" href="#"><span class="sg" data-state="queued" role="img" aria-label="Queued"></span><span>sbom</span></a>
  </div>
  <div class="stage">
    <span class="label">Deploy</span>
      <a class="job" href="#"><span class="sg" data-state="queued" role="img" aria-label="Queued"></span><span>staging</span></a>
      <a class="job" href="#"><span class="sg" data-state="manual" role="img" aria-label="Manual"></span><span>production</span></a>
  </div>
</div>

Stages run left to right; jobs in a stage run in parallel. A hairline joins each stage to the last at the height of its first job, which is all the graph a linear pipeline needs. The state glyph comes first in every job so the column reads top to bottom at a glance; failed jobs also tint their box, running ones get an accent border.

States

Code
<span class="sg" data-state="success"></span>
<span class="sg" data-state="failed"></span>
<span class="sg" data-state="running"></span>
<span class="sg" data-state="queued"></span>
<span class="sg" data-state="manual"></span>
<span class="sg" data-state="skipped"></span>
<span class="sg" data-state="canceled"></span>
<span class="sg" data-state="upstream-failed"></span>

Eight glyphs drawn in CSS: success, failed, running (a spinning accent arc), queued (a dashed ring), manual (waiting for someone), skipped, canceled and upstream failed. The same .sg marks jobs, deploys and DAG tasks across ds.

Mini pipeline

PipelineBranchStagesDuration
#4821main6m 12s
#4820fix/retry-jitter9m 40s
#4819feat/ledger-v24m 03s
#4818main7m 55s
Show code
<table class="table compact" style="--ring:var(--bg)">
  <thead><tr><th>Pipeline</th><th>Branch</th><th>Stages</th><th class="n">Duration</th></tr></thead>
  <tbody>
    <tr><td class="mono">#4821</td><td>main</td><td><span class="pipe-mini" role="img" aria-label="success, running, queued, manual"><span class="sg" data-state="success"></span><span class="sg" data-state="running"></span><span class="sg" data-state="queued"></span><span class="sg" data-state="manual"></span></span></td><td class="n">6m 12s</td></tr>
    <tr><td class="mono">#4820</td><td>fix/retry-jitter</td><td><span class="pipe-mini" role="img" aria-label="success, success, success, success"><span class="sg" data-state="success"></span><span class="sg" data-state="success"></span><span class="sg" data-state="success"></span><span class="sg" data-state="success"></span></span></td><td class="n">9m 40s</td></tr>
    <tr><td class="mono">#4819</td><td>feat/ledger-v2</td><td><span class="pipe-mini" role="img" aria-label="success, failed, skipped, skipped"><span class="sg" data-state="success"></span><span class="sg" data-state="failed"></span><span class="sg" data-state="skipped"></span><span class="sg" data-state="skipped"></span></span></td><td class="n">4m 03s</td></tr>
    <tr><td class="mono">#4818</td><td>main</td><td><span class="pipe-mini" role="img" aria-label="success, success, success, canceled"><span class="sg" data-state="success"></span><span class="sg" data-state="success"></span><span class="sg" data-state="success"></span><span class="sg" data-state="canceled"></span></span></td><td class="n">7m 55s</td></tr>
  </tbody>
</table>

One glyph per stage on a hairline, for lists of runs. Each glyph rings itself in the surface colour so the line passes behind it; on another background, set --ring.

ClassOnWhat it does
.sgspanState glyph. data-state: success, failed, running, queued, manual, skipped, canceled, upstream-failed. .lg for 18px.
.pipelinedivStages in a row, scrolling sideways when they do not fit. --stage-gap (2rem), --job-h (2.25rem).
.stagedivA .label and its jobs. Joined to the previous stage by a hairline.
.joba, buttonGlyph, name, and a <small> duration. aria-current="true" outlines the one being viewed.
.pipe-headdivThe run: glyph, number, branch, <code> commit, message, duration last.
.pipe-minispanGlyphs on a hairline. --ring to match a non-surface background.
Do
  • Durations on finished and running jobs, in the same unit style: 1m 48s.
  • Mark jobs that wait for a person as manual, not queued. Queued means a runner will pick it up.
  • Link every job to its log.
Don't
  • Colouring the whole job box green when it passes. Success is the normal case; keep it quiet.
  • A different glyph shape per CI provider.
  • Hiding skipped jobs. They explain why deploy did not run.

Accessibility

  • A glyph is drawn in CSS and says nothing on its own: give each one role="img" and an aria-label with the state, as the jobs here do. The mini pipeline labels the whole row instead.
  • The running arc spins. With reduced motion it stops in place, and the arc on its faint ring still reads as in progress.