diff --git a/Jenkinsfile b/Jenkinsfile index 2203301..90a316f 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -42,7 +42,12 @@ spec: environment { SUITE_NAME = 'pegasus' PUSHGATEWAY_URL = 'http://platform-quality-gateway.monitoring.svc.cluster.local:9091' + SONARQUBE_HOST_URL = 'http://sonarqube.quality.svc.cluster.local:9000' + SONARQUBE_PROJECT_KEY = 'pegasus' + 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' } @@ -208,10 +213,105 @@ PY steps { container('publisher') { sh ''' - set -eu + set -euo pipefail apt-get update apt-get install -y --no-install-recommends golang-go nodejs npm + set +e python -m testing.pegasus_gate enforce + gate_rc=$? + set -e + fail=0 + if [ "${gate_rc}" -ne 0 ]; then + echo "quality gate failed with rc=${gate_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=0 + if enabled "${QUALITY_GATE_IRONBANK_REQUIRED:-0}"; then + ironbank_required=1 + fi + if enabled "${PUBLISH_IMAGES:-0}"; then + ironbank_required=1 + fi + if enabled "${QUALITY_GATE_IRONBANK_ENFORCE:-1}" || [ "${ironbank_required}" -eq 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) + +status = payload.get("status") +if isinstance(status, str) and status.strip(): + print(status.strip().lower()) + raise SystemExit(0) +compliant = payload.get("compliant") +if isinstance(compliant, bool): + print("ok" if compliant else "failed") + raise SystemExit(0) +print("unknown") +PY +)" + case "${supply_status}" in + ok|pass|passed|success|compliant) + ;; + not_applicable) + if [ "${ironbank_required}" -eq 1 ]; then + echo "Supply-chain check is not applicable but required for this build" >&2 + fail=1 + fi + ;; + *) + echo "Supply-chain check failed: ${supply_status}" >&2 + fail=1 + ;; + esac + fi + + if [ "${fail}" -ne 0 ]; then + exit 1 + fi ''' } }