#!/usr/bin/env bash set -euo pipefail REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" run_step() { local label="$1" shift printf '\n== %s ==\n' "${label}" "$@" } shell_files() { local path git -C "${REPO_ROOT}" ls-files | while IFS= read -r path; do case "${path}" in jeannie | *.sh) printf '%s\n' "${path}" ;; scripts/*) if head -n 1 "${REPO_ROOT}/${path}" | grep -Eq 'sh|bash'; then printf '%s\n' "${path}" fi ;; esac done } validate_bash_syntax() { local files=() local file while IFS= read -r file; do files+=("${REPO_ROOT}/${file}") done < <(shell_files) if ((${#files[@]} == 0)); then echo "no shell files found" return 0 fi bash -n "${files[@]}" } validate_shellcheck() { local files=() local file while IFS= read -r file; do files+=("${REPO_ROOT}/${file}") done < <(shell_files) if ! command -v shellcheck >/dev/null 2>&1; then echo "shellcheck not installed; skipping" return 0 fi if ((${#files[@]} == 0)); then echo "no shell files found" return 0 fi shellcheck "${files[@]}" } validate_yaml() { if command -v ruby >/dev/null 2>&1; then ruby -e 'require "yaml"; (Dir["**/*.yml"] + Dir["**/*.yaml"]).each { |path| next if path.start_with?(".git/"); YAML.load_stream(File.read(path)) }; puts "yaml parse ok"' return 0 fi echo "ruby not installed; skipping generic YAML parse" } validate_tofu_fmt() { if ! command -v tofu >/dev/null 2>&1; then echo "tofu not installed; skipping fmt check" return 0 fi tofu fmt -check -recursive "${REPO_ROOT}/bootstrap" } validate_security_static() { "${REPO_ROOT}/scripts/validate-tailnet-policy" if command -v trivy >/dev/null 2>&1; then trivy config --quiet "${REPO_ROOT}" else echo "trivy not installed; skipping IaC security static scan" fi } validate_unit_tests() { "${REPO_ROOT}/tests/jeannie-unit" } main() { cd "${REPO_ROOT}" run_step "Inventory" "${REPO_ROOT}/scripts/validate-homelab-inventory" "${HOMELAB_INVENTORY_FILE:-${REPO_ROOT}/homelab.yml}" run_step "Unit tests" validate_unit_tests run_step "Generated docs" "${REPO_ROOT}/scripts/render-docs" --check run_step "Bash syntax" validate_bash_syntax run_step "Shellcheck" validate_shellcheck run_step "YAML parse" validate_yaml run_step "OpenTofu formatting" validate_tofu_fmt run_step "Security static checks" validate_security_static } main "$@"