--- # Статические проверки 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 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"