diff --git a/Jenkinsfile b/Jenkinsfile index e32e4c1..9c850b0 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -71,6 +71,19 @@ spec: SUITE_NAME = 'soteria' PUSHGATEWAY_URL = 'http://platform-quality-gateway.monitoring.svc.cluster.local:9091' } + options { + disableConcurrentBuilds() + } + parameters { + booleanParam( + name: 'PUBLISH_IMAGES', + defaultValue: false, + description: 'Build and push the Soteria runtime image (enable for release runs).' + ) + } + triggers { + pollSCM('H/5 * * * *') + } stages { stage('Checkout') { steps { @@ -118,12 +131,77 @@ spec: "skipped": ${tests_skipped} } EOF + printf '%s\n' "${test_rc}" > build/test.exitcode + ''' + } + } + } + stage('Publish test metrics') { + steps { + container('tester') { + sh ''' + set -eu + apt-get update >/dev/null + apt-get install -y --no-install-recommends curl jq >/dev/null + suite="${SUITE_NAME}" + gateway="${PUSHGATEWAY_URL}" + test_rc="$(cat build/test.exitcode 2>/dev/null || echo 1)" + status="ok" + if [ "${test_rc}" -ne 0 ]; then + status="failed" + fi + fetch_counter() { + status_name="$1" + line="$(curl -fsS "${gateway}/metrics" 2>/dev/null | awk -v suite="${suite}" -v status="${status_name}" ' + /platform_quality_gate_runs_total/ { + if (index($0, "job=\\"platform-quality-ci\\"") && index($0, "suite=\\"" suite "\\"") && index($0, "status=\\"" status "\\"")) { + print $2 + exit + } + } + ' || true)" + [ -n "${line}" ] && printf '%s\n' "${line}" || printf '0\n' + } + ok_count="$(fetch_counter ok)" + failed_count="$(fetch_counter failed)" + if [ "${status}" = "ok" ]; then + ok_count=$((ok_count + 1)) + else + failed_count=$((failed_count + 1)) + fi + tests_passed="$(jq -r '.passed // 0' build/test-summary.json 2>/dev/null || echo 0)" + tests_failed="$(jq -r '.failed // 0' build/test-summary.json 2>/dev/null || echo 0)" + tests_errors="$(jq -r '.errors // 0' build/test-summary.json 2>/dev/null || echo 0)" + tests_skipped="$(jq -r '.skipped // 0' build/test-summary.json 2>/dev/null || echo 0)" + cat </dev/null +# TYPE platform_quality_gate_runs_total counter +platform_quality_gate_runs_total{suite="${suite}",status="ok"} ${ok_count} +platform_quality_gate_runs_total{suite="${suite}",status="failed"} ${failed_count} +# TYPE soteria_quality_gate_tests_total gauge +soteria_quality_gate_tests_total{suite="${suite}",result="passed"} ${tests_passed} +soteria_quality_gate_tests_total{suite="${suite}",result="failed"} ${tests_failed} +soteria_quality_gate_tests_total{suite="${suite}",result="error"} ${tests_errors} +soteria_quality_gate_tests_total{suite="${suite}",result="skipped"} ${tests_skipped} +METRICS + ''' + } + } + } + stage('Enforce test result') { + steps { + container('tester') { + sh ''' + set -eu + test_rc="$(cat build/test.exitcode 2>/dev/null || echo 1)" exit "${test_rc}" ''' } } } stage('Compute version') { + when { + expression { return params.PUBLISH_IMAGES } + } steps { container('builder') { script { @@ -139,6 +217,9 @@ EOF } } stage('Buildx setup') { + when { + expression { return params.PUBLISH_IMAGES } + } steps { container('builder') { sh ''' @@ -154,6 +235,9 @@ EOF } } stage('Build & push image') { + when { + expression { return params.PUBLISH_IMAGES } + } steps { container('builder') { withCredentials([usernamePassword(credentialsId: 'harbor-robot', usernameVariable: 'HARBOR_USERNAME', passwordVariable: 'HARBOR_PASSWORD')]) { @@ -173,82 +257,6 @@ EOF } } post { - success { - container('builder') { - sh ''' - set -eu - suite="${SUITE_NAME}" - gateway="${PUSHGATEWAY_URL}" - fetch_counter() { - status="$1" - line="$(curl -fsS "${gateway}/metrics" 2>/dev/null | awk -v suite="${suite}" -v status="${status}" ' - /platform_quality_gate_runs_total/ { - if (index($0, "job=\\"platform-quality-ci\\"") && index($0, "suite=\\"" suite "\\"") && index($0, "status=\\"" status "\\"")) { - print $2 - exit - } - } - ' || true)" - [ -n "${line}" ] && printf '%s\n' "${line}" || printf '0\n' - } - ok_count="$(fetch_counter ok)" - failed_count="$(fetch_counter failed)" - ok_count=$((ok_count + 1)) - tests_passed="$(jq -r '.passed // 0' build/test-summary.json 2>/dev/null || echo 0)" - tests_failed="$(jq -r '.failed // 0' build/test-summary.json 2>/dev/null || echo 0)" - tests_errors="$(jq -r '.errors // 0' build/test-summary.json 2>/dev/null || echo 0)" - tests_skipped="$(jq -r '.skipped // 0' build/test-summary.json 2>/dev/null || echo 0)" - cat </dev/null -# TYPE platform_quality_gate_runs_total counter -platform_quality_gate_runs_total{suite="${suite}",status="ok"} ${ok_count} -platform_quality_gate_runs_total{suite="${suite}",status="failed"} ${failed_count} -# TYPE soteria_quality_gate_tests_total gauge -soteria_quality_gate_tests_total{suite="${suite}",result="passed"} ${tests_passed} -soteria_quality_gate_tests_total{suite="${suite}",result="failed"} ${tests_failed} -soteria_quality_gate_tests_total{suite="${suite}",result="error"} ${tests_errors} -soteria_quality_gate_tests_total{suite="${suite}",result="skipped"} ${tests_skipped} -METRICS - ''' - } - } - failure { - container('builder') { - sh ''' - set -eu - suite="${SUITE_NAME}" - gateway="${PUSHGATEWAY_URL}" - fetch_counter() { - status="$1" - line="$(curl -fsS "${gateway}/metrics" 2>/dev/null | awk -v suite="${suite}" -v status="${status}" ' - /platform_quality_gate_runs_total/ { - if (index($0, "job=\\"platform-quality-ci\\"") && index($0, "suite=\\"" suite "\\"") && index($0, "status=\\"" status "\\"")) { - print $2 - exit - } - } - ' || true)" - [ -n "${line}" ] && printf '%s\n' "${line}" || printf '0\n' - } - ok_count="$(fetch_counter ok)" - failed_count="$(fetch_counter failed)" - failed_count=$((failed_count + 1)) - tests_passed="$(jq -r '.passed // 0' build/test-summary.json 2>/dev/null || echo 0)" - tests_failed="$(jq -r '.failed // 0' build/test-summary.json 2>/dev/null || echo 0)" - tests_errors="$(jq -r '.errors // 0' build/test-summary.json 2>/dev/null || echo 0)" - tests_skipped="$(jq -r '.skipped // 0' build/test-summary.json 2>/dev/null || echo 0)" - cat </dev/null -# TYPE platform_quality_gate_runs_total counter -platform_quality_gate_runs_total{suite="${suite}",status="ok"} ${ok_count} -platform_quality_gate_runs_total{suite="${suite}",status="failed"} ${failed_count} -# TYPE soteria_quality_gate_tests_total gauge -soteria_quality_gate_tests_total{suite="${suite}",result="passed"} ${tests_passed} -soteria_quality_gate_tests_total{suite="${suite}",result="failed"} ${tests_failed} -soteria_quality_gate_tests_total{suite="${suite}",result="error"} ${tests_errors} -soteria_quality_gate_tests_total{suite="${suite}",result="skipped"} ${tests_skipped} -METRICS - ''' - } - } always { script { if (fileExists('build.env')) {