111 lines
4.0 KiB
Bash
111 lines
4.0 KiB
Bash
|
|
#!/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}"
|