canary¶
Widen a release stage by stage, withdrawing at the first bad sign.
Roll a release out in stages, checking each before widening it.
Amber steps have effects outside the run, so a pass is never reused. Pause it, or step through it, with the controls.
# Roll a release out in stages, checking each before widening it.
#
# A loop over stages, stopping at the first one that looks wrong. The stages
# are data: adding one is adding a line.
STAGES = [("canary", "1"), ("early", "10"), ("half", "50"), ("everyone", "100")]
def op(name, command):
return step(name, image = "alpine:3", run = command, cache = False)
def pipeline(ctx):
if ctx.ref != "main":
return
run(op("build", "./scripts/build.sh " + ctx.sha))
for name, percent in STAGES:
run(op("release to " + name, "./scripts/release.sh --percent " + percent))
health = run(op("check " + name, "./scripts/error-rate.sh --below 0.5"), allow_failure = True)
if not health.ok:
run(op("withdraw", "./scripts/release.sh --percent 0"))
fail("error rate too high at {}% ({}); withdrawn".format(percent, name))
Download: canary.pipeline.star
An advanced script is only known as it runs, so it cannot be compiled.