Skip to content

Commit 3523f23

Browse files
committed
docs(skills): document pgpm package --check; rename packaging.md -> package-separation.md to de-collide
1 parent f73c89f commit 3523f23

5 files changed

Lines changed: 145 additions & 2 deletions

File tree

.agents/skills/pgpm/SKILL.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ pgpm handles extension creation during deploy. Declare extensions in your `.cont
147147
| `pgpm migrate status` | Show deployed vs pending changes |
148148
| `pgpm plan` | Generate plan from SQL `-- requires:` comments |
149149
| `pgpm package` | Bundle module for publishing |
150+
| `pgpm package --check` | Verify committed bundle artifacts are in sync with `deploy/` (CI gate) |
150151

151152
## Essential Development Workflow
152153

@@ -364,8 +365,9 @@ Consult these reference files for detailed documentation on specific topics:
364365
| [references/routing-profile.md](references/routing-profile.md) | Routing profile & module self-description | `extensions.json` provides/consumes, `pgpm.apply.json`, workspace `portability` in `pgpm.json`, routing precedence |
365366
| [references/module-naming.md](references/module-naming.md) | npm names vs control file names | Confused about which identifier to use where |
366367
| [references/plan-format.md](references/plan-format.md) | pgpm.plan file format | Fixing `Invalid line format` errors, editing plan files manually |
367-
| [references/packaging.md](references/packaging.md) | Package separation & restructuring | Splitting a database into multiple pgpm packages, cherry-picking objects into a package, change granularity, derived paths and requires |
368+
| [references/package-separation.md](references/package-separation.md) | Package separation & restructuring | Splitting a database into multiple pgpm packages, cherry-picking objects into a package, change granularity, derived paths and requires |
368369
| [references/publishing.md](references/publishing.md) | Publishing modules to npm | Bundling, versioning with lerna, publishing @pgpm/* packages |
370+
| [references/package-check.md](references/package-check.md) | `pgpm package --check` artifact drift gate | Verifying committed bundle artifacts match `deploy/`, wiring a CI check for changed modules |
369371
| [references/testing.md](references/testing.md) | PostgreSQL integration tests | Setting up pgsql-test, seed adapters, test patterns |
370372
| [references/troubleshooting.md](references/troubleshooting.md) | Common issues and solutions | Debugging connection, deployment, testing, or Docker problems |
371373
| [references/ci-cd.md](references/ci-cd.md) | GitHub Actions CI/CD workflows | Setting up CI for pgpm projects, PostgreSQL service containers, test sharding |

.agents/skills/pgpm/references/ci-cd.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,31 @@ steps:
421421
env: ${{ matrix.env }}
422422
```
423423

424+
## Bundle Drift Check
425+
426+
Gate every PR so that no module's committed `sql/<name>--<version>.bundle.tar.gz`
427+
can drift from its `deploy/` SQL. `pgpm package --check` is read-only and
428+
touches no database, and by default only verifies the modules git says
429+
changed — so it is near-instant on a normal PR. See
430+
`references/package-check.md`.
431+
432+
```yaml
433+
jobs:
434+
bundle-check:
435+
runs-on: ubuntu-latest
436+
steps:
437+
- uses: actions/checkout@v4
438+
with:
439+
fetch-depth: 0 # need the base ref for the diff
440+
# ... pnpm + node + pgpm setup ...
441+
- name: Verify pgpm bundles are in sync
442+
run: pgpm package --check --since origin/${{ github.base_ref }}
443+
```
444+
445+
Fail-fast is the default (stops at the first stale bundle); add
446+
`--no-fail-fast` to list every drifted module in one run. It needs no
447+
PostgreSQL service container.
448+
424449
## Best Practices
425450

426451
1. **Always use health checks** — Ensure PostgreSQL is ready before tests run
@@ -431,6 +456,8 @@ steps:
431456
6. **Bootstrap users before tests** — `pgpm admin-users` creates required roles
432457
7. **Use fail-fast: false** — Let all tests complete even if some fail
433458
8. **Pin pgpm version** — Ensure consistent behavior across runs
459+
9. **Gate bundle drift** — Run `pgpm package --check` on PRs so stale
460+
`sql/*.bundle.tar.gz` artifacts can't merge (fetch-depth: 0 for the diff)
434461

435462
## References
436463

.agents/skills/pgpm/references/cli.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,28 @@ pgpm plan
217217
218218
**pgpm package** — Package module for distribution
219219
220+
Emits two artifacts into `sql/`: the consolidated `sql/<name>--<version>.sql`
221+
and the content-addressed `sql/<name>--<version>.bundle.tar.gz` (consumed by
222+
`pgpm deploy --fast`/`--bundled`).
223+
220224
```bash
221225
pgpm package
222226
pgpm package --no-plan
223227
```
224228
229+
**pgpm package --check** — Verify committed artifacts are in sync (no writes, no DB)
230+
231+
Fails fast when a module's committed `sql/<name>--<version>.bundle.tar.gz` no
232+
longer matches its `deploy/`. By default only the modules that changed (via
233+
git) are checked. See `references/package-check.md`.
234+
235+
```bash
236+
pgpm package --check # changed modules (auto base)
237+
pgpm package --check --since origin/main # diff HEAD vs a branch/ref/tag
238+
pgpm package --check --all # every workspace module
239+
pgpm package --check --no-fail-fast # list all drift instead of stopping
240+
```
241+
225242
### Testing
226243
227244
**pgpm test-packages** — Run integration tests on all modules in workspace
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# Package check: verify committed artifacts are in sync with `deploy/`
2+
3+
`pgpm package --check` is a **read-only, no-DB** integrity check. It proves
4+
that each module's committed build artifact (`sql/<name>--<version>.bundle.tar.gz`)
5+
still matches the SQL in that module's `deploy/`, and fails fast when someone
6+
edited SQL without re-running `pgpm package`. Consult this when wiring a CI
7+
gate for pgpm workspaces, or when asked "how do we stop stale bundles from
8+
being merged".
9+
10+
It is the verification half of the packaging story:
11+
12+
- `pgpm package`**build** the artifacts (`sql/<name>--<version>.sql` +
13+
`sql/<name>--<version>.bundle.tar.gz`). See `references/publishing.md`.
14+
- `pgpm package --check`**verify** those committed artifacts (this file).
15+
- `pgpm deploy --fast` / `--bundled`**consume** the verified bundle. See
16+
`references/deploy-lifecycle.md`.
17+
- Artifact internals (digests, AST) — the `pgpm-migration-bundle` skill.
18+
19+
## Commands
20+
21+
```bash
22+
pgpm package --check # verify only the modules that changed
23+
pgpm package --check --since origin/main # diff HEAD vs a branch, ref, or tag
24+
pgpm package --check --all # verify every module in the workspace
25+
pgpm package --check --dependents # also re-check modules that require a changed one
26+
pgpm package --check --no-fail-fast # list every drifted module instead of stopping at the first
27+
```
28+
29+
Exits non-zero and names each drifted module, e.g.:
30+
31+
```text
32+
✖ my-second: committed bundle does not match deploy/ — run `pgpm package`
33+
1 module(s) out of sync. Run `pgpm package` in each and commit the artifacts.
34+
```
35+
36+
## How it decides what to check
37+
38+
Change detection layers cheapest-source-first, then maps files to modules
39+
through the workspace graph:
40+
41+
1. **Base ref** — explicit `--since <ref>` wins; otherwise the PR base in CI
42+
(`origin/$GITHUB_BASE_REF`); otherwise working-tree only.
43+
2. **Changed files** — union of `git diff --name-only <base>...HEAD`
44+
(three-dot, so branches/refs/tags all work) and `git status --porcelain`
45+
(uncommitted + untracked). It shells out to the `git` binary — no
46+
`simple-git`/Octokit dependency.
47+
3. **Files → modules** — each changed path is attributed to its owning module
48+
(longest-matching module directory). Only those modules are checked.
49+
`--all` skips detection; `--dependents` walks the reverse `requires` graph.
50+
51+
> A module's artifact reflects **only its own** `deploy/` (`resolveWithPlan`
52+
> never inlines required modules), so a dependency change cannot drift a
53+
> dependent's artifact. `--dependents` is therefore off by default — enable it
54+
> only for extra-paranoid checks.
55+
56+
## What it verifies per module
57+
58+
For each targeted module (`checkModuleArtifact` in
59+
`pgpm/core/src/packaging/check.ts`):
60+
61+
1. `resolveBundleArtifactPath` — artifact exists → else `missing-artifact`.
62+
2. `readBundleArtifact` — archive is readable → else `unreadable-artifact`.
63+
3. `verifyBundle` — internal digests are self-consistent → else `integrity`.
64+
4. `bundleMatchesModule` — the artifact's stored per-change sha256 + plan bytes
65+
still match the current `deploy/` → else `out-of-sync`.
66+
67+
No SQL is parsed or executed and no database is touched — it is read + sha256
68+
only, so it is cheap enough to gate every PR.
69+
70+
## CI usage
71+
72+
Drop the one-liner into a PR workflow (works in any pgpm workspace with zero
73+
config — it auto-detects the PR base):
74+
75+
```yaml
76+
- name: Verify pgpm bundles are in sync
77+
run: pgpm package --check --since origin/${{ github.base_ref }}
78+
```
79+
80+
Fail-fast is the default, so the job stops at the first stale bundle. Use
81+
`--no-fail-fast` when you want the full list in one run.
82+
83+
## Programmatic API
84+
85+
```ts
86+
import { checkPackages } from '@pgpmjs/core';
87+
88+
const result = await checkPackages({ since: 'origin/main' });
89+
if (result.drifted.length) process.exit(1);
90+
// result: { targeted, checked, drifted, base, changedModules }
91+
```

.agents/skills/pgpm/references/packaging.md renamed to .agents/skills/pgpm/references/package-separation.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
1-
# Packaging: restructuring and separating pgpm packages
1+
# Package separation & restructuring
22

33
How pgpm derives modular packages from one canonical substrate: statement
44
facts and a typed dependency graph. Consult this when asked to split a
55
database into multiple pgpm packages, cherry-pick objects into a package,
66
restructure change granularity, or understand how change paths and
77
`requires` are derived.
88

9+
> **Naming note:** this is *not* the `pgpm package` build command. `pgpm
10+
> package` compiles one module into its distributable artifacts (see
11+
> `references/publishing.md` to build+publish, `references/package-check.md`
12+
> to verify those artifacts). This file is about *separating* one deploy
13+
> surface into several packages.
14+
915
Everything here lives in `@pgpmjs/transform` (`pgpm/transform`), with paths
1016
rendered by `@pgpmjs/naming-spec` (`pgpm/naming-spec`). The underlying facts,
1117
graph, and identity primitives come from `@pgsql/transform` (npm, from the

0 commit comments

Comments
 (0)