ci(lesavka): reuse headless display wrapper across gates

This commit is contained in:
Brad Stein 2026-05-19 20:22:37 -03:00
parent e55243f42b
commit e1429f0609
7 changed files with 31 additions and 15 deletions

15
scripts/ci/headless_run.sh Executable file
View File

@ -0,0 +1,15 @@
#!/usr/bin/env bash
# Run GUI-adjacent CI commands safely on headless Jenkins agents.
lesavka_ci_run_headless() {
local cmd=("$@")
if [[ -z "${DISPLAY:-}" && "${LESAVKA_CI_HEADLESS_GTK:-1}" != "0" ]] && command -v xvfb-run >/dev/null 2>&1; then
cmd=(xvfb-run -a -s "-screen 0 1920x1080x24" "${cmd[@]}")
fi
if command -v dbus-run-session >/dev/null 2>&1; then
cmd=(dbus-run-session -- "${cmd[@]}")
fi
"${cmd[@]}"
}

View File

@ -3,6 +3,7 @@
set -euo pipefail
ROOT=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.." && pwd)
source "${ROOT}/scripts/ci/headless_run.sh"
cd "$ROOT"
if [[ "${LESAVKA_ALLOW_DISRUPTIVE_INPUT_TESTS:-0}" != "1" ]]; then
@ -38,4 +39,4 @@ INPUT_TESTS=(
cargo fmt --all -- --check
cargo check -q -p lesavka_client --bin lesavka-client
cargo check -q -p lesavka_server --bin lesavka-server
cargo test -q -p lesavka_tests --features disruptive-input-tests "${INPUT_TESTS[@]}"
lesavka_ci_run_headless cargo test -q -p lesavka_tests --features disruptive-input-tests "${INPUT_TESTS[@]}"

View File

@ -3,6 +3,7 @@
set -euo pipefail
ROOT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)
source "${ROOT_DIR}/scripts/ci/headless_run.sh"
REPORT_DIR="${ROOT_DIR}/target/media-reliability-gate"
TEST_LOG="${REPORT_DIR}/cargo-test.log"
SUMMARY_JSON="${REPORT_DIR}/summary.json"
@ -54,11 +55,11 @@ status=0
set +e
{
echo '==> client camera profile/unit guards'
cargo test -p lesavka_client --color never input::camera::tests -- --nocapture
lesavka_ci_run_headless cargo test -p lesavka_client --color never input::camera::tests -- --nocapture
camera_status=${PIPESTATUS[0]}
echo
echo '==> media reliability contract tests'
cargo test -p lesavka_tests --color never "${MEDIA_TESTS[@]}"
lesavka_ci_run_headless cargo test -p lesavka_tests --color never "${MEDIA_TESTS[@]}"
contract_status=${PIPESTATUS[0]}
if [[ "${camera_status}" -ne 0 || "${contract_status}" -ne 0 ]]; then
exit 1

View File

@ -3,6 +3,7 @@
set -euo pipefail
ROOT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)
source "${ROOT_DIR}/scripts/ci/headless_run.sh"
REPORT_DIR="${ROOT_DIR}/target/performance-gate"
TEST_LOG="${REPORT_DIR}/cargo-test.log"
METRICS_FILE="${REPORT_DIR}/metrics.prom"
@ -32,7 +33,7 @@ PERFORMANCE_TESTS=(
start_seconds=$(date +%s)
status=0
set +e
cargo test -p lesavka_tests "${PERFORMANCE_TESTS[@]}" --color never 2>&1 | tee "${TEST_LOG}"
lesavka_ci_run_headless cargo test -p lesavka_tests "${PERFORMANCE_TESTS[@]}" --color never 2>&1 | tee "${TEST_LOG}"
status=${PIPESTATUS[0]}
set -e
duration_seconds=$(($(date +%s) - start_seconds))

View File

@ -2,6 +2,7 @@
set -euo pipefail
ROOT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)
source "${ROOT_DIR}/scripts/ci/headless_run.sh"
REPORT_DIR="${ROOT_DIR}/target/quality-gate"
COVERAGE_LCOV="${REPORT_DIR}/coverage.lcov"
SUMMARY_TXT="${REPORT_DIR}/summary.txt"
@ -199,7 +200,8 @@ status=0
# Several integration contracts intentionally mutate process environment and
# probe singleton runtime state. Keep coverage collection serial so per-file
# percentages stay stable enough to serve as a baseline gate.
if RUST_TEST_THREADS="${RUST_TEST_THREADS:-1}" cargo llvm-cov --workspace --all-targets --lcov --output-path "${COVERAGE_LCOV}"; then
export RUST_TEST_THREADS="${RUST_TEST_THREADS:-1}"
if lesavka_ci_run_headless cargo llvm-cov --workspace --all-targets --lcov --output-path "${COVERAGE_LCOV}"; then
if python3 - "${COVERAGE_LCOV}" "${BASELINE_JSON}" "${METRICS_FILE}" "${SUMMARY_TXT}" "${ROOT_DIR}" "${COVERAGE_CONTRACT_JSON}" "${branch}" "${commit}" "${build_number}" "${jenkins_job}" <<'PY'
import json
import os

View File

@ -3,6 +3,7 @@
set -euo pipefail
ROOT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)
source "${ROOT_DIR}/scripts/ci/headless_run.sh"
REPORT_DIR="${ROOT_DIR}/target/test-gate"
TEST_LOG="${REPORT_DIR}/cargo-test.log"
SUMMARY_JSON="${REPORT_DIR}/summary.json"
@ -27,14 +28,8 @@ build_url=${BUILD_URL:-}
start_seconds=$(date +%s)
status=0
set +e
cargo_test_cmd=(cargo test --workspace --all-targets --no-fail-fast --color never)
if [[ -z "${DISPLAY:-}" && "${LESAVKA_CI_HEADLESS_GTK:-1}" != "0" ]] && command -v xvfb-run >/dev/null 2>&1; then
cargo_test_cmd=(xvfb-run -a -s "-screen 0 1920x1080x24" "${cargo_test_cmd[@]}")
fi
if command -v dbus-run-session >/dev/null 2>&1; then
cargo_test_cmd=(dbus-run-session -- "${cargo_test_cmd[@]}")
fi
RUST_TEST_THREADS="${RUST_TEST_THREADS:-1}" "${cargo_test_cmd[@]}" 2>&1 | tee "${TEST_LOG}"
export RUST_TEST_THREADS="${RUST_TEST_THREADS:-1}"
lesavka_ci_run_headless cargo test --workspace --all-targets --no-fail-fast --color never 2>&1 | tee "${TEST_LOG}"
status=${PIPESTATUS[0]}
set -e
end_seconds=$(date +%s)

View File

@ -3,6 +3,7 @@
set -euo pipefail
ROOT=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.." && pwd)
source "${ROOT}/scripts/ci/headless_run.sh"
cd "$ROOT"
VIDEO_TESTS=(
@ -24,10 +25,10 @@ VIDEO_IGNORE_REGEX='(^|/)(common/src/(hid|paste|process_metrics)\.rs|server/src/
cargo fmt --all -- --check
cargo check -q -p lesavka_client --bin lesavka-client
cargo check -q -p lesavka_server --bin lesavka-server
cargo test -q -p lesavka_tests "${VIDEO_TESTS[@]}"
lesavka_ci_run_headless cargo test -q -p lesavka_tests "${VIDEO_TESTS[@]}"
cargo llvm-cov clean --workspace
cargo llvm-cov --workspace "${VIDEO_TESTS[@]}" \
lesavka_ci_run_headless cargo llvm-cov --workspace "${VIDEO_TESTS[@]}" \
--ignore-filename-regex "$VIDEO_IGNORE_REGEX" \
--fail-under-lines 95 \
--summary-only