-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathci
More file actions
executable file
·48 lines (45 loc) · 3.29 KB
/
Copy pathci
File metadata and controls
executable file
·48 lines (45 loc) · 3.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#!/usr/bin/env bash
#
# Run the same checks that GitLab CI runs, using Docker.
# Runs shellcheck (lint) and bats (unit tests) in the same images as CI.
# Does not require ShellCheck or Bats to be installed locally.
# Silent like every command: the first line points at this run's log file and the terminal
# shows a dot per line of output. Reports each job loudly in the log (see lib/ci_report):
# on failure it prints a banner and re-surfaces the failing tests at the END of the log,
# the terminal shows " FAIL (see <log>)", and ./ci exits non-zero.
# Usage: ./ci
#
set -euo pipefail # exit on error, undefined vars, or pipe failures
. "$(dirname "$0")"/lib/capture # captured command: per-run log dir, banner + "logs:" pointer, dots, trace (see lib/capture)
. "$(dirname "$0")"/lib/exit_trap # composable EXIT traps: register cleanup without clobbering the capture's display handler
. "$(dirname "$0")"/lib/ci_report # provides ci_report: loud pass/fail summary so failures aren't missed
# Each Docker job's output flows through the capture layer (dots on the terminal, full text
# in the run-dir log) AND is tee'd to this temp file, so ci_report can re-surface failures at
# the end. The file is reused (each `tee` truncates it) and removed on exit.
ci_log=$(mktemp "${TMPDIR:-/tmp}/quibble-ci.XXXXXX") # template form works on both macOS (BSD) and Linux (GNU) mktemp
_ci_cleanup() { rm -f "$ci_log"; } # remove the temp capture file whenever ./ci exits ($1 is the exit code, unused)
quibble_register_exit_trap ci_log_cleanup _ci_cleanup # unique key so duration_trap's "display" handler still runs
# --- ShellCheck job (matches .gitlab-ci.yml shellcheck job) ---
# --rm: remove container after it exits. -v: mount repo read-only into /mnt.
# sh -c: install bash (not in Alpine) and git (lib/debug_info's prerequisite check runs
# when ./lint sources lib/capture), then run ./lint.
# 2>&1 | tee: merge stderr into stdout and capture it for ci_report (the capture layer turns it into dots).
# || status=$?: with `set -o pipefail` the pipeline's status is docker's; capture it without
# tripping `set -e`, so ci_report (not a bare abort) gets to report the result.
echo "Running shellcheck..."
status=0
docker run --rm -v "$PWD:/mnt:ro" koalaman/shellcheck-alpine:stable \
sh -c "apk add --no-cache bash git >/dev/null 2>&1 && cd /mnt && ./lint" 2>&1 | tee "$ci_log" || status=$?
ci_report shellcheck "$status" "$ci_log" || exit "$?" # "shellcheck passed", or a loud banner then abort (skip bats)
echo
# --- Bats job (matches .gitlab-ci.yml bats job) ---
# sh -c: install bash and git (git is needed by lib/debug_info), then run bats.
# The http(s)_proxy variables apply only to the bats run (not the apk install, which
# needs the network): they route HTTP(S) to a dead local proxy so an accidental network
# call in a unit test fails in under a second instead of hanging the job — the same
# offline enforcement as ./test_unit.
echo "Running bats..."
status=0
docker run --rm -v "$PWD:/mnt:ro" --entrypoint sh bats/bats:latest \
-c "apk add --no-cache bash git >/dev/null 2>&1 && cd /mnt && http_proxy=http://127.0.0.1:9 https_proxy=http://127.0.0.1:9 bats test/" 2>&1 | tee "$ci_log" || status=$?
ci_report bats "$status" "$ci_log" || exit "$?" # "bats passed", or a loud banner re-surfacing the failing tests then exit non-zero