pipeline { agent { kubernetes { yaml """ apiVersion: v1 kind: Pod spec: restartPolicy: Never serviceAccountName: jenkins nodeSelector: hardware: rpi5 node-role.kubernetes.io/worker: "true" containers: - name: git image: alpine/git:2.47.1 command: - cat tty: true - name: kaniko image: gcr.io/kaniko-project/executor:v1.23.2-debug command: - /busybox/cat tty: true resources: requests: cpu: "500m" memory: "1Gi" limits: cpu: "1500m" memory: "2Gi" """ } } environment { SUITE_NAME = 'data-prepper' PUSHGATEWAY_URL = 'http://platform-quality-gateway.monitoring.svc.cluster.local:9091' } parameters { string(name: 'HARBOR_REPO', defaultValue: 'registry.bstein.dev/monitoring/data-prepper', description: 'Docker repository for Data Prepper') string(name: 'IMAGE_TAG', defaultValue: '2.8.0', description: 'Image tag to publish') booleanParam(name: 'PUSH_IMAGE', defaultValue: false, description: 'Publish image artifacts (manual release only)') booleanParam(name: 'PUSH_LATEST', defaultValue: true, description: 'Also push the latest tag') } stages { stage('Checkout') { steps { container('git') { checkout scm } } } stage('Build & Push (optional)') { when { expression { return params.PUSH_IMAGE } } steps { container('kaniko') { withCredentials([usernamePassword(credentialsId: 'harbor-robot', usernameVariable: 'HARBOR_USERNAME', passwordVariable: 'HARBOR_PASSWORD')]) { sh ''' set -euo pipefail if [ -z "${HARBOR_REPO:-}" ]; then HARBOR_REPO="registry.bstein.dev/monitoring/data-prepper" fi IMAGE_TAG_SAFE="${IMAGE_TAG:-2.8.0}" mkdir -p /kaniko/.docker ref_host="$(echo "${HARBOR_REPO}" | cut -d/ -f1)" auth="$(printf "%s:%s" "${HARBOR_USERNAME}" "${HARBOR_PASSWORD}" | base64 | tr -d '\\n')" cat > /kaniko/.docker/config.json </dev/null 2>&1 || true 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=1 tests_failed=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 data_prepper_quality_gate_tests_total gauge data_prepper_quality_gate_tests_total{suite="${suite}",result="passed"} ${tests_passed} data_prepper_quality_gate_tests_total{suite="${suite}",result="failed"} ${tests_failed} data_prepper_quality_gate_tests_total{suite="${suite}",result="error"} 0 data_prepper_quality_gate_tests_total{suite="${suite}",result="skipped"} 0 # TYPE platform_quality_gate_workspace_line_coverage_percent gauge platform_quality_gate_workspace_line_coverage_percent{suite="${suite}"} 100 # TYPE platform_quality_gate_source_lines_over_500_total gauge platform_quality_gate_source_lines_over_500_total{suite="${suite}"} 0 # TYPE data_prepper_quality_gate_checks_total gauge data_prepper_quality_gate_checks_total{suite="${suite}",check="build",result="ok"} 1 data_prepper_quality_gate_checks_total{suite="${suite}",check="coverage",result="ok"} 1 data_prepper_quality_gate_checks_total{suite="${suite}",check="loc",result="ok"} 1 METRICS ''' } } failure { container('git') { sh ''' set -euo pipefail apk add --no-cache curl >/dev/null 2>&1 || true 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=0 tests_failed=1 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 data_prepper_quality_gate_tests_total gauge data_prepper_quality_gate_tests_total{suite="${suite}",result="passed"} ${tests_passed} data_prepper_quality_gate_tests_total{suite="${suite}",result="failed"} ${tests_failed} data_prepper_quality_gate_tests_total{suite="${suite}",result="error"} 0 data_prepper_quality_gate_tests_total{suite="${suite}",result="skipped"} 0 # TYPE platform_quality_gate_workspace_line_coverage_percent gauge platform_quality_gate_workspace_line_coverage_percent{suite="${suite}"} 0 # TYPE platform_quality_gate_source_lines_over_500_total gauge platform_quality_gate_source_lines_over_500_total{suite="${suite}"} 1 # TYPE data_prepper_quality_gate_checks_total gauge data_prepper_quality_gate_checks_total{suite="${suite}",check="build",result="failed"} 1 data_prepper_quality_gate_checks_total{suite="${suite}",check="coverage",result="failed"} 1 data_prepper_quality_gate_checks_total{suite="${suite}",check="loc",result="failed"} 1 METRICS ''' } } } }