#!/usr/bin/env bash set -euo pipefail REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" BUILD_DIR="${REPO_DIR}/build" COVERAGE_PROFILE="${BUILD_DIR}/coverage.out" COVERAGE_PERCENT_FILE="${BUILD_DIR}/coverage-percent.txt" QUALITY_METRICS_ENABLED="${ANANKE_QUALITY_METRICS_ENABLED:-1}" QUALITY_METRICS_FILE="${ANANKE_QUALITY_METRICS_FILE:-/var/lib/ananke/quality-gate.prom}" QUALITY_STATE_FILE="${ANANKE_QUALITY_STATE_FILE:-/var/lib/ananke/quality-gate.state}" QUALITY_PUSHGATEWAY_ENABLED="${ANANKE_QUALITY_PUSHGATEWAY_ENABLED:-1}" QUALITY_PUSHGATEWAY_URL="${ANANKE_QUALITY_PUSHGATEWAY_URL:-${PUSHGATEWAY_URL:-http://platform-quality-gateway.monitoring.svc.cluster.local:9091}}" QUALITY_PUSHGATEWAY_JOB="${ANANKE_QUALITY_PUSHGATEWAY_JOB:-platform-quality-ci}" QUALITY_PUSHGATEWAY_TRIGGER="${ANANKE_QUALITY_PUSHGATEWAY_TRIGGER:-host}" QUALITY_LAST_OK=0 QUALITY_LAST_FAILED=0 QUALITY_LAST_SUCCESS=0 QUALITY_LAST_RUN_TS=0 QUALITY_SUCCESS_PERCENT="0.00" read_quality_counter() { local key="$1" if [[ ! -f "${QUALITY_STATE_FILE}" ]]; then echo 0 return 0 fi local value value="$(awk -F= -v key="${key}" '$1==key {print $2}' "${QUALITY_STATE_FILE}" | tail -n1)" if [[ ! "${value}" =~ ^[0-9]+$ ]]; then echo 0 return 0 fi echo "${value}" } write_quality_metrics() { local exit_code="$1" local metrics_dir state_dir metrics_dir="$(dirname "${QUALITY_METRICS_FILE}")" state_dir="$(dirname "${QUALITY_STATE_FILE}")" mkdir -p "${state_dir}" >/dev/null 2>&1 || return 0 if [[ "${QUALITY_METRICS_ENABLED}" == "1" ]]; then mkdir -p "${metrics_dir}" >/dev/null 2>&1 || return 0 fi local ok failed total last_success now success_percent ok="$(read_quality_counter ok)" failed="$(read_quality_counter failed)" last_success=0 if [[ "${exit_code}" -eq 0 ]]; then ok=$((ok + 1)) last_success=1 else failed=$((failed + 1)) fi total=$((ok + failed)) now="$(date +%s)" success_percent="$(awk -v ok="${ok}" -v total="${total}" 'BEGIN { if (total <= 0) { print "0.00" } else { printf "%.2f", (ok * 100.0) / total } }')" QUALITY_LAST_OK="${ok}" QUALITY_LAST_FAILED="${failed}" QUALITY_LAST_SUCCESS="${last_success}" QUALITY_LAST_RUN_TS="${now}" QUALITY_SUCCESS_PERCENT="${success_percent}" local tmp_metrics="" tmp_state if [[ "${QUALITY_METRICS_ENABLED}" == "1" ]]; then tmp_metrics="$(mktemp "${metrics_dir}/quality-gate.prom.XXXXXX")" fi tmp_state="$(mktemp "${state_dir}/quality-gate.state.XXXXXX")" if [[ "${QUALITY_METRICS_ENABLED}" == "1" ]]; then cat > "${tmp_metrics}" < "${tmp_state}" </dev/null 2>&1; then echo "[quality] warning: python3 not found; skipping Pushgateway publish" >&2 return 0 fi if ! python3 "${REPO_DIR}/scripts/publish_quality_metrics.py" \ --pushgateway-url "${QUALITY_PUSHGATEWAY_URL}" \ --job-name "${QUALITY_PUSHGATEWAY_JOB}" \ --suite "ananke" \ --trigger "${QUALITY_PUSHGATEWAY_TRIGGER}" \ --local-ok "${QUALITY_LAST_OK}" \ --local-failed "${QUALITY_LAST_FAILED}"; then echo "[quality] warning: Pushgateway publish failed for suite=ananke url=${QUALITY_PUSHGATEWAY_URL}" >&2 fi } quality_gate_finalize() { local exit_code="$1" set +e write_quality_metrics "${exit_code}" || true publish_quality_metrics || true exit "${exit_code}" } trap 'quality_gate_finalize $?' EXIT cd "${REPO_DIR}" mkdir -p "${BUILD_DIR}" rm -f "${COVERAGE_PROFILE}" "${COVERAGE_PERCENT_FILE}" printf 'failed\n' > "${BUILD_DIR}/docs-naming.status" echo "[quality] unit tests + workspace coverage profile" go test -coverprofile="${COVERAGE_PROFILE}" ./... coverage_percent="$(go tool cover -func="${COVERAGE_PROFILE}" | awk '/^total:/ {gsub("%","",$3); print $3}')" if [[ -z "${coverage_percent}" ]]; then coverage_percent="0" fi printf '%s\n' "${coverage_percent}" > "${COVERAGE_PERCENT_FILE}" echo "[quality] hygiene: doc contracts" cd testing go test ./hygiene -run TestHygieneContracts/doc_contract -count=1 echo "[quality] hygiene: naming contracts" go test ./hygiene -run TestHygieneContracts/naming_contract -count=1 printf 'ok\n' > "${BUILD_DIR}/docs-naming.status" echo "[quality] hygiene: LOC limits" go test ./hygiene -run TestHygieneContracts/loc_limit -count=1 echo "[quality] hygiene: split test-module contract" go test ./hygiene -run TestHygieneContracts/split_module_contract -count=1 cd "${REPO_DIR}" echo "[quality] lint" ./scripts/lint.sh echo "[quality] installer template contracts" ./scripts/verify_install_templates.sh echo "[quality] per-file coverage gate (95%)" cd testing ANANKE_ENFORCE_COVERAGE=1 ANANKE_PER_FILE_COVERAGE_TARGET=95 go test ./coverage -run TestPerFileCoverageReport -count=1 -v