Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 22 additions & 6 deletions .github/workflows/changeset-guard.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
name: Changeset Guard

# Why this is its own workflow instead of a job in `ci.yml`: a changeset is a
# markdown file under `.changeset/`, and both `ci.yml` and `lint.yml` list
# `'**/*.md'` AND `.changeset/**` under `paths-ignore`. A PR that adds only a
# changeset therefore starts no workflow at all — which is exactly the PR this
# check needs to see. GitHub has no per-job path filter, so the gate lives here,
# with the inverse trigger: it runs *only* when `.changeset/**` changes.
# Why this is its own workflow instead of a job in `ci.yml`: on a PR that adds
# only a changeset, every gate inside `ci.yml` and `lint.yml` skips, so nothing
# in either of them ever reads the changeset — which is exactly the PR this check
# needs to see. It has to run outside that decision.
#
# That is no longer the reason this header used to give. It said both `ci.yml`
# and `lint.yml` list `'**/*.md'` AND `.changeset/**` under `paths-ignore`, so a
# changeset-only PR "starts no workflow at all". objectui#3523 step 2 deleted
# `paths-ignore` from their `pull_request` trigger; it remains ONLY on `push`.
# Such a PR does start both workflows and does produce their contexts — measured:
# PR #3856 (one markdown file) 16 checks, PR #4339 (one line added to AGENTS.md)
# 17. The correction is objectui#3857; an author had already acted on the old
# sentence and got the opposite result.
#
# What #3523 moved rather than deleted is the path DECISION: it is now the
# `Decide whether this change needs a full run` step in `ci.yml`, with a twin in
# `lint.yml`, and its exclusion list is that `push` filter unchanged —
# `'**/*.md'` and `.changeset/**` included, held identical to it by
# `scripts/__tests__/merge-queue-reporting.test.ts`. Both workflows therefore
# start, report, and skip every expensive step on precisely this PR. GitHub has
# no per-job path filter either, so the gate lives here, with the inverse
# trigger: it runs *only* when `.changeset/**` changes.
#
# It needs no install and no build — a checkout plus one `node` call, a few
# seconds — so keep it that way if you add checks to it.
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ AGENTS.md 的「只跑受影响的包」指的是**用上面的路径过滤缩
- minor/patch **独立演进**——objectstack 没动时不必跟发;objectui 自己的改动照常用 changeset 推进(从当前 major 起步,如 `11.0.0 → 11.1.0`)。
- objectstack 跨 major(→12)时,下一次 objectui 发版一并把 major 提到 `12`。
- 推论:**changeset 里不要声明 `major`** —— fixed 组任一 `major` 都会把全组推上去、脱离 objectstack 的节奏(如 17.x 期间被推到 18)。objectui 自身的破坏性变更也标 `minor`(在正文里写清 breaking 语义即可);唯一例外是跟随 objectstack 跨 major 的那一次同步升级。
- **这一条现在由 CI 机械强制** —— `scripts/check-changeset-no-major.mjs` 在任一 changeset 声明 `major` 时退出非零,由 `.github/workflows/changeset-guard.yml` 跑(它是唯一以 `.changeset/**` 为**触发**路径的 workflow:`ci.yml`/`lint.yml` 都把 `**/*.md` 和 `.changeset/**` 列进 `paths-ignore`,只加 changeset 的 PR 不会启动任何 workflow),`pnpm test` 里另有一条仓库状态断言兜底。跟随 objectstack 跨 major 的那一次发版设 `OBJECTUI_ALLOW_MAJOR=1` 放行。前情:objectui#3161/#3159/#3160/#3225 四个 changeset 在 17.x 期间标了 `major`(17 个包条目),足以把 39 个包发成 `18.0.0`。
- **这一条现在由 CI 机械强制** —— `scripts/check-changeset-no-major.mjs` 在任一 changeset 声明 `major` 时退出非零,由 `.github/workflows/changeset-guard.yml` 跑(它是唯一以 `.changeset/**` 为**触发**路径的 workflow。这里曾写「`ci.yml`/`lint.yml` 都把 `**/*.md` 和 `.changeset/**` 列进 `paths-ignore`,只加 changeset 的 PR 不会启动任何 workflow」——**已不成立,别照它做判断**:objectui#3523 step 2 把 `paths-ignore` 从这两个 workflow 的 `pull_request` 上删掉了,今天它**只**留在 `push` 触发上;PR 的路径判断改在 job 内做 —— `ci.yml` 的 `Decide whether this change needs a full run` 步骤,`lint.yml` 有同名的一份。所以 md-only / changeset-only 的 PR **照常启动**这两个 workflow 并产出 required context —— 实测 PR #3856(只改一个 `.md`)起了 16 个 check、PR #4339(只给 AGENTS.md 加一行)起了 17 个。真正被跳过的是重活:那个 job 内开关的排除表逐条**等于** `push` 的 `paths-ignore`(仍含 `**/*.md` 与 `.changeset/**`),changeset-only 的 PR 里这两个 workflow 每一步都 skip。这才是 changeset-guard.yml 今天仍必须独立、且以 `.changeset/**` **反向**触发的理由:它跑在那个 job 内开关之外,免安装免构建,是唯一判得到 changeset-only PR 的东西。见 objectui#3523 step 2 / objectui#3857),`pnpm test` 里另有一条仓库状态断言兜底。跟随 objectstack 跨 major 的那一次发版设 `OBJECTUI_ALLOW_MAJOR=1` 放行。前情:objectui#3161/#3159/#3160/#3225 四个 changeset 在 17.x 期间标了 `major`(17 个包条目),足以把 39 个包发成 `18.0.0`。
- 这是约定优先于 semver 纯粹性的取舍(为可维护/好记),因此 objectui 的 major 不代表「它自身 API 的破坏性变更次数」。`@object-ui/site` 与 `@object-ui/example-*` 在 `ignore` 列表,不随组联动。

### 多 agent 协作纪律(并行修改本仓库,务必遵守)
Expand Down
33 changes: 26 additions & 7 deletions scripts/check-changeset-presence.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,32 @@
*
* `.github/workflows/changeset-guard.yml` already exists and looks like the
* natural home. It is not: its trigger is `paths: ['.changeset/**']`, and that
* INVERSION is deliberate and documented in its own header — `ci.yml` and
* `lint.yml` both list `.changeset/**` under `paths-ignore`, so a PR that adds
* ONLY a changeset starts no other workflow at all, and that guard exists to see
* exactly that PR. A PR which forgot its changeset, by definition, does not touch
* `.changeset/**`: the one check that could notice is the one check guaranteed
* not to run. Widening its paths would break the case it was built for, so this
* gate is forward-triggered and lives alongside it.
* INVERSION is deliberate and documented in its own header.
*
* Its reason is NOT the one this comment used to give — "`ci.yml` and `lint.yml`
* both list `.changeset/**` under `paths-ignore`, so a PR that adds ONLY a
* changeset starts no other workflow at all". objectui#3523 step 2 deleted
* `paths-ignore` from those two workflows' `pull_request` trigger; it survives
* only on `push`. Such a PR therefore DOES start them and DOES produce their
* contexts — measured: PR #3856 (one markdown file) started 16 checks, PR #4339
* (one line added to AGENTS.md) started 17. objectui#3857 pinned the correction
* after an author acted on the old sentence and got the opposite result.
*
* What #3523 moved rather than deleted is the path DECISION. It is now the
* `Decide whether this change needs a full run` step in `ci.yml`, with a twin in
* `lint.yml`, and its exclusion list is that `push` filter unchanged — markdown
* and `.changeset/**` included, held identical to it by
* `scripts/__tests__/merge-queue-reporting.test.ts`. So on a changeset-only PR
* both workflows start, report, and skip every expensive step: no gate inside
* either of them ever reads the changeset. The conclusion survives its premise —
* `changeset-guard.yml` runs outside that in-job switch, with no install and no
* build, so it is still the only thing that judges such a PR at all.
*
* This gate faces the other way. A PR which forgot its changeset, by definition,
* does not touch `.changeset/**`: the one check that could notice is the one
* check guaranteed not to run. Widening that workflow's paths would break the
* case it was built for, so this gate is forward-triggered and lives alongside
* it.
*
* ## What is guarded, and why it is derived rather than listed
*
Expand Down
2 changes: 1 addition & 1 deletion skills/objectui/guides/console-development.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ console symbols retired since:
| `UserManagementPage` | **Deleted** (`cccdf84d7`, whose message records where these objects went: "contributed by framework plugins (plugin-auth, -security, -audit) into the Setup app navigation"). The URL is now a redirect to `sys_user` — see "Routing patterns". |
| `RoleManagementPage` | **Deleted** (`cccdf84d7`). ADR-0090 D3 renamed `sys_role` to `sys_position`; the URL redirects there. |
| `PermissionManagementPage` | **Deleted** (`cccdf84d7`, 26 lines). Permissions are edited through `PermissionMatrixEditor`, registered as the `permission` type's `EditPage`. |
| `config/metadataTypeRegistry.ts` | **Never existed under `apps/console/src/`.** The real registry is `packages/app-shell/src/views/metadata-admin/registry.ts`. |
| `config/metadataTypeRegistry.ts` | **Deleted** (`ff9a0d9e9`, "remove studio app and migrate to metadata-admin engine"; added in `d601ef693`). It did exist, at exactly that path under `apps/console/src/` — 195 lines when it landed, 317 when it went, and `git show ff9a0d9e9^:apps/console/src/config/metadataTypeRegistry.ts` still reads it. Worth knowing before deciding that a `ROADMAP.md` line naming it was invented rather than stale. The real registry is `packages/app-shell/src/views/metadata-admin/registry.ts`. |
| `MetadataTypeConfig`, `registerMetadataType`, `getMetadataTypeConfig`, `pageSchemaFactory`, `listComponent`, `MetadataListComponentProps` | **No such API anywhere in the repo** (zero hits). The live equivalents are `MetadataResourceConfig`, `registerMetadataResource()`, `getMetadataResource()`, and the `ListPage` / `EditPage` / `CreatePage` component overrides. |
| `buildObjectDetailPageSchema`, `schemas/objectDetailPageSchema.ts` | **Deleted** (objectui#3731 / #3736). Zero callers for months — its only consumer was `MetadataDetailPage`, retired above. The `object` type is edited by the metadata-admin engine's generic shell; see "Schema-driven detail pages". |
| `ObjectDetailTabsWidget`, `ObjectPropertiesWidget`, `ObjectFieldDesignerWidget`, `ObjectRelationshipsWidget`, `ObjectKeysWidget`, `ObjectDataExperienceWidget`, `ObjectDataPreviewWidget` | **Deleted** (objectui#3731 / #3736) with `registerObjectDetailWidgets.ts` and its `main.tsx` import. The seven widget types they registered — `object-detail-tabs`, `object-properties`, `object-field-designer`, `object-relationships`, `object-keys`, `object-data-experience`, `object-data-preview` — no longer resolve in `ComponentRegistry`. |
Expand Down
Loading