T27.AI

Блог

PR курса теперь несёт свой пост

2026-10-07 · 4 мин чтения

[PR открыт и не влит; действует только на PR, открытые или обновлённые после слияния; проверяет, что файл поста изменился, а не что в нём написано] Проверка T27 work report теперь отклоняет PR в trinity, который меняет курс и не добавляет и не правит тело поста в блоге в том же PR. Слова правила живут только в спеке t27, specs/policy/course_post.t27, которую проверка читает и при сбое закрывается. Переименованные уроки считаются по старому и новому пути, переименованные посты не считаются, а неполный список файлов даёт «не решено». Семь посаженных мутантов уронили каждый свой тест.

Гравюрный триптих к статье: PR курса теперь несёт свой пост
Открыть полный триптих в исходном размере
#CI#Courses#Blog#MutationTesting

У каждого PR в trinity уже есть отчёт о работе, а влитый PR потом становится черновиком поста в блоге. Но изменение курса всё ещё могло попасть в main совсем без поста, и читатель встречал новый урок раньше, чем что-нибудь его объясняло. trinity#1461 закрывает эту дыру: PR, который меняет курс, обязан нести свой пост — английское body и русское ruBody — в том же PR, иначе статус «T27 work report» краснеет. PR открыт и ещё не влит.

Правило живёт в спеке t27

Слова правила лежат в одном файле, apps/website/specs/policy/course_post.t27. В нём фраза правила, каталог курса (apps/website/specs/course/), каталог постов (apps/website/src/data/blog/bodies/) и два статуса файла, которые считаются написанным постом: «added» и «modified». Три блока test закрепляют эти значения. Спека лежит в specs/policy/, а не в specs/course/, поэтому правка правила сама изменением курса не считается.

scripts/pr_blog_report.py правило не пересказывает. Он читает строковые константы спеки и её единственный список строк и при сбое закрывается: нет константы, у каталога нет косой черты в конце, или длина списка POST_STATUSES не совпадает с объявленной — проверка останавливается. Длину скрипт сверяет сам, потому что t27 пока не проверяет объявленную длину массива (gHashTag/t27#7395). Сообщение об отказе — это фраза RULE из спеки и файл, который её задел.

Что считается изменением и что — постом

Семь посаженных ошибок, семь красных тестов

PR добавляет 10 тестов на правило; весь набор теперь гоняет 71 тест, и повторный прогон 7 октября дал OK. Чтобы проверить, что тесты видят ошибку, в pr_blog_report.py по одному посадили семь мутантов, каждый потом откатили через git. Каждый уронил тест, названный в его честь.

  1. Статус файла не смотрится, и удалённый пост засчитался бы.
  2. Отказ никогда не выдаётся.
  3. Объявленная длина POST_STATUSES не проверяется.
  4. Проверка неполного списка перевёрнута.
  5. Отказ называет спеку по-старому, путём, обрезанным через parents[3], без начального apps/.
  6. previous_filename не смотрится, и урок, вынесенный из курса, пропускается.
  7. Пометка «не решено» для неполного списка с файлом курса снова превращена в отказ.

Чего это не проверяет

Проверяется, что файл тела поста изменился, а не то, что пост описывает изменение курса; содержание по-прежнему судят ревью и проверки блога. Workflow запускает скрипт из main (pull_request_target), поэтому правило действует только на PR, открытые или обновлённые после слияния. Ручной перезапуск отчёта для старого PR курса, ушедшего без поста, теперь станет красным.

Чего это не решает

Пруфы

Поработаем вместе

Хотите так же проверить собственный дизайн?

Я аудирую RTL и строю независимые побитово точные модели, затем провожу результат через синтез и, когда это полезно, проверяю на плате Artix-7. Первый модуль проверки — бесплатно.