Skip to content

feat(pgpm-core): rebundleWorkspace — emit chunks as separate modules with control-only cross-chunk deps#1413

Merged
pyramation merged 2 commits into
mainfrom
feat/rebundle-control-only-deps
Jul 22, 2026
Merged

feat(pgpm-core): rebundleWorkspace — emit chunks as separate modules with control-only cross-chunk deps#1413
pyramation merged 2 commits into
mainfrom
feat/rebundle-control-only-deps

Conversation

@pyramation

@pyramation pyramation commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Summary

Atom 4, third slice: the "modular workspace" carve. Where rebundleModule (#1412) collapses a module into fewer changes within one extension, rebundleWorkspace emits each chunk as its own tiny module — the same monolith sliced into independently publishable forks (a users module, an admin module, …). This is where the control-only cross-chunk dep mode from deep-dive-4 finally has a home: cross-module ordering rides on the control-file requires, not on plan cross-references.

The emitted directory is a real, discoverable, deployable pgpm workspace, via two new reusable helpers in workspace/minimal.ts:

writeMinimalWorkspace(dir)   → pgpm.json  { "packages": ["packages/*"] }   # workspace marker getWorkspacePath walks up to
writeMinimalModule(dir, ...) → pgpm.plan, <name>.control, Makefile, package.json, deploy|revert|verify/<change>.sql

writeMinimalModule emits the minimal file set pgpm needs — matching what pgpm init scaffolds, minus the network-fetched boilerplate (README/LICENSE/jest/tests/lint configs). The .control carries the full extension shape (comment, default_version, module_pathname, requires, relocatable, superuser), and the Makefile is standard PGXS. These are generic scaffolding knives, usable by any emitter — not rebundle-specific.

rebundleWorkspace composition:

rebundleWorkspace(sourceDir, { outputDir, crossChunkDepMode }) →
  outputDir/
    pgpm.json
    packages/<chunk>/  (one per chunk, via writeMinimalModule; merged deploy/revert/verify via mergeChunkScript)

crossChunkDepMode (default control-only):

  • control-only — deps live only in control requires; the plan change has no cross-ref. Extension install/deploy ordering handles the rest — the right shape for versioned module forks.
  • change — additionally records the fine-grained plan cross-ref (<dep>:<dep>).

Reuses existing plumbing throughout: rebundlePlan (chunk model + deploy order), the extracted mergeChunkScript/mergeSqlStatements (shared with rebundleModule/packageModule), and slice's generatePlanContent. Tags are remapped onto their sealing chunk-module.

Gates.

  1. Byte-identical: workspace deploy (all package deploy scripts concatenated in deploy order) and the original module deploy both go through the same mergeSqlStatements pipeline; equality proves the carve preserved the deployed statements and their order.
  2. Actually deploys: a new integration test deploys the emitted workspace module-by-module in deploy order against Postgres and asserts the schemas/tables exist and one merged change per chunk is recorded.

Purely additive — new rebundleWorkspace + crossChunkDepMode + the workspace/minimal helpers; rebundleModule/rebundlePlan and every existing packaging/slice path are untouched.

Test plan

  • 8 rebundleWorkspace tests (real DDL, no DB): per-chunk module layout + pgpm.json/Makefile, control-only vs change dep representation, no-dep root module, tag remap, byte-identical gate in both dep modes + overwrite guard.
  • New workspace/minimal unit tests: pgpm.json discoverable via pgpmPath, module discoverable via modulePath, full control fields, PGXS Makefile, missing-script/non-empty guards.
  • New deploy-integration test: emitted control-only workspace deploys via PgpmMigrate.deploy in deploy order; auth/billing schemas + tables created; 2 merged changes recorded.
  • Full @pgpmjs/core suite green with Postgres up: 435/435 (66 suites). tsc --noEmit and pnpm build clean.

Link to Devin session: https://app.devin.ai/sessions/ad40d16f38a349b48eb7ce9375e27e6e
Requested by: @pyramation

@pyramation pyramation self-assigned this Jul 22, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@pyramation
pyramation merged commit fd6107f into main Jul 22, 2026
14 checks passed
@pyramation
pyramation deleted the feat/rebundle-control-only-deps branch July 22, 2026 06:24
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