Skip to content

refactor: uniform workspace scripts; remove package-identity forks in root/CI - #160

Merged
krisnye merged 1 commit into
mainfrom
krisnye/monorepo-script-conventions
Jul 29, 2026
Merged

refactor: uniform workspace scripts; remove package-identity forks in root/CI#160
krisnye merged 1 commit into
mainfrom
krisnye/monorepo-script-conventions

Conversation

@krisnye

@krisnye krisnye commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Description

Root and CI forked on package identity — the anti-pattern this PR removes:

  • CI ran unit tests for a hardcoded subset of packages and merely built the
    private sample apps (a broken sample test could merge green — see ci: pin Node 24, test every package, fix data-lit-todo id-shape assumption #159), and
    applied test:node only to data-persistence.
  • Root typecheck enumerated the sample packages by name.
  • Root publish enumerated the six publishable packages by name — a list that
    had already drifted from the private field (it omitted data-persistence
    and data-sync, both private: false).

Every new package forced edits to these central lists, and the lists silently
diverged from reality.

Approach: uniform recursive invocation

Each package owns how it builds/tests/typechecks via standard script names.
Root and CI just call pnpm -r run <script>, which pnpm runs in dependency
(topological) order and skips packages that don't define the script. Adding
a package needs zero edits to any central list.

CI (.github/workflows/ci.yml)

Collapsed to a single job whose every step is one pnpm -r run … with no
package names: check:workspacetypechecklintbuildtest.
Strictly more coverage than before:

  • Every package is now type-checked (samples included; previously only built).
  • Each package runs its complete suite — data-persistence's browser tests
    now run in CI (37 test files vs the 20 node-only ones CI ran before).

Publishing — governed only by private

pnpm -r publish publishes every private: false package and skips the rest.
Removed all publish-public scripts (6 real + 7 stale "true" no-ops on private
samples) and the hardcoded root list.

Important

data-persistence and data-sync are private: false, so under the
property-driven rule they become publishable (the old hardcoded list wrongly
excluded them). If either should stay unreleased for now, set private: true
that one field is the single source of truth. No packages are published by this
PR; it only changes the publish script.

Convention guard + docs

  • scripts/check-workspace-conventions.mjs (CI: pnpm run check:workspace)
    enforces: every package sets private explicitly (absent must never mean
    "publishable"), and no publish-public scripts exist.
  • The "Workspace script conventions" section of CLAUDE.md documents the
    standard script names and the private-only publish rule.

Other

  • core test now skips perf tests by default (folds the old test:ci); perf
    moved to test:perf.

Verification

Full pipeline green on Node 24 (mirrors the new CI exactly):
check:workspace ✓ · pnpm -r run typecheck ✓ (all 17 packages) · lint ✓ ·
build ✓ · test ✓ (core 245 files, data-persistence 37 incl. browser, every
sample app passing).

Related PRs

🤖 Generated with Claude Code

…t/CI

Root and CI forked on package identity: CI ran unit tests for a hardcoded
subset and applied test:node only to data-persistence, root typecheck listed
sample packages by name, and publish enumerated the six publishable packages
by name — a list that had already drifted from the `private` field (it omitted
data-persistence and data-sync, both private:false). Every new package forced
edits to these central lists.

Replace all of it with uniform recursive invocation. Each package owns HOW it
builds/tests/typechecks via standard script names; root and CI just call
`pnpm -r run <script>`, which pnpm runs in dependency order and skips for
packages that don't define the script.

- CI: one job running check:workspace, typecheck, lint, build, test — each a
  single `pnpm -r run` with zero package names. Now typechecks every package
  (samples included) and runs each package's complete suite (data-persistence's
  browser tests now run in CI, previously never did).
- Publishing is governed solely by `private`: `pnpm -r publish` ships every
  private:false package and skips the rest. Removed all `publish-public`
  scripts (6 real + 7 stale no-ops on private samples) and the hardcoded root
  publish list. NOTE: data-persistence and data-sync are private:false, so they
  become publishable — set private:true if either should stay unreleased.
- core `test` now skips perf tests by default (folds the old test:ci); perf
  moved to test:perf.
- Root typecheck collapses the foundation/libraries/samples name lists into
  `pnpm -r run typecheck`.
- scripts/check-workspace-conventions.mjs (CI: pnpm run check:workspace) enforces
  the rules: every package sets `private` explicitly, and no publish-public
  scripts. Convention documented in CLAUDE.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@krisnye
krisnye force-pushed the krisnye/monorepo-script-conventions branch 3 times, most recently from 12d640e to eea2565 Compare July 29, 2026 03:51
@krisnye
krisnye merged commit 9242f25 into main Jul 29, 2026
4 checks passed
@krisnye
krisnye deleted the krisnye/monorepo-script-conventions branch July 29, 2026 03:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant