ci: publish complete gate telemetry
This commit is contained in:
parent
1da08ba589
commit
e684bf9670
@ -8,6 +8,7 @@ SUMMARY_JSON="${REPORT_DIR}/summary.json"
|
||||
SUMMARY_TXT="${REPORT_DIR}/summary.txt"
|
||||
METRICS_FILE="${REPORT_DIR}/metrics.prom"
|
||||
PUSHGATEWAY_URL=${QUALITY_GATE_PUSHGATEWAY_URL:-}
|
||||
PUSHGATEWAY_JOB=${LESAVKA_GATE_GLUE_PUSHGATEWAY_JOB:-platform-quality-ci}
|
||||
|
||||
mkdir -p "${REPORT_DIR}"
|
||||
cd "${ROOT_DIR}"
|
||||
@ -21,7 +22,8 @@ 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'
|
||||
status=0
|
||||
python3 - "${SUMMARY_JSON}" "${SUMMARY_TXT}" "${METRICS_FILE}" "${branch}" "${commit}" "${ROOT_DIR}" <<'PY' || status=$?
|
||||
import json
|
||||
import pathlib
|
||||
import sys
|
||||
@ -99,12 +101,11 @@ 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=$?
|
||||
"${PUSHGATEWAY_URL%/}/metrics/job/${PUSHGATEWAY_JOB}/suite/lesavka/gate/gate-glue" || status=$?
|
||||
fi
|
||||
|
||||
exit "${status}"
|
||||
|
||||
@ -8,6 +8,8 @@ SUMMARY_TXT="${REPORT_DIR}/summary.txt"
|
||||
BASELINE_JSON="${ROOT_DIR}/scripts/ci/hygiene_gate_baseline.json"
|
||||
METADATA_JSON="${REPORT_DIR}/cargo-metadata.json"
|
||||
METRICS_FILE="${REPORT_DIR}/metrics.prom"
|
||||
PUSHGATEWAY_URL=${QUALITY_GATE_PUSHGATEWAY_URL:-}
|
||||
PUSHGATEWAY_JOB=${LESAVKA_HYGIENE_GATE_PUSHGATEWAY_JOB:-platform-quality-ci}
|
||||
|
||||
mkdir -p "${REPORT_DIR}"
|
||||
|
||||
@ -25,7 +27,8 @@ if [[ -z "${commit}" ]]; then
|
||||
commit=$(git -C "${ROOT_DIR}" rev-parse --short HEAD 2>/dev/null || echo unknown)
|
||||
fi
|
||||
|
||||
python3 - "${CLIPPY_JSON}" "${BASELINE_JSON}" "${SUMMARY_TXT}" "${ROOT_DIR}" "${METRICS_FILE}" "${branch}" "${commit}" <<'PY'
|
||||
status=0
|
||||
python3 - "${CLIPPY_JSON}" "${BASELINE_JSON}" "${SUMMARY_TXT}" "${ROOT_DIR}" "${METRICS_FILE}" "${branch}" "${commit}" <<'PY' || status=$?
|
||||
import json
|
||||
import os
|
||||
import pathlib
|
||||
@ -530,3 +533,18 @@ if failed:
|
||||
print(line, file=sys.stderr)
|
||||
raise SystemExit(1)
|
||||
PY
|
||||
|
||||
publish_status=0
|
||||
if [[ -n "${PUSHGATEWAY_URL}" ]]; then
|
||||
curl --fail --silent --show-error \
|
||||
--data-binary @"${METRICS_FILE}" \
|
||||
"${PUSHGATEWAY_URL%/}/metrics/job/${PUSHGATEWAY_JOB}/suite/lesavka/gate/hygiene" || publish_status=$?
|
||||
else
|
||||
echo "Skipping hygiene metrics publish: QUALITY_GATE_PUSHGATEWAY_URL is not set"
|
||||
fi
|
||||
|
||||
if [[ "${status}" -eq 0 && "${publish_status}" -ne 0 ]]; then
|
||||
status="${publish_status}"
|
||||
fi
|
||||
|
||||
exit "${status}"
|
||||
|
||||
@ -10,7 +10,7 @@ SUMMARY_TXT="${REPORT_DIR}/summary.txt"
|
||||
METRICS_FILE="${REPORT_DIR}/metrics.prom"
|
||||
STATUS_FILE="${REPORT_DIR}/gate-status.txt"
|
||||
PUSHGATEWAY_URL=${QUALITY_GATE_PUSHGATEWAY_URL:-}
|
||||
PUSHGATEWAY_JOB=${LESAVKA_MEDIA_GATE_PUSHGATEWAY_JOB:-lesavka-media-reliability-gate}
|
||||
PUSHGATEWAY_JOB=${LESAVKA_MEDIA_GATE_PUSHGATEWAY_JOB:-platform-quality-ci}
|
||||
SYNC_PROBE_REPORT_JSON=${LESAVKA_SYNC_PROBE_REPORT_JSON:-}
|
||||
SYNC_PROBE_REPORT_DIR=${LESAVKA_SYNC_PROBE_REPORT_DIR:-}
|
||||
REQUIRE_SYNC_PROBE=${LESAVKA_REQUIRE_SYNC_PROBE:-0}
|
||||
@ -279,7 +279,7 @@ status=$(cat "${STATUS_FILE}")
|
||||
if [[ -n "${PUSHGATEWAY_URL}" ]]; then
|
||||
curl --fail --silent --show-error \
|
||||
--data-binary @"${METRICS_FILE}" \
|
||||
"${PUSHGATEWAY_URL%/}/metrics/job/${PUSHGATEWAY_JOB}/suite/lesavka" || status=$?
|
||||
"${PUSHGATEWAY_URL%/}/metrics/job/${PUSHGATEWAY_JOB}/suite/lesavka/gate/media-reliability" || status=$?
|
||||
fi
|
||||
|
||||
exit "${status}"
|
||||
|
||||
@ -7,7 +7,7 @@ REPORT_DIR="${ROOT_DIR}/target/performance-gate"
|
||||
TEST_LOG="${REPORT_DIR}/cargo-test.log"
|
||||
METRICS_FILE="${REPORT_DIR}/metrics.prom"
|
||||
PUSHGATEWAY_URL=${QUALITY_GATE_PUSHGATEWAY_URL:-}
|
||||
PUSHGATEWAY_JOB=${LESAVKA_PERFORMANCE_GATE_PUSHGATEWAY_JOB:-lesavka-performance-gate}
|
||||
PUSHGATEWAY_JOB=${LESAVKA_PERFORMANCE_GATE_PUSHGATEWAY_JOB:-platform-quality-ci}
|
||||
|
||||
mkdir -p "${REPORT_DIR}"
|
||||
cd "${ROOT_DIR}"
|
||||
@ -68,7 +68,7 @@ PY
|
||||
if [[ -n "${PUSHGATEWAY_URL}" ]]; then
|
||||
curl --fail --silent --show-error \
|
||||
--data-binary @"${METRICS_FILE}" \
|
||||
"${PUSHGATEWAY_URL%/}/metrics/job/${PUSHGATEWAY_JOB}/suite/lesavka" || status=$?
|
||||
"${PUSHGATEWAY_URL%/}/metrics/job/${PUSHGATEWAY_JOB}/suite/lesavka/gate/performance" || status=$?
|
||||
fi
|
||||
|
||||
exit "${status}"
|
||||
|
||||
@ -103,6 +103,90 @@ publish_metrics() {
|
||||
"${PUSHGATEWAY_URL%/}/metrics/job/platform-quality-ci/suite/lesavka"
|
||||
}
|
||||
|
||||
write_fallback_quality_metrics() {
|
||||
python3 - "${METRICS_FILE}" "${ROOT_DIR}" "${branch}" "${commit}" "${build_number}" "${jenkins_job}" <<'PY'
|
||||
import pathlib
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
metrics_path = pathlib.Path(sys.argv[1])
|
||||
root = pathlib.Path(sys.argv[2])
|
||||
branch = sys.argv[3]
|
||||
commit = sys.argv[4]
|
||||
build_number = sys.argv[5]
|
||||
jenkins_job = sys.argv[6]
|
||||
|
||||
def run_git(*args: str) -> list[str]:
|
||||
proc = subprocess.run(
|
||||
['git', '-C', str(root), *args],
|
||||
check=True,
|
||||
text=True,
|
||||
capture_output=True,
|
||||
)
|
||||
return [line for line in proc.stdout.splitlines() if line]
|
||||
|
||||
def repo_files() -> list[str]:
|
||||
tracked = run_git('ls-files')
|
||||
untracked = run_git('ls-files', '--others', '--exclude-standard')
|
||||
return sorted(set(tracked + untracked))
|
||||
|
||||
def is_test_path(rel: str) -> bool:
|
||||
return 'tests' in pathlib.Path(rel).parts
|
||||
|
||||
def esc(value: str) -> str:
|
||||
return value.replace('\\', r'\\').replace('\n', r'\\n').replace('"', r'\"')
|
||||
|
||||
source_files: list[str] = []
|
||||
source_loc_over_500: list[str] = []
|
||||
for rel in repo_files():
|
||||
if not rel.endswith('.rs') or '/src/' not in rel or is_test_path(rel):
|
||||
continue
|
||||
path = root / rel
|
||||
if not path.exists() or path.is_dir():
|
||||
continue
|
||||
source_files.append(rel)
|
||||
loc = sum(1 for _ in path.open('r', encoding='utf-8'))
|
||||
if loc > 500:
|
||||
source_loc_over_500.append(rel)
|
||||
|
||||
labels = f'suite="lesavka",branch="{esc(branch)}",commit="{esc(commit)}"'
|
||||
build_labels = f'{labels},build_number="{esc(build_number)}",jenkins_job="{esc(jenkins_job)}"'
|
||||
loc_ok_value = 0 if source_loc_over_500 else 1
|
||||
loc_failed_value = 1 if source_loc_over_500 else 0
|
||||
metrics = [
|
||||
'# HELP platform_quality_gate_runs_total Number of quality gate runs by result.',
|
||||
'# TYPE platform_quality_gate_runs_total counter',
|
||||
f'platform_quality_gate_runs_total{{{labels},status="failed"}} 1',
|
||||
'# HELP platform_quality_gate_build_info Build metadata for the latest lesavka gate run.',
|
||||
'# TYPE platform_quality_gate_build_info gauge',
|
||||
f'platform_quality_gate_build_info{{{build_labels}}} 1',
|
||||
'# 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="coverage",status="ok"}} 0',
|
||||
f'platform_quality_gate_checks_total{{{labels},check="coverage",status="failed"}} 1',
|
||||
f'platform_quality_gate_checks_total{{{labels},check="loc",status="ok"}} {loc_ok_value}',
|
||||
f'platform_quality_gate_checks_total{{{labels},check="loc",status="failed"}} {loc_failed_value}',
|
||||
]
|
||||
for check in ('tests', 'style', 'media_reliability', 'gate_glue', 'sonarqube', 'supply_chain'):
|
||||
metrics.append(f'platform_quality_gate_checks_total{{{labels},check="{check}",status="not_applicable"}} 1')
|
||||
metrics.extend([
|
||||
'# HELP platform_quality_gate_workspace_line_coverage_percent Workspace line coverage percent.',
|
||||
'# TYPE platform_quality_gate_workspace_line_coverage_percent gauge',
|
||||
f'platform_quality_gate_workspace_line_coverage_percent{{{labels}}} 0',
|
||||
'# HELP platform_quality_gate_source_files_total Count of tracked source files in the source LOC gate.',
|
||||
'# TYPE platform_quality_gate_source_files_total gauge',
|
||||
f'platform_quality_gate_source_files_total{{{labels}}} {len(source_files)}',
|
||||
'# HELP platform_quality_gate_source_lines_over_500_total Count of tracked source files over 500 LOC.',
|
||||
'# TYPE platform_quality_gate_source_lines_over_500_total gauge',
|
||||
f'platform_quality_gate_source_lines_over_500_total{{{labels}}} {len(source_loc_over_500)}',
|
||||
'# HELP platform_quality_gate_repo_source_lines_over_500_total Count of repo source files over 500 LOC, including untracked working-tree files.',
|
||||
'# TYPE platform_quality_gate_repo_source_lines_over_500_total gauge',
|
||||
f'platform_quality_gate_repo_source_lines_over_500_total{{{labels}}} {len(source_loc_over_500)}',
|
||||
])
|
||||
metrics_path.write_text('\n'.join(metrics) + '\n', encoding='utf-8')
|
||||
PY
|
||||
}
|
||||
|
||||
status=0
|
||||
# Several integration contracts intentionally mutate process environment and
|
||||
# probe singleton runtime state. Keep coverage collection serial so per-file
|
||||
@ -191,6 +275,7 @@ for rel, counts in sorted(lcov_counts.items()):
|
||||
})
|
||||
|
||||
files.sort(key=lambda item: item['path'])
|
||||
source_files = []
|
||||
source_loc_over_500 = []
|
||||
for rel in repo_files():
|
||||
if not rel.endswith('.rs') or '/src/' not in rel:
|
||||
@ -200,6 +285,7 @@ for rel in repo_files():
|
||||
path = root / rel
|
||||
if not path.exists() or path.is_dir():
|
||||
continue
|
||||
source_files.append(rel)
|
||||
loc = sum(1 for _ in path.open('r', encoding='utf-8'))
|
||||
if loc > 500:
|
||||
source_loc_over_500.append(f'{rel}: source file exceeds 500 LOC ({loc})')
|
||||
@ -293,6 +379,9 @@ metrics.append(f'platform_quality_gate_workspace_line_coverage_percent{{{labels}
|
||||
metrics.append('# HELP platform_quality_gate_files_total Count of tracked source files in the quality gate.')
|
||||
metrics.append('# TYPE platform_quality_gate_files_total gauge')
|
||||
metrics.append(f'platform_quality_gate_files_total{{{labels}}} {len(files)}')
|
||||
metrics.append('# HELP platform_quality_gate_source_files_total Count of tracked source files in the source LOC gate.')
|
||||
metrics.append('# TYPE platform_quality_gate_source_files_total gauge')
|
||||
metrics.append(f'platform_quality_gate_source_files_total{{{labels}}} {len(source_files)}')
|
||||
metrics.append('# HELP platform_quality_gate_files_at_or_above_95_total Count of files at or above the 95 percent line target.')
|
||||
metrics.append('# TYPE platform_quality_gate_files_at_or_above_95_total gauge')
|
||||
metrics.append(f'platform_quality_gate_files_at_or_above_95_total{{{labels}}} {files_at_95}')
|
||||
@ -410,6 +499,9 @@ else
|
||||
fi
|
||||
|
||||
publish_status=0
|
||||
if ! grep -q '^platform_quality_gate_checks_total{' "${METRICS_FILE}"; then
|
||||
write_fallback_quality_metrics
|
||||
fi
|
||||
refresh_counter_metrics
|
||||
if publish_metrics; then
|
||||
:
|
||||
|
||||
@ -8,6 +8,7 @@ SUMMARY_JSON="${REPORT_DIR}/summary.json"
|
||||
SUMMARY_TXT="${REPORT_DIR}/summary.txt"
|
||||
METRICS_FILE="${REPORT_DIR}/metrics.prom"
|
||||
PUSHGATEWAY_URL=${QUALITY_GATE_PUSHGATEWAY_URL:-}
|
||||
PUSHGATEWAY_JOB=${LESAVKA_SONAR_GATE_PUSHGATEWAY_JOB:-platform-quality-ci}
|
||||
ENFORCE=${LESAVKA_SONAR_ENFORCE:-0}
|
||||
|
||||
mkdir -p "${REPORT_DIR}"
|
||||
@ -92,7 +93,7 @@ PY
|
||||
if [[ -n "${PUSHGATEWAY_URL}" ]]; then
|
||||
curl --fail --silent --show-error \
|
||||
--data-binary @"${METRICS_FILE}" \
|
||||
"${PUSHGATEWAY_URL%/}/metrics/job/lesavka-sonarqube-gate/suite/lesavka" || status=$?
|
||||
"${PUSHGATEWAY_URL%/}/metrics/job/${PUSHGATEWAY_JOB}/suite/lesavka/gate/sonarqube" || status=$?
|
||||
fi
|
||||
|
||||
exit "${status}"
|
||||
|
||||
@ -11,6 +11,7 @@ SBOM_JSON="${REPORT_DIR}/sbom.cargo-metadata.json"
|
||||
TREE_TXT="${REPORT_DIR}/dependency-tree.txt"
|
||||
SECRET_TXT="${REPORT_DIR}/secret-scan.txt"
|
||||
PUSHGATEWAY_URL=${QUALITY_GATE_PUSHGATEWAY_URL:-}
|
||||
PUSHGATEWAY_JOB=${LESAVKA_SUPPLY_CHAIN_PUSHGATEWAY_JOB:-platform-quality-ci}
|
||||
ENFORCE_TOOLS=${LESAVKA_SUPPLY_CHAIN_ENFORCE_TOOLS:-0}
|
||||
|
||||
mkdir -p "${REPORT_DIR}"
|
||||
@ -138,7 +139,7 @@ PY
|
||||
if [[ -n "${PUSHGATEWAY_URL}" ]]; then
|
||||
curl --fail --silent --show-error \
|
||||
--data-binary @"${METRICS_FILE}" \
|
||||
"${PUSHGATEWAY_URL%/}/metrics/job/lesavka-supply-chain-gate/suite/lesavka" || status=$?
|
||||
"${PUSHGATEWAY_URL%/}/metrics/job/${PUSHGATEWAY_JOB}/suite/lesavka/gate/supply-chain" || status=$?
|
||||
fi
|
||||
|
||||
exit "${status}"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user