refactor: uniform workspace scripts; remove package-identity forks in root/CI - #160
Merged
Merged
Conversation
…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
force-pushed
the
krisnye/monorepo-script-conventions
branch
3 times, most recently
from
July 29, 2026 03:51
12d640e to
eea2565
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Root and CI forked on package identity — the anti-pattern this PR removes:
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:nodeonly todata-persistence.typecheckenumerated the sample packages by name.publishenumerated the six publishable packages by name — a list thathad already drifted from the
privatefield (it omitteddata-persistenceand
data-sync, bothprivate: 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 nopackage names:
check:workspace→typecheck→lint→build→test.Strictly more coverage than before:
data-persistence's browser testsnow run in CI (37 test files vs the 20 node-only ones CI ran before).
Publishing — governed only by
privatepnpm -r publishpublishes everyprivate: falsepackage and skips the rest.Removed all
publish-publicscripts (6 real + 7 stale"true"no-ops on privatesamples) and the hardcoded root list.
Important
data-persistenceanddata-syncareprivate: false, so under theproperty-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
publishscript.Convention guard + docs
scripts/check-workspace-conventions.mjs(CI:pnpm run check:workspace)enforces: every package sets
privateexplicitly (absent must never mean"publishable"), and no
publish-publicscripts exist.CLAUDE.mddocuments thestandard script names and the
private-only publish rule.Other
testnow skips perf tests by default (folds the oldtest:ci); perfmoved 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, everysample app passing).
Related PRs
pipeline no longer forks on identity at all.
🤖 Generated with Claude Code