#!/usr/bin/env bash # Run or account for SonarQube analysis in the Atlas quality contract. set -euo pipefail ROOT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd) REPORT_DIR="${ROOT_DIR}/target/sonarqube-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:-} ENFORCE=${LESAVKA_SONAR_ENFORCE:-0} 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 status=0 sonar_status=not_applicable reason='SONARQUBE_HOST_URL, SONARQUBE_TOKEN, or sonar-scanner is unavailable' if [[ -n "${SONARQUBE_HOST_URL:-}" && -n "${SONARQUBE_TOKEN:-}" ]] && command -v sonar-scanner >/dev/null 2>&1; then sonar_status=ok reason='sonar-scanner completed' if ! sonar-scanner \ -Dsonar.projectKey=lesavka \ -Dsonar.projectName=lesavka \ -Dsonar.sources=client/src,server/src,common/src,testing/src \ -Dsonar.tests=testing/tests \ -Dsonar.host.url="${SONARQUBE_HOST_URL}" \ -Dsonar.token="${SONARQUBE_TOKEN}" \ >"${REPORT_DIR}/sonar-scanner.log" 2>&1; then sonar_status=failed reason='sonar-scanner failed; see sonar-scanner.log' status=1 fi elif [[ "${ENFORCE}" == "1" ]]; then sonar_status=failed status=1 fi python3 - "${SUMMARY_JSON}" "${SUMMARY_TXT}" "${METRICS_FILE}" "${sonar_status}" "${reason}" "${branch}" "${commit}" <<'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]) sonar_status = sys.argv[4] reason = sys.argv[5] branch = sys.argv[6] commit = sys.argv[7] def esc(value: str) -> str: return value.replace('\\', r'\\').replace('\n', r'\n').replace('"', r'\"') summary = { 'suite': 'lesavka', 'check': 'sonarqube', 'status': sonar_status, 'reason': reason, 'branch': branch, 'commit': commit, 'generated_at': datetime.now(timezone.utc).isoformat(), } summary_path.write_text(json.dumps(summary, indent=2, sort_keys=True) + '\n', encoding='utf-8') text_path.write_text( f'sonarqube gate report\nstatus: {sonar_status}\nreason: {reason}\nbranch: {branch}\ncommit: {commit}\n', encoding='utf-8', ) labels = f'suite="lesavka",branch="{esc(branch)}",commit="{esc(commit)}"' statuses = {'ok': 0, 'failed': 0, 'not_applicable': 0} statuses[sonar_status] = 1 metrics = [ '# HELP platform_quality_gate_checks_total Check outcomes from the latest lesavka gate run.', '# TYPE platform_quality_gate_checks_total gauge', ] for state, value in statuses.items(): metrics.append(f'platform_quality_gate_checks_total{{{labels},check="sonarqube",status="{state}"}} {value}') metrics_path.write_text('\n'.join(metrics) + '\n', encoding='utf-8') print(text_path.read_text(encoding='utf-8')) 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=$? fi exit "${status}"