diff --git a/Jenkinsfile b/Jenkinsfile index 4af4086..ecfe471 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -103,9 +103,31 @@ spec: mkdir -p build export GOFLAGS='-buildvcs=false' set +e - go test ./... -coverprofile=build/coverage.out - coverage_rc=$? + go test ./... -coverprofile=build/sonar-root.cover.out + root_rc=$? + ( + cd testing + go test ./config -coverpkg=scm.bstein.dev/bstein/ananke/... -coverprofile=../build/sonar-testing-config.cover.out + ) + config_rc=$? + ( + cd testing + go test ./execx ./metrics ./hygiene ./orchestrator ./state ./sshutil ./ups -coverpkg=scm.bstein.dev/bstein/ananke/... -coverprofile=../build/sonar-testing.cover.out + ) + testing_rc=$? set -e + coverage_rc=0 + if [ "${root_rc}" -ne 0 ] || [ "${config_rc}" -ne 0 ] || [ "${testing_rc}" -ne 0 ]; then + coverage_rc=1 + fi + if [ -s build/sonar-root.cover.out ] && [ -s build/sonar-testing-config.cover.out ] && [ -s build/sonar-testing.cover.out ]; then + { + head -n 1 build/sonar-root.cover.out + tail -n +2 build/sonar-root.cover.out + tail -n +2 build/sonar-testing-config.cover.out + tail -n +2 build/sonar-testing.cover.out + } > build/coverage.out + fi printf '%s\n' "${coverage_rc}" > build/sonarqube-coverage.rc ''' } @@ -138,23 +160,55 @@ spec: import base64 import json import os +import time import urllib.parse import urllib.request +from pathlib import Path host = os.getenv('SONARQUBE_HOST_URL', '').strip().rstrip('/') project_key = os.getenv('SONARQUBE_PROJECT_KEY', '').strip() token = os.getenv('SONARQUBE_TOKEN', '').strip() report_path = os.getenv('QUALITY_GATE_SONARQUBE_REPORT', 'build/sonarqube-quality-gate.json') payload = {"status": "ERROR", "note": "missing SONARQUBE_HOST_URL and/or SONARQUBE_PROJECT_KEY"} -if host and project_key: - query = urllib.parse.urlencode({"projectKey": project_key}) - request = urllib.request.Request(f"{host}/api/qualitygates/project_status?{query}", method="GET") + +def fetch_json(url): + request = urllib.request.Request(url, method="GET") if token: encoded = base64.b64encode(f"{token}:".encode("utf-8")).decode("utf-8") request.add_header("Authorization", f"Basic {encoded}") + with urllib.request.urlopen(request, timeout=12) as response: + return json.loads(response.read().decode("utf-8")) + +if host and project_key: + analysis_id = "" + task_id = "" + task_file = Path(".scannerwork/report-task.txt") + if task_file.exists(): + for line in task_file.read_text(encoding="utf-8", errors="ignore").splitlines(): + key, _, value = line.partition("=") + if key == "ceTaskId": + task_id = value.strip() + break try: - with urllib.request.urlopen(request, timeout=12) as response: - payload = json.loads(response.read().decode("utf-8")) + if task_id: + for _ in range(24): + task_payload = fetch_json( + f"{host}/api/ce/task?{urllib.parse.urlencode({'id': task_id})}" + ) + task = task_payload.get("task", {}) + task_status = str(task.get("status", "")).upper() + if task_status in {"SUCCESS", "FAILED", "CANCELED"}: + analysis_id = str(task.get("analysisId", "")).strip() + if task_status != "SUCCESS": + payload = {"status": "ERROR", "error": f"sonarqube task {task_status.lower()}"} + break + time.sleep(5) + else: + payload = {"status": "ERROR", "error": "timed out waiting for sonarqube task"} + if "error" not in payload: + params = {"analysisId": analysis_id} if analysis_id else {"projectKey": project_key} + query = urllib.parse.urlencode(params) + payload = fetch_json(f"{host}/api/qualitygates/project_status?{query}") except Exception as exc: # noqa: BLE001 payload = {"status": "ERROR", "error": str(exc)} with open(report_path, "w", encoding="utf-8") as handle: