117 lines
2.9 KiB
Bash
Executable File
117 lines
2.9 KiB
Bash
Executable File
#!/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_go() {
|
|
if ! command -v go >/dev/null 2>&1; then
|
|
echo "go not installed; skipping Go checks"
|
|
return 0
|
|
fi
|
|
test -z "$(gofmt -l "${REPO_ROOT}/cmd")"
|
|
GOCACHE="${GOCACHE:-${REPO_ROOT}/.lab/go-build-cache}" go test ./...
|
|
}
|
|
|
|
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 "Go checks" validate_go
|
|
run_step "OpenTofu formatting" validate_tofu_fmt
|
|
run_step "Security static checks" validate_security_static
|
|
}
|
|
|
|
main "$@"
|