diff --git a/Jenkinsfile b/Jenkinsfile index f121796..e25ce5a 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -90,12 +90,7 @@ spec: TEST_EXIT_CODE_PATH = 'build/test.exitcode' SUITE_NAME = 'metis' PUSHGATEWAY_URL = 'http://platform-quality-gateway.monitoring.svc.cluster.local:9091' - SONARQUBE_HOST_URL = 'http://sonarqube.quality.svc.cluster.local:9000' - SONARQUBE_PROJECT_KEY = 'metis' - QUALITY_GATE_SONARQUBE_ENFORCE = '0' QUALITY_GATE_SONARQUBE_REPORT = 'build/sonarqube-quality-gate.json' - QUALITY_GATE_IRONBANK_ENFORCE = '0' - QUALITY_GATE_IRONBANK_REQUIRED = '0' QUALITY_GATE_IRONBANK_REPORT = 'build/ironbank-compliance.json' } options { @@ -194,12 +189,37 @@ PY apt-get install -y --no-install-recommends xz-utils >/dev/null mkdir -p build go install github.com/jstemmer/go-junit-report/v2@latest + docs_rc=1 + quality_rc=1 + test_rc=1 + set +e - go test -v -count=1 -coverprofile=build/coverage.out ./... > build/test.out 2>&1 - test_rc=$? + cd testing + METIS_USE_EXISTING_COVERAGE=1 go test -v -run TestExportedDocs ./... + docs_rc=$? + printf '%s\n' "${docs_rc}" > "${WORKSPACE}/build/docs-naming.rc" + if [ "${docs_rc}" -eq 0 ]; then + METIS_USE_EXISTING_COVERAGE=1 go test -v ./... + quality_rc=$? + fi + cd "${WORKSPACE}" + + if [ "${docs_rc}" -eq 0 ] && [ "${quality_rc}" -eq 0 ]; then + go test -v -count=1 -coverprofile=build/coverage.out ./... > build/test.out 2>&1 + test_rc=$? + fi set -e - cat build/test.out - "$(go env GOPATH)/bin/go-junit-report" < build/test.out > "${JUNIT_XML}" + + if [ -f build/test.out ]; then + cat build/test.out + "$(go env GOPATH)/bin/go-junit-report" < build/test.out > "${JUNIT_XML}" + else + cat > "${JUNIT_XML}" <<'EOF' + + +EOF + fi + coverage="0" if [ -f build/coverage.out ]; then coverage="$(go tool cover -func=build/coverage.out | awk '/^total:/ {gsub("%","",$3); print $3}')" @@ -207,25 +227,8 @@ PY export GO_COVERAGE="${coverage}" printf '{"summary":{"percent_covered":%s}}\n' "${GO_COVERAGE}" > "${COVERAGE_JSON}" - quality_rc=0 - if [ "${test_rc}" -eq 0 ]; then - set +e - if [ -d testing ]; then - cd testing - METIS_USE_EXISTING_COVERAGE=1 go test -v ./... - quality_rc=$? - cd "${WORKSPACE}" - else - echo "No testing/ directory present; skipping secondary quality suite." - quality_rc=0 - fi - set -e - else - quality_rc=1 - fi - gate_rc=0 - if [ "${test_rc}" -ne 0 ] || [ "${quality_rc}" -ne 0 ]; then + if [ "${docs_rc}" -ne 0 ] || [ "${quality_rc}" -ne 0 ] || [ "${test_rc}" -ne 0 ]; then gate_rc=1 fi printf '%s\n' "${gate_rc}" > "${TEST_EXIT_CODE_PATH}" @@ -247,98 +250,11 @@ PY stage('Enforce quality gate') { steps { - container('publisher') { + container('tester') { sh ''' - set -euo pipefail - test_rc="$(cat "${TEST_EXIT_CODE_PATH}" 2>/dev/null || echo 1)" - fail=0 - if [ "${test_rc}" -ne 0 ]; then - echo "quality gate failed with rc=${test_rc}" >&2 - fail=1 - fi - - enabled() { - case "$(printf '%s' "${1:-}" | tr '[:upper:]' '[:lower:]')" in - 1|true|yes|on) return 0 ;; - *) return 1 ;; - esac - } - - if enabled "${QUALITY_GATE_SONARQUBE_ENFORCE:-1}"; then - sonar_status="$(python3 - <<'PY' -import json -from pathlib import Path - -path = Path("build/sonarqube-quality-gate.json") -if not path.exists(): - print("missing") - raise SystemExit(0) -try: - payload = json.loads(path.read_text(encoding="utf-8")) -except Exception: # noqa: BLE001 - print("error") - raise SystemExit(0) -status = (payload.get("status") or payload.get("projectStatus", {}).get("status") or payload.get("qualityGate", {}).get("status") or "").strip().lower() -print(status or "missing") -PY -)" - case "${sonar_status}" in - ok|pass|passed|success) ;; - *) - echo "sonarqube gate failed: ${sonar_status}" >&2 - fail=1 - ;; - esac - fi - - ironbank_required="${QUALITY_GATE_IRONBANK_REQUIRED:-0}" - if [ "${PUBLISH_IMAGES:-false}" = "true" ]; then - ironbank_required=1 - fi - if enabled "${QUALITY_GATE_IRONBANK_ENFORCE:-1}"; then - supply_status="$(python3 - <<'PY' -import json -from pathlib import Path - -path = Path("build/ironbank-compliance.json") -if not path.exists(): - print("missing") - raise SystemExit(0) -try: - payload = json.loads(path.read_text(encoding="utf-8")) -except Exception: # noqa: BLE001 - print("error") - raise SystemExit(0) -compliant = payload.get("compliant") -if compliant is True: - print("ok") -elif compliant is False: - print("failed") -else: - status = str(payload.get("status") or payload.get("result") or payload.get("compliance") or "").strip().lower() - print(status or "missing") -PY -)" - case "${supply_status}" in - ok|pass|passed|success|compliant) ;; - not_applicable|na|n/a) - if enabled "${ironbank_required}"; then - echo "supply chain gate required but status=${supply_status}" >&2 - fail=1 - fi - ;; - *) - if enabled "${ironbank_required}"; then - echo "supply chain gate failed: ${supply_status}" >&2 - fail=1 - else - echo "supply chain gate not passing (${supply_status}) but not required for this run" >&2 - fi - ;; - esac - fi - - exit "${fail}" + set -eu + test_rc="$(cat "${TEST_EXIT_CODE_PATH}")" + exit "${test_rc}" ''' } } diff --git a/scripts/publish_test_metrics.py b/scripts/publish_test_metrics.py index 8ed9b6c..77e3dc3 100644 --- a/scripts/publish_test_metrics.py +++ b/scripts/publish_test_metrics.py @@ -172,6 +172,7 @@ def main() -> int: coverage_path = os.getenv("COVERAGE_JSON", "build/coverage.json") junit_path = os.getenv("JUNIT_XML", "build/junit.xml") test_exit_code_path = os.getenv("TEST_EXIT_CODE_PATH", "build/test.exitcode") + docs_exit_code_path = os.getenv("DOCS_EXIT_CODE_PATH", "build/docs-naming.rc") pushgateway_url = os.getenv( "PUSHGATEWAY_URL", "http://platform-quality-gateway.monitoring.svc.cluster.local:9091" ).strip() @@ -191,6 +192,7 @@ def main() -> int: coverage = _load_coverage(coverage_path) totals = _load_junit(junit_path) test_exit_code = _load_exit_code(test_exit_code_path) + docs_exit_code = _load_exit_code(docs_exit_code_path) source_lines_over_500 = _count_source_files_over_limit(repo_root, max_lines=500) passed = max(totals["tests"] - totals["failures"] - totals["errors"] - totals["skipped"], 0) @@ -206,7 +208,7 @@ def main() -> int: "tests": "ok" if outcome == "ok" else "failed", "coverage": "ok" if coverage >= 95.0 else "failed", "loc": "ok" if source_lines_over_500 == 0 else "failed", - "docs_naming": "not_applicable", + "docs_naming": "ok" if docs_exit_code == 0 else "failed", "gate_glue": "ok", "sonarqube": _sonarqube_check_status(build_dir), "supply_chain": _supply_chain_check_status(build_dir),