lesavka/scripts/ci/gate_glue_gate.sh

111 lines
4.0 KiB
Bash
Raw Normal View History

#!/usr/bin/env bash
# Validate that upstream gates emitted the canonical Atlas metric contract.
set -euo pipefail
ROOT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)
REPORT_DIR="${ROOT_DIR}/target/gate-glue-gate"
SUMMARY_JSON="${REPORT_DIR}/summary.json"
SUMMARY_TXT="${REPORT_DIR}/summary.txt"
METRICS_FILE="${REPORT_DIR}/metrics.prom"
PUSHGATEWAY_URL=${QUALITY_GATE_PUSHGATEWAY_URL:-}
mkdir -p "${REPORT_DIR}"
cd "${ROOT_DIR}"
branch=${BRANCH_NAME:-${GIT_BRANCH:-}}
if [[ -z "${branch}" ]]; then
branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo unknown)
fi
commit=${GIT_COMMIT:-}
if [[ -z "${commit}" ]]; then
commit=$(git rev-parse --short HEAD 2>/dev/null || echo unknown)
fi
python3 - "${SUMMARY_JSON}" "${SUMMARY_TXT}" "${METRICS_FILE}" "${branch}" "${commit}" "${ROOT_DIR}" <<'PY'
import json
import pathlib
import sys
from datetime import datetime, timezone
summary_path = pathlib.Path(sys.argv[1])
text_path = pathlib.Path(sys.argv[2])
metrics_path = pathlib.Path(sys.argv[3])
branch = sys.argv[4]
commit = sys.argv[5]
root = pathlib.Path(sys.argv[6])
def esc(value: str) -> str:
return value.replace('\\', r'\\').replace('\n', r'\n').replace('"', r'\"')
metric_files = [
root / 'target' / 'hygiene-gate' / 'metrics.prom',
root / 'target' / 'quality-gate' / 'metrics.prom',
root / 'target' / 'test-gate' / 'metrics.prom',
root / 'target' / 'media-reliability-gate' / 'metrics.prom',
]
required_metrics = {
'platform_quality_gate_runs_total': False,
'platform_quality_gate_tests_total': False,
'platform_quality_gate_checks_total': False,
'platform_quality_gate_workspace_line_coverage_percent': False,
'platform_quality_gate_source_lines_over_500_total': False,
}
required_checks = {'tests', 'coverage', 'loc', 'style', 'media_reliability'}
seen_checks: set[str] = set()
missing_files: list[str] = []
for path in metric_files:
if not path.exists():
missing_files.append(path.relative_to(root).as_posix())
continue
text = path.read_text(encoding='utf-8', errors='replace')
for metric in required_metrics:
if metric in text:
required_metrics[metric] = True
for check in required_checks:
if f'check="{check}"' in text:
seen_checks.add(check)
missing_metrics = [name for name, present in required_metrics.items() if not present]
missing_checks = sorted(required_checks - seen_checks)
status = 'failed' if missing_files or missing_metrics or missing_checks else 'ok'
summary = {
'suite': 'lesavka',
'check': 'gate_glue',
'status': status,
'branch': branch,
'commit': commit,
'generated_at': datetime.now(timezone.utc).isoformat(),
'missing_files': missing_files,
'missing_metrics': missing_metrics,
'missing_checks': missing_checks,
}
summary_path.write_text(json.dumps(summary, indent=2, sort_keys=True) + '\n', encoding='utf-8')
lines = ['gate glue report', f'status: {status}', f'branch: {branch}', f'commit: {commit}', '']
for key in ('missing_files', 'missing_metrics', 'missing_checks'):
values = summary[key]
lines.append(f'{key}: {", ".join(values) if values else "none"}')
text_path.write_text('\n'.join(lines) + '\n', encoding='utf-8')
labels = f'suite="lesavka",branch="{esc(branch)}",commit="{esc(commit)}"'
ok = 1 if status == 'ok' else 0
failed = 1 - ok
metrics = [
'# HELP platform_quality_gate_checks_total Check outcomes from the latest lesavka gate run.',
'# TYPE platform_quality_gate_checks_total gauge',
f'platform_quality_gate_checks_total{{{labels},check="gate_glue",status="ok"}} {ok}',
f'platform_quality_gate_checks_total{{{labels},check="gate_glue",status="failed"}} {failed}',
]
metrics_path.write_text('\n'.join(metrics) + '\n', encoding='utf-8')
print(text_path.read_text(encoding='utf-8'))
if status != 'ok':
raise SystemExit(1)
PY
status=$?
if [[ -n "${PUSHGATEWAY_URL}" ]]; then
curl --fail --silent --show-error \
--data-binary @"${METRICS_FILE}" \
"${PUSHGATEWAY_URL%/}/metrics/job/lesavka-gate-glue-gate/suite/lesavka" || status=$?
fi
exit "${status}"