Uh oh!
There was an error while loading. Please reload this page.
Add automated testing infrastructure and CI/CD workflows - #2
Conversation
Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
…ton test Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
huangyiirene
commented
Jan 13, 2026
@copilot 34.4524084Z ##[group]Run pnpm install --frozen-lockfile |
Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
Fixed in commit 5803195. The issue was a pnpm version mismatch - the lockfile was generated with pnpm 10.28.0, but the CI workflows were configured to use pnpm 8. Updated all workflows (ci.yml, pr-checks.yml, release.yml) to use pnpm version 10, which is compatible with the lockfile format. |
There was a problem hiding this comment.
Pull request overview
This PR establishes a comprehensive automated testing infrastructure and CI/CD pipeline for the Object UI monorepo project. It introduces Vitest as the testing framework with React Testing Library, adds 36 passing tests across all core packages, and implements GitHub Actions workflows for continuous integration, releases, and pull request validation.
Changes:
- Added Vitest testing framework with configuration and 36 tests across 5 packages (@object-ui/protocol, @object-ui/engine, @object-ui/renderer, @object-ui/ui, @object-ui/designer)
- Implemented three GitHub Actions workflows (CI, Release, PR Checks) with multi-node testing and coverage reporting
- Updated all package configurations with test scripts and TypeScript exclusions for test files
- Added comprehensive documentation (TESTING.md, CONTRIBUTING.md, CHANGELOG.md) and updated README with testing instructions and CI badges
Reviewed changes
Copilot reviewed 25 out of 26 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| vitest.config.ts | Main Vitest configuration with coverage settings and package aliases |
| vitest.setup.ts | Test setup file importing jest-dom matchers |
| packages/*/tsconfig.json | Updated to exclude test files from TypeScript compilation |
| packages//src/tests/.test.tsx | Added comprehensive test suites for all core packages |
| packages/*/package.json | Updated test scripts to use Vitest |
| package.json | Added testing dependencies and updated test scripts |
| .github/workflows/*.yml | Added CI, Release, and PR Checks workflows |
| TESTING.md | Comprehensive testing documentation |
| CONTRIBUTING.md | Contributor guidelines with testing instructions |
| CHANGELOG.md | Project changelog tracking changes |
| README.md | Updated with testing section, CI badges, and pnpm version requirement |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Uh oh!
There was an error while loading. Please reload this page.
- Fix handleExportCSV to guard on gridRef.current?.api (issue #1) - Add dedicated onContextMenuAction callback instead of overloading onCellClicked (issue #2) - Remove icon property from customItems to prevent HTML injection (issue #3) - Remove validation claim from README - only basic AG Grid editing (issue #4) - Add test assertions for all new inputs (editable, exportConfig, etc.) (issue #5) - Fix onExport type to only support 'csv' format (issue #6) - Remove unused ColumnConfig properties (autoSize, groupable) (issue #9) - Type schema props with proper interfaces instead of 'any' (issue #10) - Update export description to only mention CSV (issue #11) - Add AG Grid Community vs Enterprise section to docs (issue #8) - Update README and docs with new callback and clarifications All tests pass (8/8), lint clean (0 errors) Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
commandment #2(docs-driven):ci.yml 的 docs job 多了一步 Check docs links, 该页的 job 表格原文只写了 turbo build,已同步。 另在 Link Checking 一节补一张对照表,写清两个检查器各管什么: check-doc-links.mjs 管站内 /docs/... 路由、不走网络、在 ci.yml 里跑; Lychee 管外链、走网络、只能手动触发。并写明两个已知缺口(#3448 纯 docs PR 不触发 ci.yml;#3449 Lychee 扫的是 docs/ 而非 content/docs/),以免读者从这一页 得出「文档链接已被完全守住」的结论。 未改该页既有的其它内容(如 job 数量与 dev-server 行的既存漂移),另行记录。 验证:pnpm exec vitest run scripts/__tests__/ -> 8 files / 120 tests passed (含 ci-cd-pipeline-doc.test.ts 的 9 条,它正是钉这一页的)。
…bjectstack-ai#3292) (objectstack-ai#3450) * ci(docs): 把 check-doc-links 接进 CI,并修好它一直在报的那条坏链 (objectstack-ai#3213, objectstack-ai#3292) scripts/check-doc-links.mjs 早就存在且能用,但 .github/ 下零调用 —— 它在未 改动的 origin/main 上就 exit 1,报 content/docs/core/enhanced-actions.mdx -> /docs/components/form 断链,却从来没有工作流跑过它。 两处改动: 1. 坏链改指 /docs/components/form/form(retarget,不补 index 页)。 content/docs/components/ 下 9 个分类目录全部没有 index 页,补一个会是 components 树里唯一的例外;components/index.md 自己也是用代表页链到分类 (如 /docs/components/form/button),从不链裸分类路由;form/meta.json 显式 列出 pages 且不含 index。而该句 "- [Form](...) - Form submission actions" 指向的正是 form/form.mdx(title: Form,description: Form container with validation and submission handling),不是 button。 2. ci.yml 的 docs job 加一步 Check docs links,放在 Setup Node.js 之后、 install 与站点构建之前 —— 脚本零依赖零网络,坏链几秒内失败,不必等一次 完整的 Next.js 构建。 已知缺口(不在本次裁决范围,已记为 objectstack-ai#3448):ci.yml 的 paths-ignore 含 content/**,GitHub 又没有 per-job path filter,所以纯 docs PR 根本不会启动这个 workflow。control-bytes.yml 撞过同一堵墙并靠独立 workflow 解决,文件头写明了 理由。本步骤覆盖 docs+代码混合 PR 与 push to main。 check-links.yml(Lychee)按裁决维持 workflow_dispatch;有意未加 cron —— 它扫的 是 docs/**(15 个内部文件)而非 content/docs/**(183 个站点文档),范围修正前 加 cron 只会按时产出一份不覆盖站点文档的绿报告(已记为 objectstack-ai#3449)。 验证:改前 node scripts/check-doc-links.mjs -> exit 1(1 broken link); 改后 -> exit 0 "Docs links are valid." * docs(ci): 把新增的链接门禁写进 ci-cd-pipeline.md,并说明两个检查器的分工 commandment objectstack-ai#2(docs-driven):ci.yml 的 docs job 多了一步 Check docs links, 该页的 job 表格原文只写了 turbo build,已同步。 另在 Link Checking 一节补一张对照表,写清两个检查器各管什么: check-doc-links.mjs 管站内 /docs/... 路由、不走网络、在 ci.yml 里跑; Lychee 管外链、走网络、只能手动触发。并写明两个已知缺口(objectstack-ai#3448 纯 docs PR 不触发 ci.yml;objectstack-ai#3449 Lychee 扫的是 docs/ 而非 content/docs/),以免读者从这一页 得出「文档链接已被完全守住」的结论。 未改该页既有的其它内容(如 job 数量与 dev-server 行的既存漂移),另行记录。 验证:pnpm exec vitest run scripts/__tests__/ -> 8 files / 120 tests passed (含 ci-cd-pipeline-doc.test.ts 的 9 条,它正是钉这一页的)。 --------- Co-authored-by: Claude <noreply@anthropic.com>
… GitHub URL 离线校验 (objectstack-ai#3542) * feat(scripts): 门禁两向扩展 —— 扫描面扩到 examples/** 与根 README,自仓 GitHub URL 离线校验 `check-doc-links` 原本只看 `content/docs`,且按 scheme 跳过所有 https 链接。 两个已有实证的盲区因此各自积累过死链,本次一并补上(objectui#3536)。 ## 扩展一:扫描面 → `examples/**` + 根 `README.md`,但用另一套规则 关键不是"多扫两个目录",而是**这两组文件的链接语义根本不同**:它们在 GitHub 上 被阅读,相对链接是**磁盘路径**,不是 fumadocs 路由。因此新增按扫描根分流的 `SCAN_ROOTS` 表,`disk` 规则只问"存在与否": - 目录(`./packages/core`)、非 markdown 文件(`./vite.config.ts`)、无扩展名文件 (`./LICENSE`)都是合法目标 —— docs 规则的 `routeCandidates()` 在这里没有意义; - 没有"collection"可逃逸 —— console-starter 的 README 链到 `../../packages/...` 和 `../../content/docs/...` 都能正常渲染,唯一的边界是仓库根; - markdown 文件的无扩展名写法在 docs 规则下放行(浏览器可能解析),在 GitHub 上 却是实打实的 404,故 `disk` 规则不放行。 把 docs 规则硬套到这两组文件上会误报 **61 条**当前渲染正常的链接(已实测,见 PR 正文)。 绝对 `/...` href 判为拒绝(`example-absolute`):这两组文件里目前一条都没有,属预防性, 但方向是渲染器决定的 —— GitHub 把开头的 `/` 解析到 github.com 而非本仓, 根 README 里的 `/packages/core` 指向 https://github.com/packages/core。 ## 扩展二:`.../(blob|tree)/main/<path>` 的离线路径校验 这类"写成外链的仓内引用"卡在两个门禁之间:本脚本按 scheme 跳过,lychee 是 周 cron + continue-on-error 不 gate PR,曾有两条死了约三个月(objectstack-ai#3507)。现在在 **所有**扫描面校验其路径存在于工作树 —— 包括 `content/docs`,因为 `escapes-collection` 的提示本就推荐这种写法,不校验等于推荐一种没人管的形态。 刻意收窄:只认 `main`、只认本仓、只认路径(`#fragment` 不在范围)、只认 blob|tree (`/issues` 与 badge URL 是 github.com 站内路由,继续跳过)。 ## 其他 - `collectBrokenLinks(repoRoot)` 改为只收仓库根:调用方无法再配置掉某个扫描面或 `apps/site` 真源而得到一个"其实什么都没看"的绿。CLI 的仓库根由脚本自身位置推导, 避免从子目录运行时扫不到东西却报成功。 - 新增三个 reason 与对应 HINTS:`example-relative` / `example-absolute` / `self-repo-url`;新增测试覆盖两向扩展的拒绝类与放行类,并含两条规则的对照用例。 - 按 AGENTS.md objectstack-ai#2 就近更正 `ci-cd-pipeline.md` 中已被本次改动证伪的描述。 Fixesobjectstack-ai#3536 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt * docs(ci-cd-pipeline): 表格单元格改用两个独立 code span,避免转义竖线 在 markdown 表格的 code span 里写 `blob\|tree` 依赖转义竖线的渲染行为, 不同渲染器结果不一致。拆成 `blob/main/` 与 `tree/main/` 两个 span,语义不变。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt --------- Co-authored-by: Claude <noreply@anthropic.com>
The module-script shape shipped in the previous commit was TOO LATE, and the console's own build proves it. Vite merges the two HTML module entries into a single chunk, and that merged entry's static imports are hoisted above the shim's body, so in dist/assets/index-*.js the install sat behind 16 imported chunks - vendor-react, ui-components and RecordDetailView among them, all three of which contain randomUUID calls. Document order between module scripts is real in the browser but it does not survive bundling, so it cannot carry this guarantee. A classic inline script runs synchronously during parse, before any module script and therefore before any bundled chunk. That is the only bundler-independent guarantee, and it is the precedent the report named: the window.process polyfill immediately above it. Verified on the built artifact - the shim is tag #2 of 4 in dist/index.html and the only src-carrying tag is #3. The TypeScript module is deleted rather than kept for testability: a second copy of the logic would be graded green while the bootstrap that actually ships drifted away from it. The tests now EXTRACT the inline script from index.html and execute it, so they grade exactly what ships, and they fail loudly ("found 0") rather than vacuously if it is renamed or removed. Two parsing hazards found by these tests and worth keeping written down: prose describing a script tag inside an HTML comment parses as a script tag (the comment above this very shim was once paired with the shim's closing tag, reporting it as type=module), so both tests strip comments before parsing; and this app's tsconfig is browser-only, so index.html is read through Vite's `?raw` rather than node:fs, which tsc rejects. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Qqyix2QcnpUC9XeYVDzx3
Optimization Plan: Automated Testing and Basic Workflows ✅
Phase 1: Testing Infrastructure ✅
Phase 2: Write Tests for Core Packages ✅
Phase 3: GitHub Actions Workflows ✅
Phase 4: Additional Improvements ✅
🎉 Summary
All objectives completed successfully! The project now has:
Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.