A release script should stop when a required check fails. This capstone example counts ready checks and records the first blocking step.

Program

Play the script to choose whether the release checklist passes or stops at tests.

failed_step
release_checklist_gate.sh
Replay: real traced execution (multi-file project)
#!/usr/bin/env bash

failed_step="none"
checks="lint tests build publish"
ready=0
for check in $checks; do
    if [[ "$check" == "$failed_step" ]]; then
        status="blocked:$check"
        break
    fi
    ready=$((ready + 1))
done
if [[ "$failed_step" == "none" ]]; then
    status="ready"
fi
echo "ready=$ready status=$status"
#!/usr/bin/env bash

failed_step="tests"
checks="lint tests build publish"
ready=0
for check in $checks; do
    if [[ "$check" == "$failed_step" ]]; then
        status="blocked:$check"
        break
    fi
    ready=$((ready + 1))
done
if [[ "$failed_step" == "none" ]]; then
    status="ready"
fi
echo "ready=$ready status=$status"
  1. failed_step ← none

    3failed_step="none"4checks="lint tests build publish"
    values this stepnonefailed_step
  2. checks ← lint tests build publish

    3failed_step="none"4checks="lint tests build publish"5ready=0
    values this steplint tests build publishchecks
  3. ready ← 0

    4checks="lint tests build publish"5ready=06for check in $checks; do
    values this step0ready
  4. ready ← 1

    10    fi11    ready=$((ready + 1))12done
    values this step0 1readylintcheck
  5. ready ← 2

    10    fi11    ready=$((ready + 1))12done
    values this step1 2readytestscheck
  6. ready ← 3

    10    fi11    ready=$((ready + 1))12done
    values this step2 3readybuildcheck
  7. ready ← 4

    10    fi11    ready=$((ready + 1))12done
    values this step3 4readypublishcheck
  8. if [[ "$failed_step" == "none" ]]; then

    12done13if [[ "$failed_step" == "none" ]]; then14    status="ready"
    values this stepnonefailed_step
  9. status ← ready

    13if [[ "$failed_step" == "none" ]]; then14    status="ready"15fi
    values this stepreadystatus
  10. echo "ready=$ready status=$status"

    15fi16echo "ready=$ready status=$status"
    outputready=4 status=ready
    values this step4readyreadystatus
  1. failed_step ← tests

    3failed_step="tests"4checks="lint tests build publish"
    values this steptestsfailed_step
  2. checks ← lint tests build publish

    3failed_step="tests"4checks="lint tests build publish"5ready=0
    values this steplint tests build publishchecks
  3. ready ← 0

    4checks="lint tests build publish"5ready=06for check in $checks; do
    values this step0ready
  4. ready ← 1

    10    fi11    ready=$((ready + 1))12done
    values this step0 1readylintcheck
  5. if [[ "$check" == "$failed_step" ]]; then

    6for check in $checks; do7    if [[ "$check" == "$failed_step" ]]; then8        status="blocked:$check"
    values this steptestschecktestsfailed_step
  6. status ← blocked:tests

    7if [[ "$check" == "$failed_step" ]]; then8    status="blocked:$check"9    break
    values this stepblocked:testsstatus
  7. if [[ "$failed_step" == "none" ]]; then

    12done13if [[ "$failed_step" == "none" ]]; then14    status="ready"
    values this steptestsfailed_step
  8. echo "ready=$ready status=$status"

    15fi16echo "ready=$ready status=$status"
    outputready=1 status=blocked:tests
    values this step1readyblocked:testsstatus
checklist gate A gate verifies required checks before a release proceeds.
fail fast Failing fast records the first blocking step instead of hiding it.
release status A final status line makes the release decision clear.