mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
Классификация changes вынесена в scripts/classify-changes.mjs (выходы perf_iso/perf_interaction, fallback --all). performance_smoke добавляет large-house-isometric-v1 при правке src/iso-* и large-house-interaction-v1 при правке живого пути, по 3 образца против hardMaxMs полных профилей (budgets-*-smoke.json). Набор профилей входит в ключ reuse. PROCESS.md §8. Issue: #473 User-Visible: no
60 lines
3.5 KiB
JavaScript
Executable File
60 lines
3.5 KiB
JavaScript
Executable File
// Классификация изменённых файлов для job `changes` в validate.yml (#473 AC8).
|
|
//
|
|
// Шаблоны жили inline в shell-шаге `classify` как `has('regex')`. Пока выходов
|
|
// было три, это терпимо; с диффозависимыми профилями перф-смока (#473) их
|
|
// пять, и вопрос «запустит ли правка src/iso-x.ts изометрический профиль»
|
|
// стал вопросом к workflow, на который нельзя ответить тестом — shell в YAML
|
|
// не исполняется локально. Теперь ответ даёт функция, а shell только
|
|
// переписывает её вывод в `$GITHUB_OUTPUT`.
|
|
//
|
|
// Контракт неизменен: каждый выход — строка 'true'/'false', как её и читают
|
|
// условия `if: needs.changes.outputs.X == 'true'`. Fallback «полный прогон
|
|
// без классификации» (--all) выставляет все выходы в 'true' — в том числе те,
|
|
// что появятся позже: пропущенный ключ в fallback-е означал бы, что job
|
|
// с этим условием молча не запускается ровно в тех прогонах, где база
|
|
// недоказуема и проверять надо всё.
|
|
|
|
import { readFileSync } from 'node:fs';
|
|
|
|
export const CLASSIFIERS = {
|
|
frontend: /^(src\/|demo\/|test\/|dist\/|custom_components\/houseplan\/frontend\/|package(-lock)?\.json$|rollup\.config\.mjs$|tsconfig)/,
|
|
backend: /^(custom_components\/.*\.py$|tests_backend\/|scripts\/support-relay\/|pytest\.ini$)/,
|
|
integration: /^(custom_components\/houseplan\/manifest\.json$|hacs\.json$|custom_components\/.*\.py$|custom_components\/.*\/translations\/)/,
|
|
// Перф-смок (#473 §5): изометрический профиль — при правке изометрии,
|
|
// профиль взаимодействия — при правке живого пути и оркестраторов кадра.
|
|
// Только `src/**`: тесты и демо кадр не замедляют.
|
|
perf_iso: /^src\/iso-[^/]+\.ts$/,
|
|
perf_interaction: /^src\/(live-[^/]+|render-[^/]+|houseplan-render-lifecycle|houseplan-card)\.ts$/,
|
|
};
|
|
|
|
export const OUTPUTS = Object.keys(CLASSIFIERS);
|
|
|
|
/** Список файлов → выходы job `changes` ('true'/'false' по каждому ключу). */
|
|
export function classifyChanges(files) {
|
|
const list = (Array.isArray(files) ? files : String(files).split('\n'))
|
|
.map((file) => file.trim()).filter(Boolean);
|
|
const result = {};
|
|
for (const [name, pattern] of Object.entries(CLASSIFIERS)) {
|
|
result[name] = list.some((file) => pattern.test(file)) ? 'true' : 'false';
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/** Fallback без классификации: всё прогоняется. */
|
|
export function classifyAll() {
|
|
return Object.fromEntries(OUTPUTS.map((name) => [name, 'true']));
|
|
}
|
|
|
|
/** Формат `$GITHUB_OUTPUT`. */
|
|
export function formatOutputs(outputs) {
|
|
return OUTPUTS.map((name) => `${name}=${outputs[name]}`).join('\n') + '\n';
|
|
}
|
|
|
|
const invokedDirectly = process.argv[1]
|
|
&& import.meta.url === new URL(`file://${process.argv[1]}`).href;
|
|
if (invokedDirectly) {
|
|
const all = process.argv.includes('--all');
|
|
const outputs = all ? classifyAll() : classifyChanges(readFileSync(0, 'utf8'));
|
|
process.stdout.write(formatOutputs(outputs));
|
|
}
|