114 lines
4.6 KiB
Bash
114 lines
4.6 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
|
test_tmp=$(mktemp -d)
|
|
dirty_file=
|
|
trap 'rm -rf "$test_tmp"; [[ -z $dirty_file ]] || rm -f "$dirty_file"' EXIT HUP INT TERM
|
|
real_docker=$(command -v docker)
|
|
output="$test_tmp/dist"
|
|
load_state="$test_tmp/docker.load"
|
|
: > "$load_state"
|
|
|
|
mkdir -p "$test_tmp/bin"
|
|
cat > "$test_tmp/bin/docker" <<'EOF'
|
|
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
printf '%s\n' "$*" >> "$DOCKER_LOG"
|
|
[[ $1 == buildx && $2 == create ]] && exit 0
|
|
[[ $1 == buildx && $2 == rm ]] && exit 0
|
|
if [[ $1 == buildx && $2 == build ]]; then
|
|
image=
|
|
previous=
|
|
for arg in "$@"; do
|
|
[[ $arg == type=docker,*dest=* ]] && output=${arg##*dest=}
|
|
[[ $previous == --tag ]] && image=$arg
|
|
previous=$arg
|
|
done
|
|
fake_archive=$(mktemp -d)
|
|
printf '[]\n' > "$fake_archive/manifest.json"
|
|
printf '%s\n' "$image" > "$fake_archive/image-ref"
|
|
tar -cf "$output" -C "$fake_archive" manifest.json image-ref
|
|
rm -rf "$fake_archive"
|
|
exit 0
|
|
fi
|
|
if [[ $# == 3 && $1 == load && $2 == --input && -s $3 ]]; then
|
|
image=$(tar -xOf "$3" image-ref)
|
|
grep -Fxq "$image" "$DOCKER_LOAD_STATE" || printf '%s\n' "$image" >> "$DOCKER_LOAD_STATE"
|
|
exit 0
|
|
fi
|
|
if [[ $1 == image && $2 == inspect ]]; then
|
|
inspected_images=("${@:3}")
|
|
cmp -s <(printf '%s\n' "${inspected_images[@]}") "$DOCKER_LOAD_STATE"
|
|
exit 0
|
|
fi
|
|
if [[ $1 == save && $2 == --output ]]; then
|
|
saved_images=("${@:4}")
|
|
cmp -s <(printf '%s\n' "${saved_images[@]}") "$DOCKER_LOAD_STATE"
|
|
fake_archive=$(mktemp -d)
|
|
printf '[]\n' > "$fake_archive/manifest.json"
|
|
tar -cf "$3" -C "$fake_archive" manifest.json
|
|
rm -rf "$fake_archive"
|
|
exit 0
|
|
fi
|
|
exit 1
|
|
EOF
|
|
chmod +x "$test_tmp/bin/docker"
|
|
|
|
cd "$root"
|
|
dirty_file=$(mktemp "$root/.build-production-dirty.XXXXXX")
|
|
if PATH="$test_tmp/bin:$PATH" DOCKER_LOG="$test_tmp/docker.log" GOCHAT_DIST_DIR="$output" \
|
|
GOCHAT_VERSION=1.2.3 bash scripts/build-production.sh >"$test_tmp/dirty.out" 2>&1; then
|
|
echo 'dirty worktree build unexpectedly succeeded' >&2
|
|
exit 1
|
|
fi
|
|
grep -q 'refusing production build from a dirty worktree' "$test_tmp/dirty.out"
|
|
rm "$dirty_file"
|
|
dirty_file=
|
|
|
|
: > "$test_tmp/docker.log"
|
|
PATH="$test_tmp/bin:$PATH" DOCKER_LOG="$test_tmp/docker.log" DOCKER_LOAD_STATE="$load_state" GOCHAT_DIST_DIR="$output" \
|
|
GOCHAT_VERSION=1.2.3 bash scripts/build-production.sh
|
|
|
|
tag=1.2.3-$(git rev-parse --short=12 HEAD)
|
|
expected_images=("gochat/gochat:$tag" "gochat/shangwutong:$tag")
|
|
archive="$output/images/gochat-$tag-images.tgz"
|
|
test -s "$archive"
|
|
gzip -t "$archive"
|
|
(cd "$output" && sha256sum -c SHA256SUMS)
|
|
grep -q '^GOCHAT_IMAGE_REF=gochat/gochat:1.2.3-' "$output/.env.example"
|
|
grep -q '^SHANGWUTONG_IMAGE_REF=gochat/shangwutong:1.2.3-' "$output/.env.example"
|
|
test -f "$output/deploy/fluentd/fluent.conf"
|
|
test -f "$output/deploy/prometheus/prometheus.yml"
|
|
test -f "$output/backend/configs/prometheus_alerts.yml"
|
|
test "$(grep -c '^buildx build ' "$test_tmp/docker.log")" -eq 2
|
|
test "$(grep -c '^load --input ' "$test_tmp/docker.log")" -eq 2
|
|
test "$(grep -Fc -- "--build-arg VERSION=1.2.3 --build-arg COMMIT_SHA=$(git rev-parse --short=12 HEAD) --build-arg BUILD_DATE=$(git show -s --format=%cI HEAD) --build-arg SOURCE_DATE_EPOCH=$(git show -s --format=%ct HEAD)" "$test_tmp/docker.log")" -eq 2
|
|
cmp -s <(printf '%s\n' "${expected_images[@]}") "$load_state"
|
|
test "$(grep '^image inspect ' "$test_tmp/docker.log")" = "image inspect ${expected_images[*]}"
|
|
test "$(grep -c '^save --output ' "$test_tmp/docker.log")" -eq 1
|
|
read -r -a save_args <<< "$(grep '^save --output ' "$test_tmp/docker.log")"
|
|
test "${#save_args[@]}" -eq 5
|
|
cmp -s <(printf '%s\n' "${save_args[@]:3}") "$load_state"
|
|
|
|
cp "$output/.env.example" "$output/.env"
|
|
(cd "$output" && "$real_docker" compose --env-file .env -f deploy/docker/docker-compose.prod.yml config --quiet)
|
|
rm "$output/.env"
|
|
first_sum=$(sha256sum "$archive")
|
|
PATH="$test_tmp/bin:$PATH" DOCKER_LOG="$test_tmp/docker.log" DOCKER_LOAD_STATE="$load_state" GOCHAT_DIST_DIR="$output" \
|
|
GOCHAT_VERSION=1.2.3 bash scripts/build-production.sh
|
|
test "$first_sum" = "$(sha256sum "$archive")"
|
|
|
|
if PATH="$test_tmp/bin:$PATH" DOCKER_LOG="$test_tmp/docker.log" DOCKER_LOAD_STATE="$load_state" \
|
|
docker image inspect "${expected_images[0]}" gochat/not-loaded:latest >/dev/null 2>&1; then
|
|
echo 'docker inspect mock accepted an image that was not loaded' >&2
|
|
exit 1
|
|
fi
|
|
if PATH="$test_tmp/bin:$PATH" DOCKER_LOG="$test_tmp/docker.log" DOCKER_LOAD_STATE="$load_state" \
|
|
docker save --output "$test_tmp/extra.tar" "${expected_images[@]}" gochat/extra:latest >/dev/null 2>&1; then
|
|
echo 'docker save mock accepted an extra image' >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo 'production build script test passed'
|