From e75fd334bf894418c909b2fc8ce38f7279540b8a Mon Sep 17 00:00:00 2001 From: Apple Date: Mon, 2 Mar 2026 10:13:06 -0800 Subject: [PATCH] ops(dev): add release evidence auto-generator script Made-with: Cursor --- ops/generate_release_evidence.sh | 192 +++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100755 ops/generate_release_evidence.sh diff --git a/ops/generate_release_evidence.sh b/ops/generate_release_evidence.sh new file mode 100755 index 00000000..3562e6b6 --- /dev/null +++ b/ops/generate_release_evidence.sh @@ -0,0 +1,192 @@ +#!/usr/bin/env bash +# Generate partially prefilled release evidence markdown. +# +# Usage: +# bash ops/generate_release_evidence.sh +# bash ops/generate_release_evidence.sh --out release-evidence-custom.md +# bash ops/generate_release_evidence.sh --sofiia-url http://127.0.0.1:8002 --skip-preflight +# +# Exit codes: +# 0 = file created +# 1 = critical error + +set -euo pipefail + +SOFIIA_URL="http://127.0.0.1:8002" +OUT_FILE="" +SKIP_PREFLIGHT=0 +SKIP_HEALTH=0 + +while [ "$#" -gt 0 ]; do + case "$1" in + --out) + OUT_FILE="${2:-}" + shift 2 + ;; + --sofiia-url) + SOFIIA_URL="${2:-}" + shift 2 + ;; + --skip-preflight) + SKIP_PREFLIGHT=1 + shift + ;; + --skip-health) + SKIP_HEALTH=1 + shift + ;; + -h|--help) + cat <<'EOF' +Usage: bash ops/generate_release_evidence.sh [options] + +Options: + --out Output markdown file path + --sofiia-url Sofiia console base URL (default: http://127.0.0.1:8002) + --skip-preflight Skip preflight execution + --skip-health Skip health/metrics checks +EOF + exit 0 + ;; + *) + echo "Unknown argument: $1" + exit 1 + ;; + esac +done + +if ! command -v git >/dev/null 2>&1; then + echo "ERROR: git is required" + exit 1 +fi +if ! command -v date >/dev/null 2>&1; then + echo "ERROR: date is required" + exit 1 +fi + +REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || true)" +if [ -z "${REPO_ROOT}" ]; then + echo "ERROR: not inside a git repository" + exit 1 +fi + +cd "${REPO_ROOT}" + +TS_TAG="$(date -u '+%Y%m%d-%H%M%S')" +if [ -z "${OUT_FILE}" ]; then + OUT_FILE="release-evidence-${TS_TAG}.md" +fi + +UTC_TS="$(date -u '+%Y-%m-%d %H:%M:%S UTC')" +KYIV_TS="$(TZ=Europe/Kyiv date '+%Y-%m-%d %H:%M:%S %Z' 2>/dev/null || date '+%Y-%m-%d %H:%M:%S')" +GIT_SHA="$(git rev-parse --short HEAD 2>/dev/null || echo "unknown")" +GIT_BRANCH="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")" +GIT_MSG="$(git log -1 --pretty=%s 2>/dev/null || echo "unknown")" +HOST_NAME="$(hostname 2>/dev/null || echo "unknown")" +NODE_ID_VALUE="${NODE_ID:-unset}" +OPERATOR_VALUE="${USER:-unknown}" + +PREFLIGHT_STATUS="SKIPPED" +PREFLIGHT_CMD='bash ops/preflight_sofiia_console.sh' +if [ "${SKIP_PREFLIGHT}" = "0" ]; then + set +e + bash ops/preflight_sofiia_console.sh >/dev/null 2>&1 + PREFLIGHT_CODE=$? + set -e + if [ "${PREFLIGHT_CODE}" = "0" ]; then + PREFLIGHT_STATUS="PASS" + elif [ "${PREFLIGHT_CODE}" = "2" ]; then + PREFLIGHT_STATUS="WARN" + else + PREFLIGHT_STATUS="FAIL" + fi +fi + +HEALTH_CODE="SKIPPED" +METRICS_CODE="SKIPPED" +if [ "${SKIP_HEALTH}" = "0" ]; then + set +e + HEALTH_CODE="$(curl -s -o /dev/null -w '%{http_code}' --max-time 5 "${SOFIIA_URL}/api/health" 2>/dev/null || echo "000")" + METRICS_CODE="$(curl -s -o /dev/null -w '%{http_code}' --max-time 5 "${SOFIIA_URL}/metrics" 2>/dev/null || echo "000")" + set -e +fi + +cat > "${OUT_FILE}" < 401 confirmed: yes / no + - with key -> 200 confirmed: yes / no + +## 5) Post-release checks + +- Key metrics deltas (optional): + - sofiia_rate_limited_total: + - sofiia_idempotency_replays_total: +- Audit write/read quick check: OK / FAIL +- Retention dry-run: + - Command: \`python3 ops/prune_audit_db.py --dry-run\` + - candidates= + - Notes: + +## 6) Rollback plan & outcome + +- Rollback needed: no / yes +- If yes: + - reason: + - rollback commands used: + - result: +- Final service state: healthy / degraded + +## 7) Sign-off + +- Reviewer / approver: +- Timestamp UTC: +- Notes: +EOF + +echo "Release evidence file created: ${OUT_FILE}" +exit 0