repositories / bugabinga.net
bugabinga.net
personal infrastructure for bugabinga!
owned by admin
scripts/local/luci-manual-e2e.sh
Raw#!/usr/bin/env bash
set -euo pipefail
ROOT="$(mktemp -d /tmp/luci-manual-XXXXXX)"
LUCI="${LUCI_BIN:-${ROOT}/luci}"
HTTP_ADDR="${LUCI_HTTP_ADDR:-127.0.0.1:18080}"
CHROME="${CHROME:-}"
PODMAN_SOCKET="${LUCI_PODMAN_SOCKET:-unix://${XDG_RUNTIME_DIR:-/run/user/$(id -u)}/podman/podman.sock}"
PODMAN_PID=""
LUCI_PID=""
cleanup() {
if [[ -n "${LUCI_PID}" ]]; then
kill "${LUCI_PID}" 2>/dev/null || true
fi
if [[ -n "${PODMAN_PID}" ]]; then
kill "${PODMAN_PID}" 2>/dev/null || true
fi
echo "manual e2e root: ${ROOT}"
}
trap cleanup EXIT
find_chrome() {
if [[ -n "${CHROME}" ]]; then
printf '%s\n' "${CHROME}"
return
fi
for candidate in google-chrome-stable google-chrome chromium chromium-browser /opt/google/chrome/chrome; do
if command -v "${candidate}" >/dev/null 2>&1 || [[ -x "${candidate}" ]]; then
printf '%s\n' "${candidate}"
return
fi
done
echo "Chrome/Chromium not found" >&2
exit 1
}
ensure_podman_socket() {
local socket_path="${PODMAN_SOCKET#unix://}"
if [[ -S "${socket_path}" ]]; then
return
fi
mkdir -p "$(dirname "${socket_path}")"
podman system service --time=0 "${PODMAN_SOCKET}" >"${ROOT}/podman-service.log" 2>&1 &
PODMAN_PID="$!"
for _ in {1..50}; do
[[ -S "${socket_path}" ]] && return
sleep 0.1
done
cat "${ROOT}/podman-service.log" >&2 || true
echo "Podman socket did not start: ${socket_path}" >&2
exit 1
}
wait_http() {
for _ in {1..80}; do
curl -fsS "http://${HTTP_ADDR}/" >"${ROOT}/dashboard.html" && return
sleep 0.1
done
echo "Luci HTTP did not start" >&2
exit 1
}
wait_log() {
local wanted="$1"
for _ in {1..200}; do
if find "${ROOT}/data/logs" -type f -name '*.zst' -print0 | xargs -0 -r zstdcat 2>/dev/null | grep -q "${wanted}"; then
return
fi
sleep 0.1
done
echo "Luci log did not contain ${wanted}" >&2
exit 1
}
build_luci() {
if [[ -x "${LUCI}" ]]; then
return
fi
(cd services/luci && go build -o "${LUCI}" ./cmd/luci)
}
write_repo() {
local work="${ROOT}/work-repo"
git init "${work}" >/dev/null
git -C "${work}" config user.email test@example.invalid
git -C "${work}" config user.name Test
mkdir -p "${work}/.ci"
cat >"${work}/.ci/ci.kdl" <<'KDL'
job "push-main" {
image "docker.io/library/golang:1.26"
run "git rev-parse --is-inside-work-tree | grep -q true"
run "git ls-files | grep -qx README.md"
run "echo PUSH_OK GIT_OK"
trigger {
push {
branch "main"
}
}
}
job "push-path" {
image "docker.io/library/alpine:latest"
run "echo PATH_OK"
trigger {
push {
branch "main"
include "README.md"
}
}
}
job "push-ignore" {
image "docker.io/library/alpine:latest"
run "echo SHOULD_NOT_RUN"
trigger {
push {
include "docs/**"
}
}
}
job "matrix" {
image "docker.io/library/alpine:latest"
run "echo MATRIX_${axis}"
trigger {
push {
branch "main"
}
}
matrix {
axis "one" "two"
}
}
job "tag-release" {
image "docker.io/library/alpine:latest"
run "echo TAG_OK"
trigger {
push {
tag "v*"
}
}
}
job "scheduled" {
image "docker.io/library/alpine:latest"
run "echo SCHEDULE_OK"
trigger {
schedule "* * * * *"
}
}
job "manual-rev" {
image "docker.io/library/alpine:latest"
run "grep -q second README.md && echo MANUAL_REV_OK"
}
job "manual-secret" {
image "docker.io/library/alpine:latest"
run "test $TOKEN = s3cr3t && test -f .secrets/key && echo MANUAL_SECRET_OK"
secret "TOKEN" env="TOKEN"
secret "KEY" file=".secrets/key"
}
KDL
echo first >"${work}/README.md"
git -C "${work}" add . >/dev/null
git -C "${work}" commit -m initial >/dev/null
git -C "${work}" branch -M main
git clone --bare "${work}" "${ROOT}/repos/repo.git" >/dev/null 2>&1
git -C "${work}" remote add origin "${ROOT}/repos/repo.git"
}
main() {
local chrome
chrome="$(find_chrome)"
ensure_podman_socket
build_luci
mkdir -p "${ROOT}/repos"
write_repo
export LUCI_DATA_DIR="${ROOT}/data"
export LUCI_REPO_ROOTS="${ROOT}/repos"
export LUCI_HTTP_ADDR="${HTTP_ADDR}"
export LUCI_BASE_URL="http://${HTTP_ADDR}"
export LUCI_INBOX_DIR="${ROOT}/inbox"
export LUCI_PODMAN_SOCKET="${PODMAN_SOCKET}"
export LUCI_DEFAULT_MEMORY="512m"
export LUCI_DEFAULT_CPUS="1"
"${LUCI}" env-check >"${ROOT}/env-check.out"
"${LUCI}" serve --once >"${ROOT}/baseline.out"
echo second >"${ROOT}/work-repo/README.md"
git -C "${ROOT}/work-repo" add README.md >/dev/null
git -C "${ROOT}/work-repo" commit -m update >/dev/null
local update_rev
update_rev="$(git -C "${ROOT}/work-repo" rev-parse HEAD)"
git -C "${ROOT}/work-repo" push origin main >/dev/null 2>&1
"${LUCI}" serve --once >"${ROOT}/push.out"
git -C "${ROOT}/work-repo" -c tag.gpgSign=false tag v1.0.0
git -C "${ROOT}/work-repo" push origin v1.0.0 >/dev/null 2>&1
"${LUCI}" serve --once >"${ROOT}/tag.out"
USER=manual "${LUCI}" run repo manual-rev --rev "${update_rev}" >"${ROOT}/manual-rev-id.out"
"${LUCI}" serve --once >"${ROOT}/manual-rev.out"
mkdir -p "${ROOT}/data/secrets/repo/manual-secret"
printf 's3cr3t\n' >"${ROOT}/data/secrets/repo/manual-secret/TOKEN"
printf 'keydata\n' >"${ROOT}/data/secrets/repo/manual-secret/KEY"
USER=manual "${LUCI}" run repo manual-secret --ref main >"${ROOT}/manual-id.out"
"${LUCI}" serve --once >"${ROOT}/manual.out"
SSH_ORIGINAL_COMMAND='ci env-check' "${LUCI}" ssh >"${ROOT}/ssh.out"
"${LUCI}" serve >"${ROOT}/http.out" 2>"${ROOT}/http.err" &
LUCI_PID="$!"
wait_http
wait_log SCHEDULE_OK
curl -fsS "http://${HTTP_ADDR}/llms.txt" >"${ROOT}/llms.txt"
local chrome_args=("${chrome}" --headless=new --no-sandbox --disable-gpu --user-data-dir="${ROOT}/chrome")
"${chrome_args[@]}" --dump-dom "http://${HTTP_ADDR}/" >"${ROOT}/chrome-dashboard.html"
"${chrome_args[@]}" --dump-dom "http://${HTTP_ADDR}/repos/repo" >"${ROOT}/chrome-repo.html"
local run_id
run_id="$(grep -o '/runs/[^"<]*' "${ROOT}/chrome-dashboard.html" | head -1 | cut -d/ -f3)"
"${chrome_args[@]}" --dump-dom "http://${HTTP_ADDR}/runs/${run_id}" >"${ROOT}/chrome-run.html"
"${chrome_args[@]}" --dump-dom "http://${HTTP_ADDR}/docs" >"${ROOT}/chrome-docs.html"
"${chrome_args[@]}" --screenshot="${ROOT}/chrome-dashboard.png" "http://${HTTP_ADDR}/" >/dev/null
: >"${ROOT}/combined.log"
while IFS= read -r -d '' log; do
zstdcat "${log}" >>"${ROOT}/combined.log"
done < <(find "${ROOT}/data/logs" -type f -name '*.zst' -print0)
for want in PUSH_OK GIT_OK PATH_OK MATRIX_one MATRIX_two TAG_OK MANUAL_REV_OK MANUAL_SECRET_OK SCHEDULE_OK; do
grep -q "${want}" "${ROOT}/combined.log"
done
if grep -q SHOULD_NOT_RUN "${ROOT}/combined.log"; then
echo 'excluded path job ran' >&2
exit 1
fi
grep -q '<h1>repo</h1>' "${ROOT}/chrome-repo.html"
grep -q 'Run ' "${ROOT}/chrome-run.html"
grep -q 'Luci docs' "${ROOT}/chrome-docs.html"
grep -q '# Luci CI' "${ROOT}/llms.txt"
if grep -Eiq '<(form|button)\b' "${ROOT}"/chrome-{dashboard,repo,run,docs}.html; then
echo 'mutating UI controls found' >&2
exit 1
fi
local logs
logs="$(find "${ROOT}/data/logs" -type f | wc -l)"
if [[ "${logs}" != 8 ]]; then
echo "unexpected log count: ${logs}, want 8" >&2
exit 1
fi
printf 'ok: root=%s run=%s logs=%s\n' "${ROOT}" "${run_id}" "${logs}"
}
main "$@"