#!/usr/bin/env bash # .gitea/workflows/scripts/install-tools.sh — install the PINNED tools a given # gate stage needs on a Gitea Actions runner. Versions come from ci/versions.env # (single source of truth, R-TEST-02). Usage: install-tools.sh set -euo pipefail HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "${HERE}/../../.." && pwd)" # shellcheck disable=SC1091 source "${REPO_ROOT}/ci/versions.env" stage="${1:-all}" os="$(uname -s | tr '[:upper:]' '[:lower:]')" arch="$(uname -m)"; case "$arch" in x86_64) arch=amd64 ;; aarch64|arm64) arch=arm64 ;; esac bindir="${HOME}/.local/bin"; mkdir -p "$bindir" echo "${bindir}" >> "${GITHUB_PATH:-/dev/null}" 2>/dev/null || true export PATH="${bindir}:${PATH}" log() { printf '[install] %s\n' "$*" >&2; } install_yamllint() { have yamllint || { log "yamllint ${YAMLLINT_VERSION}"; pip install --quiet "yamllint==${YAMLLINT_VERSION}"; }; } install_check_jsonschema() { have check-jsonschema || { log "check-jsonschema ${CHECK_JSONSCHEMA_VERSION}"; pip install --quiet "check-jsonschema==${CHECK_JSONSCHEMA_VERSION}"; }; } install_kyverno() { have kyverno && return 0 log "kyverno CLI ${KYVERNO_VERSION}" # Arch strings differ per tool: the kyverno CLI tarball uses x86_64 (uname -m style), # NOT amd64 — map it here (mirrors infra/devcontainer/Containerfile). chainsaw/kubectl # below use the amd64/arm64 form, so only kyverno needs this. local karch="$arch"; case "$arch" in amd64) karch=x86_64 ;; esac local url="https://github.com/kyverno/kyverno/releases/download/v${KYVERNO_VERSION}/kyverno-cli_v${KYVERNO_VERSION}_${os}_${karch}.tar.gz" curl -fsSL "$url" | tar -xz -C "$bindir" kyverno } install_chainsaw() { have chainsaw && return 0 log "chainsaw ${CHAINSAW_VERSION}" local url="https://github.com/kyverno/chainsaw/releases/download/v${CHAINSAW_VERSION}/chainsaw_${os}_${arch}.tar.gz" curl -fsSL "$url" | tar -xz -C "$bindir" chainsaw } # promtool — the alert-rule UNIT-TEST engine the L0 check # conformance/tests/l0-static/alert-rules-unit-tested runs. Installed for the l0 stage because # without it that check exits 3 (SKIPPED, never green) on the runner and the alert unit tests # would be enforced nowhere — the exact "coverage that looks present" failure it exists to end. # Pinned from ci/versions.env to the Prometheus version prod runs (promtool IS the rule engine); # the check asserts `promtool --version` equals that pin, so a drifted install FAILS, not skips. install_promtool() { have promtool && return 0 log "promtool ${PROMTOOL_VERSION} (from the prometheus release tarball)" local tarball="prometheus-${PROMTOOL_VERSION}.${os}-${arch}" curl -fsSL "https://github.com/prometheus/prometheus/releases/download/v${PROMTOOL_VERSION}/${tarball}.tar.gz" \ | tar -xz -C "$bindir" --strip-components=1 "${tarball}/promtool" chmod +x "${bindir}/promtool" } install_kubectl() { have kubectl && return 0 log "kubectl ${KUBECTL_VERSION}" curl -fsSL -o "${bindir}/kubectl" "https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/${os}/${arch}/kubectl" chmod +x "${bindir}/kubectl" } have() { command -v "$1" >/dev/null 2>&1; } case "$stage" in lint) install_yamllint ;; l0) install_yamllint; install_check_jsonschema; install_kyverno; install_promtool ;; # schema (check-jsonschema) + Kyverno L0 + alert unit tests l1) install_chainsaw ;; # L1 render via conformance runner (Chainsaw) conformance) install_chainsaw; install_kubectl ;; # trigger the in-cluster Job all) install_yamllint; install_check_jsonschema; install_kyverno; install_promtool; install_chainsaw; install_kubectl ;; *) echo "unknown stage: $stage" >&2; exit 2 ;; esac log "stage '${stage}' tools ready"