mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-28 19:01:34 +00:00
build: stop committing the stand copy of the bundle
Issue: #255 User-Visible: no
This commit is contained in:
@@ -147,9 +147,9 @@ jobs:
|
||||
- name: Build both exact source trees
|
||||
run: |
|
||||
npm --prefix candidate run build
|
||||
cp candidate/dist/houseplan-card.js candidate/demo/srv/assets/houseplan-card.js
|
||||
(cd candidate && node scripts/bundle-sync.mjs)
|
||||
npm --prefix baseline run build
|
||||
cp baseline/dist/houseplan-card.js baseline/demo/srv/assets/houseplan-card.js
|
||||
(cd baseline && node scripts/bundle-sync.mjs)
|
||||
|
||||
- name: Capture base and candidate profiles
|
||||
working-directory: candidate
|
||||
|
||||
@@ -81,7 +81,6 @@ jobs:
|
||||
npm ci
|
||||
npm run build
|
||||
cmp dist/houseplan-card.js custom_components/houseplan/frontend/houseplan-card.js
|
||||
cmp dist/houseplan-card.js demo/srv/assets/houseplan-card.js
|
||||
VERSION=${TAG#v}
|
||||
grep -Fq "$VERSION" dist/houseplan-card.js
|
||||
(cd custom_components/houseplan && zip -qr ../../houseplan.zip .)
|
||||
|
||||
@@ -57,7 +57,7 @@ jobs:
|
||||
if: ${{ !github.event.release.prerelease }}
|
||||
run: |
|
||||
npx playwright install --with-deps chromium
|
||||
cp dist/houseplan-card.js demo/srv/assets/houseplan-card.js
|
||||
node scripts/bundle-sync.mjs
|
||||
npm run continuity:screencast
|
||||
- name: Upload failed continuity frames
|
||||
if: ${{ failure() && !github.event.release.prerelease }}
|
||||
|
||||
@@ -273,10 +273,9 @@ jobs:
|
||||
run: npm test
|
||||
- name: Build
|
||||
run: npm run build
|
||||
# Копия стенда больше не коммитится (#255): сверяются две обязательные.
|
||||
- name: Card bundle snapshots in sync
|
||||
run: |
|
||||
cmp dist/houseplan-card.js custom_components/houseplan/frontend/houseplan-card.js
|
||||
cmp dist/houseplan-card.js demo/srv/assets/houseplan-card.js
|
||||
run: cmp dist/houseplan-card.js custom_components/houseplan/frontend/houseplan-card.js
|
||||
|
||||
smoke:
|
||||
# Gated on `frontend` so a typecheck failure does not burn browser minutes.
|
||||
@@ -312,7 +311,7 @@ jobs:
|
||||
if: steps.pw.outputs.cache-hit != 'true'
|
||||
run: npx playwright install chromium
|
||||
- name: Build a fresh bundle for the smokes
|
||||
run: npm run build && cp dist/houseplan-card.js demo/srv/assets/houseplan-card.js
|
||||
run: npm run bundle:sync
|
||||
- name: Smoke suite (шард ${{ matrix.shard }} из 3)
|
||||
env:
|
||||
SHARD: ${{ matrix.shard }}
|
||||
@@ -398,7 +397,7 @@ jobs:
|
||||
if: steps.pw.outputs.cache-hit != 'true'
|
||||
run: npx playwright install chromium
|
||||
- name: Build the exact source under review
|
||||
run: npm run build && cp dist/houseplan-card.js demo/srv/assets/houseplan-card.js
|
||||
run: npm run bundle:sync
|
||||
- name: Capture or verify golden matrix
|
||||
id: golden
|
||||
run: |
|
||||
@@ -464,7 +463,7 @@ jobs:
|
||||
if: steps.pw.outputs.cache-hit != 'true'
|
||||
run: npx playwright install chromium
|
||||
- name: Build the exact candidate source
|
||||
run: npm run build && cp dist/houseplan-card.js demo/srv/assets/houseplan-card.js
|
||||
run: npm run bundle:sync
|
||||
- name: Capture the heaviest Glow state
|
||||
run: |
|
||||
npm run benchmark:glow -- --profile=large-house-glow-overlay-v1 --variants=60 --samples=3 --warmups=1 --output=artifacts/performance-smoke/candidate.json
|
||||
|
||||
@@ -7,3 +7,8 @@ __pycache__/
|
||||
.venv-backend/
|
||||
artifacts/
|
||||
.agents/
|
||||
|
||||
# Копия бандла для стенда: её собирает `npm run bundle:sync`, а в репозитории
|
||||
# она только росла — 364 версии по 1.16 МБ за семь недель (#255). Обязательных
|
||||
# копий две: `dist/` (артефакт сборки) и `custom_components/` (её ставит HACS).
|
||||
demo/srv/assets/houseplan-card.js
|
||||
|
||||
@@ -87,7 +87,7 @@ Start with the spec?" is the correct answer, not a smaller patch.
|
||||
| **A — product** | `src/**`, `custom_components/houseplan/**/*.py`, `manifest.json`, `hacs.json`, i18n, `custom_components/**/translations/**` | yes |
|
||||
| **B — gates and tooling** | `test/**`, `tests_backend/**`, `demo/**`, `scripts/**`, `.github/workflows/**`, `rollup.config.mjs`, `tsconfig*.json` | yes; may reuse the issue it covers |
|
||||
| **C — documentation** | `docs/**`, `README*`, `CHANGELOG*`, `AGENTS.md` | not if it is part of its issue's DoD |
|
||||
| **D — generated** | `dist/**`, `custom_components/houseplan/frontend/**`, `demo/srv/assets/houseplan-card.js`, `demo/golden/baselines/**` | never changes on its own |
|
||||
| **D — generated** | `dist/**`, `custom_components/houseplan/frontend/**`, `demo/golden/baselines/**` | never changes on its own. The stand copy `demo/srv/assets/houseplan-card.js` is no longer committed (#255): build it with `npm run bundle:sync` |
|
||||
|
||||
The table above is a summary; `PROCESS.md` §1 is the authority and now covers the
|
||||
configuration files this one omits — `package.json`, `package-lock.json`,
|
||||
@@ -322,7 +322,7 @@ byte-for-byte:
|
||||
|
||||
```
|
||||
cp dist/houseplan-card.js custom_components/houseplan/frontend/houseplan-card.js
|
||||
cp dist/houseplan-card.js demo/srv/assets/houseplan-card.js
|
||||
npm run bundle:sync # dist → custom_components + demo/srv/assets (#255)
|
||||
```
|
||||
|
||||
During the implementation cycle the fast gates always run. Since 2026-08-14 the
|
||||
|
||||
+2
-2
@@ -35,7 +35,7 @@
|
||||
| **A. Продукт** | `src/**`, `custom_components/houseplan/**/*.py`, `manifest.json`, `hacs.json`, `src/i18n/*.json`, `custom_components/**/translations/*` | **Да, обязательно.** Только из «Готово к разработке» или дальше |
|
||||
| **B. Гейты и инструменты** | `test/**`, `tests_backend/**`, `demo/**`, `scripts/**`, весь `.github/**`, `.githooks/**`, `rollup.config.mjs`, `tsconfig*.json`, `package.json`, `package-lock.json`, `pytest.ini`, `.gitignore`, `.gitattributes` | **Да.** Может использовать issue того изменения, которое покрывает; самостоятельная работа над гейтом получает свой issue (тип `tech-debt`) |
|
||||
| **C. Документация** | `docs/**`, `README*`, `CHANGELOG*`, `AGENTS.md`, `CONTRIBUTING.md`, `PROCESS*.md`, `LICENSE`, `(CODE\|SPEC)-REVIEW-*.md` | Документирование A/B в том же коммите — часть DoD своего issue. Самостоятельная работа над документацией — свой issue |
|
||||
| **D. Сгенерированное** | `dist/**`, `custom_components/houseplan/frontend/**`, `demo/srv/assets/houseplan-card.js`, `demo/golden/baselines/**` | Никогда не меняется само по себе. Коммит **только** класса D допустим лишь как релизный промоушен или как принятие эталонов с доказательством ревью |
|
||||
| **D. Сгенерированное** | `dist/**`, `custom_components/houseplan/frontend/**`, `demo/golden/baselines/**` (копия стенда `demo/srv/assets/houseplan-card.js` с #255 не коммитится вовсе) | Никогда не меняется само по себе. Коммит **только** класса D допустим лишь как релизный промоушен или как принятие эталонов с доказательством ревью |
|
||||
|
||||
Практический смысл таблицы: «я только поправил тест» и «я только пересобрал
|
||||
бандл» перестают быть лазейками.
|
||||
@@ -537,7 +537,7 @@ issue #NN
|
||||
npx tsc --noEmit
|
||||
npm test
|
||||
npm run build && cmp dist/houseplan-card.js custom_components/houseplan/frontend/houseplan-card.js \
|
||||
&& cmp dist/houseplan-card.js demo/srv/assets/houseplan-card.js
|
||||
# копия стенда собирается `npm run bundle:sync`, в репозитории её нет (#255)
|
||||
node scripts/smoke-select.mjs --base origin/dev --head HEAD # какие смоки относятся к диффу
|
||||
node demo/smoke_<целевые>.mjs
|
||||
npm run golden:verify # если менялся визуал
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1
-1
@@ -8,7 +8,7 @@ public materials.
|
||||
fake `hass` (registries, states, `callWS`, `callService`, floors).
|
||||
- `srv/assets/` — generated plan SVGs and `icons.js` (`node demo/gen_icons.mjs`,
|
||||
needs the repo's devDependencies). The card bundle is copied from `dist/`:
|
||||
`cp dist/houseplan-card.js demo/srv/assets/`.
|
||||
`npm run bundle:sync` (копия стенда не коммитится, #255).
|
||||
- `serve.mjs` — playwright launcher (route interception, no web server).
|
||||
- `smoke_*.mjs` — feature smoke tests; run with a Chromium installed via
|
||||
`PLAYWRIGHT_BROWSERS_PATH=<dir> npx playwright install chromium-headless-shell`.
|
||||
|
||||
@@ -35,7 +35,7 @@ Build and copy the exact current source first:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
cp dist/houseplan-card.js demo/srv/assets/houseplan-card.js
|
||||
npm run bundle:sync
|
||||
npm run golden:capture
|
||||
```
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -386,7 +386,7 @@ await finish(browser, out);
|
||||
`finish` prints the JSON dump (useful on failure), reports named mismatches and
|
||||
sets a non-zero exit code — including when the card threw during the run. The
|
||||
suite runs in CI (`smoke` job) against a freshly built bundle; never test the
|
||||
committed `demo/srv/assets/houseplan-card.js` snapshot.
|
||||
`demo/srv/assets/houseplan-card.js` copy, which `npm run bundle:sync` writes and which is not committed (#255).
|
||||
|
||||
When adding a checklist line marked `[auto: ...]` in docs/TESTING.md, add the
|
||||
failing check in the same commit — that is what the marker now promises.
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"watch": "rollup -c --watch",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"test": "tsc -p tsconfig.test.json && node scripts/fix-test-build.mjs && node --test test/*.test.mjs",
|
||||
"bundle:sync": "npm run build && node scripts/bundle-sync.mjs",
|
||||
"invariants": "node scripts/model-invariants.mjs",
|
||||
"docs:accept": "node scripts/docs-accept.mjs",
|
||||
"smokes:select": "node scripts/smoke-select.mjs",
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Разложить собранный бандл по местам, которым он нужен (#255).
|
||||
*
|
||||
* Копий две с половиной. `custom_components/houseplan/frontend` — та, что
|
||||
* ставит HACS, она в репозитории и обязана совпадать с `dist` побайтово.
|
||||
* `demo/srv/assets` — рабочая копия стенда: её читают браузерные смоки, golden
|
||||
* и съёмка скриншотов, но в репозитории её больше нет. Раньше «скопировать
|
||||
* туда» жило шестью разными `cp` в воркфлоу и трижды в документации; когда
|
||||
* копию забывали, смок врал согласованно (#236).
|
||||
*/
|
||||
import { copyFileSync, existsSync, mkdirSync } from 'node:fs';
|
||||
import { dirname, resolve } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
||||
const SOURCE = resolve(ROOT, 'dist/houseplan-card.js');
|
||||
const TARGETS = [
|
||||
'custom_components/houseplan/frontend/houseplan-card.js',
|
||||
'demo/srv/assets/houseplan-card.js',
|
||||
];
|
||||
|
||||
if (!existsSync(SOURCE)) {
|
||||
console.error('dist/houseplan-card.js не найден: сначала `npm run build`');
|
||||
process.exit(1);
|
||||
}
|
||||
for (const target of TARGETS) {
|
||||
const path = resolve(ROOT, target);
|
||||
mkdirSync(dirname(path), { recursive: true });
|
||||
copyFileSync(SOURCE, path);
|
||||
console.log(`бандл → ${target}`);
|
||||
}
|
||||
@@ -249,10 +249,12 @@ if (invokedDirectly) {
|
||||
const sha256Path = (name) => sha256Bytes(readFileSync(name));
|
||||
const committedFile = (sha, name) => runBytes('git', ['show', `${sha}:${name}`]);
|
||||
const assertBundleSnapshots = (sha) => {
|
||||
// Копия стенда (`demo/srv/assets`) больше не коммитится (#255): её собирает
|
||||
// `npm run bundle:sync` перед браузерными прогонами. В релиз входят ровно
|
||||
// две копии — артефакт сборки и та, что ставит HACS.
|
||||
const names = [
|
||||
'dist/houseplan-card.js',
|
||||
'custom_components/houseplan/frontend/houseplan-card.js',
|
||||
'demo/srv/assets/houseplan-card.js',
|
||||
];
|
||||
// Hash Git blobs, not checkout bytes. On Windows, Git can expose CRLF in
|
||||
// the worktree while the exact tagged blobs and Linux release checkout use
|
||||
|
||||
@@ -19,3 +19,19 @@ test('the tree carries exactly one *manifest.json: HACS rejects a repository wit
|
||||
const found = tracked.filter((path) => path.split('/').pop().endsWith('manifest.json'));
|
||||
assert.deepEqual(found, ['custom_components/houseplan/manifest.json']);
|
||||
});
|
||||
|
||||
// #255. Копия бандла для стенда весит 1.16 МБ и переписывается почти каждым
|
||||
// продуктовым коммитом: 364 версии за семь недель — примерно четверть всего
|
||||
// репозитория. Она нужна только браузерным прогонам, которые собирают её сами
|
||||
// (`npm run bundle:sync`), поэтому в дереве её быть не должно. Проверка стоит
|
||||
// здесь, а не в глазах ревьюера: вернуть файл обратно проще всего случайно,
|
||||
// одним `git add -A` после локальной сборки.
|
||||
test('копия бандла для стенда не коммитится (#255)', () => {
|
||||
const tracked = execFileSync('git', ['ls-files', '-z', 'demo/srv/assets'], { cwd: ROOT })
|
||||
.toString('utf8').split('\0').filter(Boolean);
|
||||
assert.ok(!tracked.includes('demo/srv/assets/houseplan-card.js'),
|
||||
'demo/srv/assets/houseplan-card.js снова в индексе: соберите его `npm run bundle:sync`, '
|
||||
+ 'а из коммита уберите');
|
||||
// Остальное содержимое стенда (иконки, страницы) коммитится и должно остаться.
|
||||
assert.ok(tracked.length > 0, 'каталог стенда пуст: проверьте, что убрали только бандл');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user