From d1ebc79183276af31f84f235de7ef2d3921cc879 Mon Sep 17 00:00:00 2001 From: Alena Batitskaia Date: Fri, 4 Sep 2026 23:13:51 +0100 Subject: [PATCH 1/2] =?UTF-8?q?=D0=92=D0=BE=D0=B7=D0=B2=D1=80=D0=B0=D1=89?= =?UTF-8?q?=D0=B0=D0=B5=D1=82=20=D1=84=D0=B0=D0=B9=D0=BB=20=D0=B8=20=D1=81?= =?UTF-8?q?=D1=82=D1=80=D0=BE=D0=BA=D1=83=20=D0=B2=20=D0=BE=D1=88=D0=B8?= =?UTF-8?q?=D0=B1=D0=BA=D1=83=20editorconfig=20=D0=B2=20CI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit На пулреквестах проверка линтера падала с одной строкой «trailing whitespace» — без файла, без номера строки, без намёка, что чинить. Причина не в наших экшенах. 3 сентября вышел editorconfig-checker 4.0.0, который сам определяет GitHub Actions и переключается на формат вывода github-actions. Файл и строка уезжают в метаданные аннотации, а в лог попадает голый текст ошибки. npm-пакет — это обёртка, которая качает бинарник «latest», поэтому CI переехал на новый мажор сам, без единой правки в репозитории. Версия бинарника закреплена переменной EC_VERSION, формат вывода задан явно: gcc печатает «файл:строка:колонка: error: правило» одной строкой — так же, как vnu в lint:html, то есть все проверки пулреквеста теперь сообщают об ошибках одинаково. Пин заодно уравнивает CI с локальным прогоном: обёртка кеширует скачанное навсегда, и без него у каждого своя версия чекера, а в CI всегда свежая. Шаг печатает подсказку, куда смотреть и чем чинить, но только если проверка дошла до отчёта о нарушениях: при упавшей загрузке бинарника совет искать пробелы уводит не туда. Заодно джоба линтеров названа «Линтеры»: в списке проверок она была единственной английской и не говорила, что именно упало. Тестом это не покрыть — это конфиг CI. Вместо теста прогоны шага целиком под bash -e на живом бинарнике v4.0.1 в трёх ветках: нарушение в файле, упавшая загрузка бинарника, чистый репозиторий. Co-Authored-By: Claude Opus 5 --- .github/workflows/linting.yml | 22 +++++++++++++++++++++- .gitignore | 2 +- AGENTS.md | 2 +- docs/deps.md | 2 ++ package.json | 2 +- 5 files changed, 26 insertions(+), 4 deletions(-) diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index 2ed094a3b..ca18ff865 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -8,6 +8,7 @@ on: jobs: lint: + name: Линтеры runs-on: ubuntu-latest steps: - name: Загрузка платформы @@ -21,14 +22,33 @@ jobs: # Шаги не прерывают друг друга: при падении видно все три отчёта сразу, # а не только первый упавший линтер. + # editorconfig-checker скачивает свой бинарник через GitHub API. Без # токена запрос неавторизованный, а лимит общий на IP раннера — прогоны # падали случайно, с «API rate limit exceeded» вместо ошибок разметки. + # + # Версия бинарника и формат вывода закреплены в npm-скрипте. Обёртка + # качает «latest», поэтому CI сам уехал на 4.0.0, а тот в GitHub Actions + # переключается на формат github-actions: файл и строка уходят в + # метаданные аннотации, и в логе остаётся голое «trailing whitespace». + # + # Подсказка печатается только если проверка дошла до отчёта: при упавшей + # загрузке бинарника совет искать пробелы уводит не туда. Пайплайн склеен + # с `exit 0` через `&&`, потому что шаг идёт в `bash -e`: без склейки + # падение проверки убьёт шаг до подсказки. - name: Проверка editorconfig if: ${{ !cancelled() }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: npm run editorconfig + run: | + set -o pipefail + npm run editorconfig 2>&1 | tee "$RUNNER_TEMP/editorconfig.log" && exit 0 + if grep -q 'errors found' "$RUNNER_TEMP/editorconfig.log"; then + echo + echo "Файлы выше расходятся с .editorconfig — правило, файл и строка указаны в отчёте." + echo "Локально тот же отчёт: npm run editorconfig. Простые случаи правит на месте npm run editorconfig -- --fix" + fi + exit 1 - name: Проверка линтером CSS if: ${{ !cancelled() }} run: npm run lint:css diff --git a/.gitignore b/.gitignore index a08041381..052939031 100644 --- a/.gitignore +++ b/.gitignore @@ -27,7 +27,7 @@ interviews .cache .issues.json -# бинарник, который editorconfig-checker скачивает при запуске +# остатки старой обёртки editorconfig-checker, которая качала бинарник сюда bin .env diff --git a/AGENTS.md b/AGENTS.md index b25b01d62..e22004759 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -114,7 +114,7 @@ npm run build && npm run lint:html # валидация разметки, н `lint:html` проверяет по одной странице каждого типа, а не весь сайт: за разметку статей отвечает один шаблон `doc.njk`, и тысячная статья не скажет ничего, чего не сказала первая. Список страниц — в `scripts/lint-html.js`, при добавлении нового типа страницы его нужно пополнить. -`editorconfig-checker` при каждом запуске качает свой бинарник в `./bin/latest/`. Папка в `.gitignore`. +`editorconfig-checker` — это обёртка вокруг бинарника, который скачивается в `node_modules` при первом запуске и кешируется там до следующего `npm ci`. Обёртке нужна нода не ниже 24, как в `.nvmrc`: на более старой она падает с `TypeError` в минифицированном коде вместо отчёта о нарушениях. Версия закреплена в npm-скрипте переменной `EC_VERSION`: обёртка по умолчанию тянет `latest`, и тогда локально остаётся навсегда та версия, которую скачали однажды, а в CI приезжает свежая — отчёты расходятся. Формат вывода тоже задан явно (`--format gcc`): с версии 4 чекер сам переключается в CI на формат аннотаций GitHub, и в логе от ошибки остаётся один текст без файла и строки. Тесты лежат в `__tests__/` рядом с кодом, общие помощники — в `test/helpers/`. Покрытие пока тонкое, самое ценное место для новых тестов — трансформации: это чистые функции, html на входе и html на выходе. diff --git a/docs/deps.md b/docs/deps.md index b3d7c3d54..d939088e7 100644 --- a/docs/deps.md +++ b/docs/deps.md @@ -29,6 +29,8 @@ npx npm-check-updates -u npm install ``` +У пакета `editorconfig-checker` версия бинарника закреплена отдельно, переменной `EC_VERSION` в npm-скрипте `editorconfig`. `npm outdated` показывает только версию обёртки, бинарник поднимается руками. + ## Разрешение конфликтов в файле _package-lock.json_ Иногда могут возникнуть конфликты слияния в Git для _package-lock.json_. Править руками этот файл можно лишь в исключительных ситуациях. diff --git a/package.json b/package.json index d3114d6c4..646354cf8 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "start": "cross-env-shell NODE_ENV=development NODE_OPTIONS=--max-old-space-size=8192 \"npm run make-links && eleventy --incremental --serve --quiet\"", "build": "cross-env-shell NODE_ENV=production \"npm run make-links && eleventy --quiet && npx gulp\"", "deploy": "cd dist && rsync -e 'ssh -i $HOME/.ssh/doka_deploy -o StrictHostKeyChecking=no' --exclude 'api.json' --exclude 'mail' --archive --progress --compress --delete . deploy@dev.doka.guide:$(echo $(grep 'SERVER_PATH' ../.env | cut -d '=' -f2))", - "editorconfig": "editorconfig-checker", + "editorconfig": "cross-env EC_VERSION=v4.0.1 editorconfig-checker --format gcc", "lint:css": "stylelint 'src/styles/**/*.css'", "lint:js": "eslint '**/*.js'", "lint:html": "node scripts/lint-html.js", From 8dedbb3203e1c0abbee56126a9d7839f7d3c6499 Mon Sep 17 00:00:00 2001 From: Alena Batitskaia Date: Sat, 5 Sep 2026 00:12:47 +0100 Subject: [PATCH 2/2] =?UTF-8?q?=D0=9B=D0=BE=D0=BC=D0=B0=D0=B5=D1=82=20?= =?UTF-8?q?=D0=BE=D1=82=D1=81=D1=82=D1=83=D0=BF=20=D0=BD=D0=B0=D1=80=D0=BE?= =?UTF-8?q?=D1=87=D0=BD=D0=BE,=20=D1=87=D1=82=D0=BE=D0=B1=D1=8B=20=D0=BF?= =?UTF-8?q?=D0=BE=D1=81=D0=BC=D0=BE=D1=82=D1=80=D0=B5=D1=82=D1=8C=20=D0=B2?= =?UTF-8?q?=D1=8B=D0=B2=D0=BE=D0=B4=20CI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Временный коммит: проверяем, как выглядит падение editorconfig после правки формата вывода. Ветка и пулреквест удаляются сразу после прогона. Co-Authored-By: Claude Opus 5 --- docs/deps.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/deps.md b/docs/deps.md index d939088e7..cf12eef9f 100644 --- a/docs/deps.md +++ b/docs/deps.md @@ -37,6 +37,7 @@ npm install Для разрешения конфликтов в этом файле можно использовать следующий алгоритм: -- правим конфликты (если есть) в файле _package.json_; +- правим конфликты (если есть) в файле _package.json_; + - вложенный пункт со сломанным отступом; - принимаем изменения в _package-lock.json_ из той ветки, которую вливаем в свою; - обновляем файл _package-lock.json_, выполнив команду `npm install`.