Add yamllint, ansible-lint, and a syntax check

scripts/check.sh runs all three and CI calls the same script. ansible.cfg keeps Ansible's temp and Galaxy caches inside the checkout so the checks work when $HOME is read-only.
This commit is contained in:
tanshu committed 2026-10-18 21:35:49 +05:30
1 parent fc70acb66b
commit 0df4054cc2
8 files changed
+166

No files matched your search

+28
View File
@@ -0,0 +1,28 @@
---
# Start narrow. Widen the profile once the existing playbooks pass it.
profile: basic
exclude_paths:
- .ansible/
- .scratch/
# These roles include postgres/roles/attach with a path built from
# playbook_dir. ansible-lint resolves it against the role directory instead
# and reports a load failure for a file that does not exist. Exclude the thin
# wrapper files rather than the real attach role.
- "*/roles/postgres/tasks/main.yaml"
- "*/roles/valkey/tasks/main.yaml"
# Legacy debt that needs a repo-wide rename or a module rewrite. These report
# without failing CI. Remove an entry when its last finding is fixed.
skip_list:
- var-naming[no-role-prefix]
- name[play]
- command-instead-of-module
- yaml
warn_list:
- experimental
- literal-compare
- no-free-form
- role-name
- command-instead-of-shell
+18
View File
@@ -0,0 +1,18 @@
name: check
on:
push:
pull_request:
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install linters
run: pip install ansible-core ansible-lint yamllint
- name: Run checks
run: ./scripts/check.sh
+5
View File
@@ -3,3 +3,8 @@
# Provider bootstrap private key for prepare-server. Never commit this.
bootstrap.pem
# Local check output and scratch files.
.ansible/
.scratch/
*.log
+20
View File
@@ -0,0 +1,20 @@
---
# Local hook, same checks as CI. Enable with:
# pre-commit install
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
args: [--allow-multiple-documents]
- id: check-added-large-files
- repo: https://github.com/adrienverge/yamllint
rev: v1.35.1
hooks:
- id: yamllint
- repo: https://github.com/ansible/ansible-lint
rev: v24.7.0
hooks:
- id: ansible-lint
+25
View File
@@ -0,0 +1,25 @@
---
extends: default
ignore: |
.ansible/
.scratch/
.git/
rules:
line-length:
max: 200
allow-non-breakable-words: true
comments:
min-spaces-from-content: 1
comments-indentation: false
document-start: disable
indentation:
spaces: 2
indent-sequences: consistent
level: warning
braces:
level: warning
truthy:
allowed-values: ["true", "false"]
check-keys: false
+20
View File
@@ -0,0 +1,20 @@
[defaults]
# The fleet inventory committed next to this file.
inventory = hosts
# Ansible writes per-run temp files under $HOME by default. The agent sandbox
# and some CI images mount $HOME read-only, which makes every run fail before
# it parses a playbook. Keep the temp tree inside the checkout instead.
local_tmp = ./.ansible/tmp
# Keep Galaxy collections local too, so CI and the check script do not depend on
# a writable $HOME.
collections_path = ./.ansible/collections
# .retry files are noise now that every playbook is checked in CI.
retry_files_enabled = False
[galaxy]
# Galaxy caches API responses under $HOME by default, which breaks the same
# read-only sandbox.
cache_dir = ./.ansible/galaxy_cache
+7
View File
@@ -0,0 +1,7 @@
---
# Collections the playbooks import. CI and scripts/check.sh install these into
# .ansible/collections so ansible-lint can resolve every module.
collections:
- name: community.docker
- name: community.general
- name: ansible.posix
+43
View File
@@ -0,0 +1,43 @@
#!/usr/bin/env bash
# Run every check this repo has. CI and pre-commit call the same script.
set -euo pipefail
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.
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 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"
if [ -f requirements.yml ]; then
echo "== ansible-galaxy collection install =="
ansible-galaxy collection install -r requirements.yml
fi
run() {
local tool="$1"
shift
if command -v "$tool" >/dev/null 2>&1; then
"$tool" "$@"
else
uvx "$tool" "$@"
fi
}
echo "== yamllint =="
run yamllint .
echo "== ansible-lint =="
run ansible-lint
echo "== ansible-playbook --syntax-check =="
shopt -s nullglob
for playbook in */playbook.yml; do
echo "-- $playbook"
ansible-playbook --syntax-check "$playbook"
done