137 lines
4.0 KiB
Bash
137 lines
4.0 KiB
Bash
|
|
#!/usr/bin/env bash
|
||
|
|
# Run the safe daily gate for the current primary branch.
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
ROOT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)
|
||
|
|
REPORT_DIR="${ROOT_DIR}/target/daily-master-gate"
|
||
|
|
SUMMARY_JSON="${REPORT_DIR}/summary.json"
|
||
|
|
SUMMARY_TXT="${REPORT_DIR}/summary.txt"
|
||
|
|
METRICS_FILE="${REPORT_DIR}/metrics.prom"
|
||
|
|
PUSHGATEWAY_URL=${QUALITY_GATE_PUSHGATEWAY_URL:-}
|
||
|
|
PUSHGATEWAY_JOB=${LESAVKA_DAILY_GATE_PUSHGATEWAY_JOB:-lesavka-daily-master-gate}
|
||
|
|
|
||
|
|
mkdir -p "${REPORT_DIR}"
|
||
|
|
cd "${ROOT_DIR}"
|
||
|
|
|
||
|
|
branch=${BRANCH_NAME:-${GIT_BRANCH:-}}
|
||
|
|
if [[ -z "${branch}" ]]; then
|
||
|
|
branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo unknown)
|
||
|
|
fi
|
||
|
|
commit=${GIT_COMMIT:-}
|
||
|
|
if [[ -z "${commit}" ]]; then
|
||
|
|
commit=$(git rev-parse --short HEAD 2>/dev/null || echo unknown)
|
||
|
|
fi
|
||
|
|
build_url=${BUILD_URL:-}
|
||
|
|
|
||
|
|
is_primary_branch=0
|
||
|
|
case "${branch}" in
|
||
|
|
master|main|origin/master|origin/main|*/master|*/main)
|
||
|
|
is_primary_branch=1
|
||
|
|
;;
|
||
|
|
esac
|
||
|
|
|
||
|
|
status=0
|
||
|
|
outcome=ok
|
||
|
|
detail="ran safe platform quality gate"
|
||
|
|
start_seconds=$(date +%s)
|
||
|
|
|
||
|
|
if [[ "${is_primary_branch}" != "1" && "${LESAVKA_DAILY_ALLOW_NON_PRIMARY:-0}" != "1" ]]; then
|
||
|
|
outcome=skipped
|
||
|
|
detail="daily gate only evaluates master/main by default"
|
||
|
|
else
|
||
|
|
set +e
|
||
|
|
LESAVKA_CI_PROFILE=daily scripts/ci/platform_quality_gate.sh
|
||
|
|
status=$?
|
||
|
|
set -e
|
||
|
|
if [[ "${status}" -ne 0 ]]; then
|
||
|
|
outcome=failed
|
||
|
|
detail="safe platform quality gate failed"
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
|
||
|
|
duration_seconds=$(($(date +%s) - start_seconds))
|
||
|
|
|
||
|
|
python3 - \
|
||
|
|
"${SUMMARY_JSON}" \
|
||
|
|
"${SUMMARY_TXT}" \
|
||
|
|
"${METRICS_FILE}" \
|
||
|
|
"${branch}" \
|
||
|
|
"${commit}" \
|
||
|
|
"${build_url}" \
|
||
|
|
"${outcome}" \
|
||
|
|
"${status}" \
|
||
|
|
"${duration_seconds}" \
|
||
|
|
"${detail}" <<'PY'
|
||
|
|
import json
|
||
|
|
import pathlib
|
||
|
|
import sys
|
||
|
|
from datetime import datetime, timezone
|
||
|
|
|
||
|
|
summary_path = pathlib.Path(sys.argv[1])
|
||
|
|
text_path = pathlib.Path(sys.argv[2])
|
||
|
|
metrics_path = pathlib.Path(sys.argv[3])
|
||
|
|
branch = sys.argv[4]
|
||
|
|
commit = sys.argv[5]
|
||
|
|
build_url = sys.argv[6]
|
||
|
|
outcome = sys.argv[7]
|
||
|
|
status = int(sys.argv[8])
|
||
|
|
duration_seconds = int(sys.argv[9])
|
||
|
|
detail = sys.argv[10]
|
||
|
|
|
||
|
|
def esc(value: str) -> str:
|
||
|
|
return value.replace('\\', r'\\').replace('\n', r'\n').replace('"', r'\"')
|
||
|
|
|
||
|
|
summary = {
|
||
|
|
'suite': 'lesavka',
|
||
|
|
'profile': 'daily',
|
||
|
|
'branch': branch,
|
||
|
|
'commit': commit,
|
||
|
|
'build_url': build_url,
|
||
|
|
'outcome': outcome,
|
||
|
|
'exit_code': status,
|
||
|
|
'duration_seconds': duration_seconds,
|
||
|
|
'detail': detail,
|
||
|
|
'generated_at': datetime.now(timezone.utc).isoformat(),
|
||
|
|
}
|
||
|
|
summary_path.write_text(json.dumps(summary, indent=2, sort_keys=True) + '\n', encoding='utf-8')
|
||
|
|
text_path.write_text(
|
||
|
|
'\n'.join([
|
||
|
|
f'lesavka daily gate: {outcome}',
|
||
|
|
f'branch: {branch}',
|
||
|
|
f'commit: {commit}',
|
||
|
|
f'duration: {duration_seconds}s',
|
||
|
|
f'detail: {detail}',
|
||
|
|
]) + '\n',
|
||
|
|
encoding='utf-8',
|
||
|
|
)
|
||
|
|
|
||
|
|
labels = f'suite="lesavka",profile="daily",branch="{esc(branch)}",commit="{esc(commit)}"'
|
||
|
|
ok = 1 if outcome == 'ok' else 0
|
||
|
|
failed = 1 if outcome == 'failed' else 0
|
||
|
|
skipped = 1 if outcome == 'skipped' else 0
|
||
|
|
metrics_path.write_text(
|
||
|
|
'\n'.join([
|
||
|
|
'# HELP lesavka_ci_profile_last_run_success Whether the latest Lesavka CI profile run succeeded.',
|
||
|
|
'# TYPE lesavka_ci_profile_last_run_success gauge',
|
||
|
|
f'lesavka_ci_profile_last_run_success{{{labels}}} {ok}',
|
||
|
|
'# HELP lesavka_ci_profile_duration_seconds Duration of the latest Lesavka CI profile run.',
|
||
|
|
'# TYPE lesavka_ci_profile_duration_seconds gauge',
|
||
|
|
f'lesavka_ci_profile_duration_seconds{{{labels}}} {duration_seconds}',
|
||
|
|
'# HELP lesavka_ci_profile_runs Current profile run outcome.',
|
||
|
|
'# TYPE lesavka_ci_profile_runs gauge',
|
||
|
|
f'lesavka_ci_profile_runs{{{labels},status="ok"}} {ok}',
|
||
|
|
f'lesavka_ci_profile_runs{{{labels},status="failed"}} {failed}',
|
||
|
|
f'lesavka_ci_profile_runs{{{labels},status="skipped"}} {skipped}',
|
||
|
|
]) + '\n',
|
||
|
|
encoding='utf-8',
|
||
|
|
)
|
||
|
|
PY
|
||
|
|
|
||
|
|
if [[ -n "${PUSHGATEWAY_URL}" ]]; then
|
||
|
|
curl --fail --silent --show-error \
|
||
|
|
--data-binary @"${METRICS_FILE}" \
|
||
|
|
"${PUSHGATEWAY_URL%/}/metrics/job/${PUSHGATEWAY_JOB}/suite/lesavka" || status=$?
|
||
|
|
fi
|
||
|
|
|
||
|
|
exit "${status}"
|