Files
infra/.gitea/workflows/lint.yml
T
DmitryandClaude Opus 5 a7b0635830 Add lint configuration and Gitea Actions CI
Configure yamllint and ansible-lint, plus a workflow running yamllint,
ansible-lint and ansible-playbook --syntax-check over every playbook.

ansible-lint uses the moderate profile: on the current code it reports
exactly the same violations as basic, so it costs nothing today while
holding a higher bar for new code. skip_list is empty; noisy legacy
rules go to warn_list with a comment on why and when to restore them.
Correctness and safety rules stay fatal.

Two constraints are encoded in the workflow: syntax-check must run from
ansible/ because roles_path is relative, and ansible-lint needs absolute
ANSIBLE_ROLES_PATH/ANSIBLE_COLLECTIONS_PATH when run from the root.

The runner is not registered yet; registration notes are in the workflow.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GTocXkGUUazHdKKd3r9k71
2026-08-26 22:09:59 +03:00

135 lines
6.3 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
# Статические проверки Ansible-кода HomeLab infras.
#
# ГДЕ ЭТО ДОЛЖНО ВЫПОЛНЯТЬСЯ
# --------------------------
# Gitea живёт на LXC `gitea` (192.168.1.25). Gitea Actions по умолчанию
# ВЫКЛЮЧЕНЫ и не имеют ни одного раннера — этот workflow не запустится,
# пока раннер не зарегистрирован ОТДЕЛЬНО, вручную:
#
# 1. Включить Actions в Gitea:
# app.ini -> [actions] ENABLED = true
# и в настройках репозитория: Settings -> Actions -> Enable.
#
# 2. Поднять act_runner. Подходящий хост — LXC `docker-test`
# (192.168.1.29): там уже есть Docker, а сборка контейнеров раннера
# не мешает проду. Ставить раннер на сам LXC `gitea` не стоит —
# CI-нагрузка не должна валить git-сервис.
#
# 3. Зарегистрировать раннер (на docker-test):
# act_runner register --no-interactive \
# --instance http://192.168.1.25:3000 \
# --token <RUNNER_TOKEN из Gitea Settings -> Actions -> Runners> \
# --name docker-test-runner \
# --labels ubuntu-latest:docker://catthehacker/ubuntu:act-latest
#
# Метка `ubuntu-latest` обязательна — именно её просит `runs-on` ниже.
#
# 4. Раннеру нужен исходящий интернет (PyPI + Ansible Galaxy).
# На docker-test трафик может идти через mihomo/OpenVPN — проверить,
# что pip и galaxy резолвятся, иначе шаг установки упадёт.
#
# Регистрация раннера НЕ автоматизирована этим репозиторием: она требует
# одноразового токена из веб-интерфейса Gitea.
#
# Локально те же проверки воспроизводятся через nix:
# nix develop -c yamllint .
# nix develop -c ansible-lint
# nix develop -c sh -c 'cd ansible && for f in playbooks/*.yml; do ansible-playbook --syntax-check "$f"; done'
name: lint
on:
push:
pull_request:
jobs:
lint:
name: yamllint + ansible-lint + syntax-check
runs-on: ubuntu-latest
env:
# ansible.cfg лежит в ansible/ и использует ОТНОСИТЕЛЬНЫЕ пути
# (roles_path = roles). Из корня репозитория он не работает, поэтому
# пути задаются абсолютно через окружение. Без этого ansible-lint
# выдаёт 12 ложных syntax-check[specific] «role not found».
ANSIBLE_ROLES_PATH: ${{ github.workspace }}/ansible/roles
ANSIBLE_COLLECTIONS_PATH: ${{ github.workspace }}/ansible/collections
ANSIBLE_INVENTORY: ${{ github.workspace }}/ansible/inventory/hosts.yml
# Ansible шумит депрекейшенами ядра — в CI они не наши.
ANSIBLE_DEPRECATION_WARNINGS: "false"
PIP_DISABLE_PIP_VERSION_CHECK: "1"
steps:
- name: Checkout
uses: actions/checkout@v4
# Образ catthehacker/ubuntu:act-latest уже несёт python3, но не всегда
# python3-venv. Ставим явно, чтобы шаг не был хрупким.
- name: Ensure python3 + venv
run: |
set -eux
if ! command -v python3 >/dev/null 2>&1 || ! python3 -m venv --help >/dev/null 2>&1; then
apt-get update
apt-get install -y --no-install-recommends python3 python3-venv python3-pip
fi
python3 --version
- name: Install ansible-core, ansible-lint, yamllint
run: |
set -eux
python3 -m venv /tmp/lintenv
. /tmp/lintenv/bin/activate
python3 -m pip install --upgrade pip
# ansible-core/proxmoxer/requests берём из репозитория, чтобы CI и
# локальное окружение не разъезжались.
python3 -m pip install -r ansible/requirements.txt
# Линтеры пинуем: обновление ansible-lint регулярно добавляет новые
# правила и красит CI без единого коммита в инфраструктуру.
python3 -m pip install 'ansible-lint==25.8.2' 'yamllint==1.37.1'
echo "/tmp/lintenv/bin" >> "$GITHUB_PATH"
- name: Install Galaxy collections
run: |
set -eux
ansible-galaxy collection install \
-r ansible/requirements.yml \
-p ansible/collections
- name: Versions
run: |
set -eux
ansible --version | head -n1
ansible-lint --version
yamllint --version
# Конфиг в /.yamllint. Падает только на ошибках (табы, дубли ключей,
# битый YAML); стилевые замечания идут как warning и CI не роняют.
- name: yamllint
run: yamllint -f standard .
# Конфиг в /.ansible-lint, profile: moderate.
- name: ansible-lint
run: ansible-lint
# syntax-check запускается ИЗ ansible/, иначе ansible.cfg с
# относительными roles_path не подхватывается и 13 плейбуков падают
# с «role not found». Переменные Proxmox (PROXMOX_*) для syntax-check
# НЕ нужны: `lookup('env', ...)` на этапе парсинга не вычисляется,
# проверено — все 37 плейбуков проходят с пустым окружением.
- name: ansible-playbook --syntax-check (все плейбуки)
working-directory: ansible
run: |
set -u
rc=0
for f in playbooks/*.yml; do
if ansible-playbook --syntax-check "$f" >/tmp/sc.log 2>&1; then
echo "ok $f"
else
rc=1
echo "FAIL $f"
sed 's/^/ /' /tmp/sc.log
fi
done
exit "$rc"