mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-06 22:49:16 +00:00
ci: prove the screenshot environment instead of trusting the place
Правило приёмки скриншотов было про место: снимать только в CI. Обоснование измерено — съёмка в другом окружении переписывает файлы без содержательных изменений, в #231 два из девяти на 7–8 байт, набор с беты все девять. Но держалось правило на комментарии, а не на механизме: кандидат проверялся на самосогласованность и принимался целиком, ни разу не сравниваясь с тем, что лежит в репозитории. Цена видна на #390: правка типов, которая физически не может сдвинуть пиксель, потребовала прогона workflow, а затем правки одиннадцати полей манифеста руками. Теперь правило про доказательство, и оно то же, что у golden с #334: среда доказана, если каждый кадр, который менять не собирались, совпал с закоммиченным байт-в-байт. Расхождение растеризации спрятать нельзя — оно задевает все кадры с текстом сразу. Снимать можно где угодно, включая WSL; принять получится только оттуда, где кадры воспроизводятся, и перестанет получаться в тот день, когда обновятся шрифты. Остальное следует из того же правила: намерение объявляется --expect-change, необъявленное расхождение останавливает приёмку, объявленное без расхождения — тоже (ложная декларация обесценивает список), заменяются ровно объявленные файлы, а тотальная перерисовка требует --no-witnesses --reason, и причина уезжает в манифест. Частый случай закрылся сам: ничего не объявлено, все кадры совпали — принимается один манифест, руками ничего писать не надо. Проверено шестью сквозными прогонами на подделанном артефакте, не только юнитами: идентичный кандидат, необъявленное расхождение, объявленное, молчаливая декларация, тотальная перерисовка без причины и с ней. Issue: #401 User-Visible: no
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
import { createHash } from 'node:crypto';
|
||||
import { readFileSync } from 'node:fs';
|
||||
|
||||
import { verifyDocsCandidate } from '../scripts/docs-accept.mjs';
|
||||
import { DOC_SCREENSHOT_VERSION, DOC_SCREENSHOTS } from '../demo/docs/screenshots.mjs';
|
||||
@@ -128,3 +129,20 @@ test('разбор пути фикстуры не зависит от разде
|
||||
assert.equal(basename('C:/artifact/sub\\02-view-touch.png'), '02-view-touch.png');
|
||||
assert.equal(basename('01-view-desktop.png'), '01-view-desktop.png');
|
||||
});
|
||||
|
||||
test('правило среды в шапках совпадает с реализацией (#401)', () => {
|
||||
// Предыдущее правило («снимать только в CI») жило исключительно в
|
||||
// комментарии, и разошлось с реальностью в тот день, когда появилась цена.
|
||||
// Этот тест держит текст и механизм вместе.
|
||||
const script = readFileSync(new URL('../scripts/docs-accept.mjs', import.meta.url), 'utf8');
|
||||
const workflow = readFileSync(
|
||||
new URL('../.github/workflows/docs-screenshots.yml', import.meta.url), 'utf8',
|
||||
);
|
||||
for (const [name, text] of [['docs-accept.mjs', script], ['docs-screenshots.yml', workflow]]) {
|
||||
assert.match(text, /#401/, `${name}: правило приёмки не сослано на решение`);
|
||||
assert.match(text, /байт-в-байт/, `${name}: не назван признак доказанной среды`);
|
||||
}
|
||||
assert.match(script, /--expect-change/, 'декларация намерения обязана быть в описании');
|
||||
assert.equal(/снимать только в CI|только из артефакта CI/.test(workflow), false,
|
||||
'старое правило про место съёмки осталось в тексте');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user