Skip to content

ci: рабочие процессы разбираются, а не сверяются по подстрокам - #156

Merged
zeegin merged 1 commit into
masterfrom
ci/actionlint-gate
Sep 17, 2026
Merged

zeegin merged 1 commit into
masterfrom
ci/actionlint-gate

Conversation

@zeegin

@zeegin zeegin commented Sep 17, 2026

Copy link
Copy Markdown
Member

Почему

Линтера рабочих процессов не было ни одного: git grep -i 'actionlint\|yamllint' по .github, Makefile.toml, tests и scripts не находил ничего.

Это заметили, когда правка на #155 унесла заголовок работы publish из release.yml. audit-native и audit-draft остались с needs: publish, указывающим в пустоту. GitHub такой файл не запускает вовсе — релиз было не выпустить.

Оба набора тестов при этом остались зелёными: они сверяют подстроки, а строка needs: [publish, audit-native] никуда не делась. Делась работа.

Что добавляется

Две проверки, обе блокирующие.

actionlint в работе contract (ubuntu) разбирает все файлы целиком: синтаксис, имена контекстов и выражений, а вместе с доступным на раннере shellcheck — ещё и содержимое run:.

test_every_workflow_job_graph_resolves проверяет то же устройство, но без сети и внешнего двоичного файла: у каждой работы есть шаги, и каждая названная в needs существует. По всем файлам в .github/workflows/, не только по release.yml.

Два отступления от постановки

Инструмент ставится не через uses:. taiki-e/install-action, которым репозиторий ставит cargo-make и cargo-deny, actionlint не поддерживает — в его manifests/ такого файла нет. Закрепить образ docker://rhysd/actionlint@sha256:… тоже нельзя: test_all_actions_are_pinned_to_full_commit_sha требует ровно сорок шестнадцатеричных символов, а digest в эту форму не укладывается. Поэтому двоичный файл скачивается с закреплённой версией и сверяется по SHA-256, зафиксированной в дереве, — по той же причине, по которой пинится версия cargo-deny.

PyYAML не используется. В постановке предложено yaml.safe_load, но в CI нет ни одного pip install, и этот импорт уже ронял обе работы Happy Path час назад, когда я завёл его ради одной проверки. Структура читается разбором отступов — так же, как реестр читает своё front matter. Разбор сверен с PyYAML на всех трёх файлах: состав работ совпадает.

Проверки

  • actionlint .github/workflows/*.yml — чисто, включая сам изменённый ci.yml
  • python3 tests/release_governance.py — 18 passed
  • python3 tests/release_assets.py — 11 passed
  • Проба: снятый заголовок publish роняет примету и даёт actionlint две ошибки job-needs
  • Шаг установки прогнан целиком: адрес, сумма (8aca8db9…), имя файла в архиве, извлечение — статический ELF x86-64

Существующие файлы гейт проходят: shellcheck локально установлен той же версии, что на раннере, и претензий к run:-блокам нет. Блоков shell: python в репозитории нет, так что pyflakes в игру не вступает.

Что надо знать ревьюеру

Ветка от master, сам сломанный publish: здесь не чинится — это сделано на #155. Если #155 вольётся первым, actionlint на master подтвердит, что там всё цело.

На #155 живёт более узкая версия той же приметы, только для release.yml. Имена у функций разные, так что слияние пройдёт без конфликта, но после вливания обеих узкую стоит убрать как поглощённую — сделаю отдельной правкой.

Линтера рабочих процессов не было ни одного. Это заметили, когда правка унесла
заголовок работы `publish` из `release.yml`: `audit-native` и `audit-draft`
остались с `needs: publish`, указывающим в пустоту, — GitHub такой файл не
запускает вовсе, то есть релиз было не выпустить. Оба набора тестов при этом
остались зелёными, потому что сверяли подстроки, а строка
`needs: [publish, audit-native]` никуда не делась; делась работа.

Появляются две проверки, и обе блокирующие.

`actionlint` в работе `contract` на ubuntu разбирает все файлы целиком: синтаксис,
имена контекстов и выражений, а вместе с доступным на раннере `shellcheck` — ещё и
содержимое `run:`. Версия и сумма зафиксированы в дереве по той же причине, что и
у cargo-deny: гейт блокирующий, и плавающий инструмент краснел бы без единой
правки рабочего процесса. Через `uses:` его не поставить — `taiki-e/install-action`
actionlint не поддерживает, а закрепление образа по digest нарушило бы правило
про сорокасимвольный SHA.

`test_every_workflow_job_graph_resolves` проверяет то же самое устройство, но не
зависит ни от сети, ни от внешнего двоичного файла: каждая работа имеет шаги, и
каждая названная в `needs` существует. Разбор идёт по отступам, без PyYAML: в CI
нет ни одного `pip install`, и завезённый ради одной проверки импорт уже ронял обе
работы Happy Path. Разбор сверен с PyYAML на всех трёх файлах — состав работ
совпадает.

Обе проверены пробой: снятый заголовок `publish` роняет примету и даёт actionlint
две ошибки `job-needs`. Шаг установки прогнан целиком — адрес, сумма, имя файла в
архиве, извлечение.
@zeegin
zeegin merged commit b9a7d1c into master Sep 17, 2026
5 checks passed
@zeegin
zeegin deleted the ci/actionlint-gate branch September 20, 2026 10:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant