Add secret scanning, layout checks, and a --changed mode
gitleaks runs before each commit and in CI, with known values in a redacted baseline. The layout check rejects empty readmes and main.yml role entrypoints. --changed lints only the YAML files that differ from HEAD.
This commit is contained in:
1 parent
f3845bde2b
commit
2aab1aec1e
8 files changed
+478
-19
No files matched your search
+105
-13
@@ -1,18 +1,35 @@
|
||||
#!/usr/bin/env bash
|
||||
# Run every check this repo has. CI and pre-commit call the same script.
|
||||
# Usage: scripts/check.sh [--changed]
|
||||
set -euo pipefail
|
||||
shopt -s nullglob
|
||||
|
||||
cd "$(dirname "${BASH_SOURCE[0]}")/.."
|
||||
|
||||
# Ansible and uv both want a writable cache. Keep them in the checkout so the
|
||||
# script works when $HOME is read-only, which is the case in the agent sandbox.
|
||||
changed=0
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--changed) changed=1 ;;
|
||||
*)
|
||||
echo "unknown argument: $arg" >&2
|
||||
echo "usage: scripts/check.sh [--changed]" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Ansible and uv want writable caches. Keep them in the checkout so the script
|
||||
# works when $HOME is read-only, which is the case in the agent sandbox.
|
||||
export ANSIBLE_CONFIG="${ANSIBLE_CONFIG:-$PWD/ansible.cfg}"
|
||||
export ANSIBLE_HOME="${ANSIBLE_HOME:-$PWD/.ansible/home}"
|
||||
export ANSIBLE_LOCAL_TEMP="${ANSIBLE_LOCAL_TEMP:-$PWD/.ansible/tmp}"
|
||||
export ANSIBLE_GALAXY_CACHE_DIR="${ANSIBLE_GALAXY_CACHE_DIR:-$PWD/.ansible/galaxy_cache}"
|
||||
export UV_CACHE_DIR="${UV_CACHE_DIR:-$PWD/.ansible/uv-cache}"
|
||||
export UV_TOOL_DIR="${UV_TOOL_DIR:-$PWD/.ansible/uv-tools}"
|
||||
export ANSIBLE_GALAXY_CACHE_DIR="${ANSIBLE_GALAXY_CACHE_DIR:-$PWD/.ansible/galaxy_cache}"
|
||||
mkdir -p "$ANSIBLE_LOCAL_TEMP" "$UV_CACHE_DIR" "$UV_TOOL_DIR" "$ANSIBLE_GALAXY_CACHE_DIR" "$ANSIBLE_HOME"
|
||||
export XDG_CACHE_HOME="${XDG_CACHE_HOME:-$PWD/.scratch/cache}"
|
||||
export PIP_CACHE_DIR="${PIP_CACHE_DIR:-$PWD/.scratch/cache/pip}"
|
||||
mkdir -p "$ANSIBLE_LOCAL_TEMP" "$UV_CACHE_DIR" "$UV_TOOL_DIR" \
|
||||
"$ANSIBLE_GALAXY_CACHE_DIR" "$ANSIBLE_HOME" "$XDG_CACHE_HOME" "$PIP_CACHE_DIR"
|
||||
|
||||
if [ -f requirements.yml ]; then
|
||||
echo "== ansible-galaxy collection install =="
|
||||
@@ -29,15 +46,90 @@ run() {
|
||||
fi
|
||||
}
|
||||
|
||||
echo "== yamllint =="
|
||||
run yamllint .
|
||||
# YAML files that differ from HEAD, including new files that are not staged yet.
|
||||
yaml_files=()
|
||||
if [ "$changed" = 1 ]; then
|
||||
while IFS= read -r file; do
|
||||
[ -n "$file" ] && yaml_files+=("$file")
|
||||
done < <(
|
||||
git diff --name-only --diff-filter=ACMR HEAD -- '*.yml' '*.yaml'
|
||||
git ls-files --others --exclude-standard -- '*.yml' '*.yaml'
|
||||
)
|
||||
fi
|
||||
|
||||
echo "== ansible-lint =="
|
||||
run ansible-lint
|
||||
# ansible-lint only understands Ansible files, so keep the changed files that
|
||||
# live under a service with a playbook.
|
||||
ansible_files=()
|
||||
if [ "$changed" = 1 ]; then
|
||||
for file in "${yaml_files[@]}"; do
|
||||
service="${file%%/*}"
|
||||
if [ -f "$service/playbook.yml" ]; then
|
||||
ansible_files+=("$file")
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ "$changed" = 1 ] && [ "${#yaml_files[@]}" -eq 0 ]; then
|
||||
echo "== changed mode: no YAML files changed =="
|
||||
else
|
||||
echo "== yamllint =="
|
||||
if [ "$changed" = 1 ]; then
|
||||
run yamllint "${yaml_files[@]}"
|
||||
else
|
||||
run yamllint .
|
||||
fi
|
||||
|
||||
echo "== ansible-lint =="
|
||||
if [ "$changed" = 1 ] && [ "${#ansible_files[@]}" -eq 0 ]; then
|
||||
echo "no changed Ansible files"
|
||||
elif [ "$changed" = 1 ]; then
|
||||
run ansible-lint "${ansible_files[@]}"
|
||||
else
|
||||
run ansible-lint
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "== layout =="
|
||||
layout_ok=1
|
||||
for playbook in */playbook.yml; do
|
||||
service="${playbook%/playbook.yml}"
|
||||
if [ ! -s "$service/readme.md" ]; then
|
||||
echo "missing or empty $service/readme.md" >&2
|
||||
layout_ok=0
|
||||
fi
|
||||
done
|
||||
for entrypoint in */roles/*/tasks/main.yml */roles/*/handlers/main.yml; do
|
||||
echo "role entrypoint must use .yaml: $entrypoint" >&2
|
||||
layout_ok=0
|
||||
done
|
||||
if [ "$layout_ok" -ne 1 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "== gitleaks =="
|
||||
./scripts/check-secrets.sh
|
||||
|
||||
echo "== ansible-playbook --syntax-check =="
|
||||
shopt -s nullglob
|
||||
for playbook in */playbook.yml; do
|
||||
echo "-- $playbook"
|
||||
ansible-playbook --syntax-check "$playbook"
|
||||
done
|
||||
playbooks=()
|
||||
if [ "$changed" = 1 ]; then
|
||||
for file in "${yaml_files[@]}"; do
|
||||
service="${file%%/*}"
|
||||
if [ -f "$service/playbook.yml" ]; then
|
||||
playbooks+=("$service/playbook.yml")
|
||||
fi
|
||||
done
|
||||
if [ "${#playbooks[@]}" -gt 0 ]; then
|
||||
mapfile -t playbooks < <(printf '%s\n' "${playbooks[@]}" | sort -u)
|
||||
fi
|
||||
else
|
||||
playbooks=(*/playbook.yml)
|
||||
fi
|
||||
|
||||
if [ "${#playbooks[@]}" -eq 0 ]; then
|
||||
echo "no playbooks to check"
|
||||
else
|
||||
for playbook in "${playbooks[@]}"; do
|
||||
echo "-- $playbook"
|
||||
ansible-playbook --syntax-check "$playbook"
|
||||
done
|
||||
fi
|
||||
Reference in new issue
Block a user