diff --git a/DEVLOG.md b/DEVLOG.md index f0cf44d2..37666696 100644 --- a/DEVLOG.md +++ b/DEVLOG.md @@ -883,3 +883,21 @@ P30 先前已收完 15 個必修缺口;這輪把剩下 15 組建議項目逐 **交叉 review 額外收掉的邊界**:修正 `hover-card-content` package/registry 四個 template handler 的 `protected` 可見性 drift;刪除 registry combobox 與 `SanringCvaBase` 完全重複的 `onFocus`/`onBlur`;補 Dialog title/description 放在 nested `DialogHeader` 時的 ARIA 測試,以及 Sheet 開啟後 panel focus 測試。Transfer 使用錯誤的 `--sanring-primary-foreground` token 也改回既有 `--sanring-primary-fg`。 **驗證**:`pnpm exec ng test "@sanring/ui" --watch=false` 為 70 個 spec 檔、**421 個測試全過**;`pnpm exec ng build "@sanring/ui"` 成功;P30 修改範圍 ESLint、Prettier、`git diff --check` 通過;`pnpm exec ngc -p apps/docs/tsconfig.app.json --noEmit` 通過;`check-registry-sync.mjs`(52/52)與 `check-registry-parity.mjs`(52 個 shared component directories)皆綠燈;Docs production build 成功,initial bundle 435.37 kB。首次 Docs build 的 `SIGABRT` 由 macOS crash report 定位到 Angular 22 local build cache 的 native LMDB `ExtendedEnv`(不是編譯診斷);清除 `.angular/cache` 後仍可重現,該次驗證以 `CI=true` 停用 local persistent cache,並在允許 Google Fonts inline request 後完整通過。 + +**追加查證與修復(2026-08-22)**:這輪驗證涵蓋 `packages/ui`/`registry` 原始碼本身,但沒有涵蓋「registry 發布 metadata 有沒有跟著同步」——`transfer` 把打勾指示器從內嵌 `sanring-checkbox` 改成 `@lucide/angular` 的 `LucideCheck` 圖示(本節「Transfer 與 Tree」段落所述改動)時,新增的 `@lucide/angular` import 沒有同步反映到 `registry/registry.json` 的 `transfer.peerDependencies`。這類漂移原本該被 `packages/cli/src/commands/build.test.ts` 的 golden-fixture 測試(掃描 `registry/components/` 實際 import 並與手寫 `registry.json` 逐一比對)抓到,但 `.github/workflows/ci.yml` 的 `test-cli` job 一直缺一個步驟(見下方 P31),這個測試從未在乾淨 checkout 上真正跑過,所以完全沒被察覺,直到下一個 session 為了排查一個無關的版本發布 PR 的 CI 失敗才連帶挖出來。已在 `registry/registry.json` 補上 `transfer.peerDependencies.@lucide/angular`,`build.test.ts` golden fixture 重新綠燈(52 個元件零已知落差)。**教訓**:往後任何會改到元件 import 的修正(尤其是新增/替換 icon、shared util 依賴),要記得跑一次 `pnpm --filter @sanring/cli test`(或至少 `build.test.ts` 的 golden fixture)確認 `registry.json` metadata 沒有漂移,光靠 `check-registry-sync.mjs`/`check-registry-parity.mjs` 不夠——那兩支腳本比對的是「檔案存在性」與「Angular 結構/a11y attribute」,不比對 peerDependencies 是否對得上實際 import。 + +--- + +## P31 — `ci.yml` 的 `test-cli` job 從未在乾淨環境跑過 + picocolors CI-only 測試污染 + +**背景**:幫 `@sanring/cli` 準備一個版本發布 PR 時,`Test (@sanring/cli)` CI check 失敗,查證後發現不是這次改動造成的——查了 repo 至今僅有的兩次 `ci.yml` 執行紀錄(2026-08-07、2026-08-22),兩次都因為同一個原因掛掉:`packages/cli/registry/`(`.gitignore` 排除、只有 `pnpm --filter @sanring/cli build` 內部的 `sync-registry` 步驟才會產生的目錄)在乾淨 checkout 上不存在,但至少一個既有測試(`registry.test.ts` 的「falls back to the bundled local registry」案例)直接讀這個目錄。本機一直測得過是因為開發機上通常至少跑過一次 `build`,留下了這份沒進版控的產物;CI 從沒補過這一步,等於這條測試路徑從沒被驗證過。 + +**修復**:`ci.yml` 的 `test-cli` job 在 `pnpm install` 之後、`pnpm --filter @sanring/cli test` 之前,補一個「Sync registry fixtures」步驟跑 `pnpm --filter @sanring/cli run sync-registry`。 + +**修復後浮現的第二層問題**:sync-registry 補上後,9 個 ENOENT 失敗消失,但浮出一個真正的 golden-fixture 落差(見上方 P30 追加段落的 `transfer` peerDependencies 漂移)與 4 個只在 CI 環境失敗、本機重跑多次都過的測試(`add.test.ts` x2、`info.test.ts`、`search.test.ts`)。用 OrbStack 起一個 `node:24-bookworm` 容器、完整重建 `node_modules`(bind mount 進來的 host `node_modules` 含 macOS 的 native binary,不能直接借用,要在容器內重新 `pnpm install`)、手動設 `CI=true`/`GITHUB_ACTIONS=true` 精確重現 GitHub Actions runner 後,100% 可重現、非 flaky。根因:`picocolors`(CLI 輸出上色用的套件)把任何 truthy 的 `CI` 環境變數當成「有 color 支援」的訊號(`isColorSupported = ... || !!env.CI`),而 GitHub Actions 預設就會設 `CI=true`;本機互動式跑測試時沒有這個變數,色碼關閉。結果是 CLI 輸出在 CI 裡夾帶 ANSI escape code(例如 `Installed \x1b[2m(1):\x1b[22m \x1b[1mwidget\x1b[22m`),把原本假設純文字的字面比對(`output.includes('Already installed: @lucide/angular')`、`/Installed \(1\).*widget/`)全部斷開——本機測不到,CI 100% 會中。 + +**修復**:`packages/cli/vitest.config.ts` 的 `test.env` 補 `NO_COLOR: '1'`,讓 CLI 輸出(進而讓這些斷言)在 CI 與本機行為一致,而不是逐一修每條斷言去容忍 ANSI code。 + +**額外的流程修正(跟這兩個 CI bug 無關,是同一輪順手發現並修正的操作失誤)**:原本手動跑了 `pnpm changeset version` 把兩份 changeset 直接消耗掉、產生 0.24.0 並連同版號改動一起開 PR,結果讓 `.github/workflows/require-changeset.yml` 判定「這個 PR 沒有待處理的 changeset」而失敗。查 `gh pr list` 撈出的完整歷史(#1–#26)後確認:這個 repo 27 次版本紀錄裡有 26 次都是 `changesets/action` bot 自動開的 `chore: version packages` PR(分支 `changeset-release/main`)在做真正的 bump,只有一次(0.23.2→0.23.3)是例外手動直接推到 `main`(沒經過 PR,所以沒撞到這個檢查)。修正方式是把 `packages/cli/package.json`/`CHANGELOG.md` 改回 0.23.3、把兩份 changeset 檔案原樣留著(不消耗),讓 bot 在這個 PR 合併進 `main` 後自己開版號 PR。**教訓**:`packages/cli`/`registry` 的版本發布一律讓 changeset 檔案跟著功能改動落地就好,不要手動跑 `changeset version`——那是 bot 的工作,手動搶著做只會跟 `require-changeset.yml` 打架。 + +**驗證**:Docker 重現(`node:24-bookworm`、`CI=true`、`GITHUB_ACTIONS=true`、`--frozen-lockfile`、`sync-registry`、`vitest run`)240/240 通過;`pnpm changeset status --since=origin/main` 通過;PR #27 的六個 GitHub Actions check(Lint、Test (@sanring/cli)、Test (@sanring/ui)、Type check、Registry Sync Check、Require Changeset)全綠。