ci: add backend quality gate and pushgateway status
This commit is contained in:
parent
2a3ee95e74
commit
4447174108
117
Jenkinsfile
vendored
117
Jenkinsfile
vendored
@ -44,6 +44,13 @@ spec:
|
||||
mountPath: /root/.docker
|
||||
- name: harbor-config
|
||||
mountPath: /docker-config
|
||||
- name: tester
|
||||
image: python:3.12-slim
|
||||
command: ["cat"]
|
||||
tty: true
|
||||
volumeMounts:
|
||||
- name: workspace-volume
|
||||
mountPath: /home/jenkins/agent
|
||||
volumes:
|
||||
- name: workspace-volume
|
||||
emptyDir: {}
|
||||
@ -67,6 +74,8 @@ spec:
|
||||
BACK_IMAGE = "${REGISTRY}/bstein-dev-home-backend"
|
||||
VERSION_TAG = 'dev'
|
||||
SEMVER = 'dev'
|
||||
SUITE_NAME = 'bstein-home'
|
||||
PUSHGATEWAY_URL = 'http://platform-quality-gateway.monitoring.svc.cluster.local:9091'
|
||||
}
|
||||
options {
|
||||
disableConcurrentBuilds()
|
||||
@ -88,7 +97,7 @@ spec:
|
||||
sh '''
|
||||
set -euo pipefail
|
||||
for attempt in 1 2 3 4 5; do
|
||||
if apk add --no-cache bash git jq; then
|
||||
if apk add --no-cache bash git jq curl; then
|
||||
break
|
||||
fi
|
||||
if [ "$attempt" -eq 5 ]; then
|
||||
@ -142,13 +151,26 @@ spec:
|
||||
sleep 2
|
||||
done
|
||||
docker buildx create --name bstein-builder --driver docker-container \
|
||||
--driver-opt image=registry.bstein.dev/bstein/buildkit:buildx-stable-1-arm64 \
|
||||
--driver-opt image=moby/buildkit:buildx-stable-1 \
|
||||
--bootstrap --use || docker buildx use bstein-builder
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Backend unit tests') {
|
||||
steps {
|
||||
container('tester') {
|
||||
sh '''
|
||||
set -euo pipefail
|
||||
mkdir -p build
|
||||
python -m pip install --no-cache-dir -r backend/requirements.txt pytest pytest-mock
|
||||
python -m pytest backend/tests -q --junitxml=build/junit-backend.xml
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Build & push frontend') {
|
||||
steps {
|
||||
container('builder') {
|
||||
@ -187,11 +209,102 @@ spec:
|
||||
}
|
||||
|
||||
post {
|
||||
success {
|
||||
container('tester') {
|
||||
sh '''
|
||||
set -euo pipefail
|
||||
export QUALITY_STATUS=ok
|
||||
python - <<'PY'
|
||||
import os
|
||||
import re
|
||||
import urllib.request
|
||||
|
||||
suite = os.environ.get("SUITE_NAME", "bstein-home")
|
||||
status = os.environ.get("QUALITY_STATUS", "failed")
|
||||
gateway = os.environ.get("PUSHGATEWAY_URL", "http://platform-quality-gateway.monitoring.svc.cluster.local:9091").rstrip("/")
|
||||
text = urllib.request.urlopen(f"{gateway}/metrics", timeout=10).read().decode("utf-8", errors="replace")
|
||||
|
||||
def counter(name: str) -> float:
|
||||
pattern = re.compile(
|
||||
rf'^platform_quality_gate_runs_total\\{{[^}}]*job="platform-quality-ci"[^}}]*suite="{re.escape(suite)}"[^}}]*status="{name}"[^}}]*\\}}\\s+([0-9]+(?:\\.[0-9]+)?)$',
|
||||
re.M,
|
||||
)
|
||||
match = pattern.search(text)
|
||||
return float(match.group(1)) if match else 0.0
|
||||
|
||||
ok = counter("ok")
|
||||
failed = counter("failed")
|
||||
if status == "ok":
|
||||
ok += 1
|
||||
else:
|
||||
failed += 1
|
||||
payload = (
|
||||
"# TYPE platform_quality_gate_runs_total counter\\n"
|
||||
f'platform_quality_gate_runs_total{{suite="{suite}",status="ok"}} {int(ok)}\\n'
|
||||
f'platform_quality_gate_runs_total{{suite="{suite}",status="failed"}} {int(failed)}\\n'
|
||||
)
|
||||
req = urllib.request.Request(
|
||||
f"{gateway}/metrics/job/platform-quality-ci/suite/{suite}",
|
||||
data=payload.encode("utf-8"),
|
||||
method="POST",
|
||||
headers={"Content-Type": "text/plain"},
|
||||
)
|
||||
urllib.request.urlopen(req, timeout=10).read()
|
||||
PY
|
||||
'''
|
||||
}
|
||||
}
|
||||
failure {
|
||||
container('tester') {
|
||||
sh '''
|
||||
set -euo pipefail
|
||||
export QUALITY_STATUS=failed
|
||||
python - <<'PY'
|
||||
import os
|
||||
import re
|
||||
import urllib.request
|
||||
|
||||
suite = os.environ.get("SUITE_NAME", "bstein-home")
|
||||
status = os.environ.get("QUALITY_STATUS", "failed")
|
||||
gateway = os.environ.get("PUSHGATEWAY_URL", "http://platform-quality-gateway.monitoring.svc.cluster.local:9091").rstrip("/")
|
||||
text = urllib.request.urlopen(f"{gateway}/metrics", timeout=10).read().decode("utf-8", errors="replace")
|
||||
|
||||
def counter(name: str) -> float:
|
||||
pattern = re.compile(
|
||||
rf'^platform_quality_gate_runs_total\\{{[^}}]*job="platform-quality-ci"[^}}]*suite="{re.escape(suite)}"[^}}]*status="{name}"[^}}]*\\}}\\s+([0-9]+(?:\\.[0-9]+)?)$',
|
||||
re.M,
|
||||
)
|
||||
match = pattern.search(text)
|
||||
return float(match.group(1)) if match else 0.0
|
||||
|
||||
ok = counter("ok")
|
||||
failed = counter("failed")
|
||||
if status == "ok":
|
||||
ok += 1
|
||||
else:
|
||||
failed += 1
|
||||
payload = (
|
||||
"# TYPE platform_quality_gate_runs_total counter\\n"
|
||||
f'platform_quality_gate_runs_total{{suite="{suite}",status="ok"}} {int(ok)}\\n'
|
||||
f'platform_quality_gate_runs_total{{suite="{suite}",status="failed"}} {int(failed)}\\n'
|
||||
)
|
||||
req = urllib.request.Request(
|
||||
f"{gateway}/metrics/job/platform-quality-ci/suite/{suite}",
|
||||
data=payload.encode("utf-8"),
|
||||
method="POST",
|
||||
headers={"Content-Type": "text/plain"},
|
||||
)
|
||||
urllib.request.urlopen(req, timeout=10).read()
|
||||
PY
|
||||
'''
|
||||
}
|
||||
}
|
||||
always {
|
||||
script {
|
||||
def props = fileExists('build.env') ? readProperties(file: 'build.env') : [:]
|
||||
echo "Build complete for ${props['SEMVER'] ?: env.VERSION_TAG}"
|
||||
}
|
||||
archiveArtifacts artifacts: 'build/junit-backend.xml', allowEmptyArchive: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user