Skip to content

Commit c1fb1d3

Browse files
bloveclaude
andauthored
feat(release): npm publishing pipeline (initial 0.0.1 release) (#58)
* docs(specs): npm publishing pipeline design Brainstormed design for shipping @pretable/core, @pretable/react, and @cacheplane/json-stream to npm via changesets/action with provenance. Key decisions: - 3 public packages versioned as a fixed group, dual ESM+CJS, initial 0.0.1 - Internal seam (PretableSurface, usePretableModel, etc.) extracted to a new private workspace package @pretable-internal/react-surface and bundled into @pretable/react via tsup noExternal — preserves bench measurement integrity (single source of truth for the rendered surface) - Bundled internal deps move to devDependencies (not dependencies) so the published manifest doesn't reference unpublishable workspace versions - publint --strict + attw --pack verification per public package, matching TanStack Query's per-package test:build pattern - changesets/action@v1 with auto-merge of Version Packages PR; aligns with Dawn's release.yml shape - Provenance attestation enabled day-one (NPM_CONFIG_PROVENANCE + id-token permission); trusted publishing configured manually after first 0.0.1 publishes, drops NPM_TOKEN reliance - latest dist-tag only; pre/next premature at 0.0.x Includes a first-release runbook covering scope ownership, branch protection, post-publish verification, trusted publishing migration, and rollback via npm deprecate. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(plans): npm publishing pipeline implementation plan Covers 17 tasks across 5 phases: Phase 1 (Tasks 1-5): extract @pretable-internal/react-surface — scaffold the new private package, move all internal/* files plus row-height.ts and use-pretable.ts, update consumers (bench, website, streaming-demo). Phase 2 (Tasks 6-9): switch public packages to dual ESM+CJS with tsup's dts:true. Move bundled internal deps to devDependencies so the published manifest doesn't reference unpublishable workspace versions. Phase 3 (Tasks 10-12): add publint + attw verification per public package, wire as a CI gate matching TanStack Query's pattern. Phase 4 (Tasks 13-15): changesets fixed group, github-compact changelog, seed initial-release.md, release.yml with provenance + auto-merge. Phase 5 (Tasks 16-17): pre-PR validation including npm pack tarball inspection; PR open + watch + merge. Plan is concrete: every step has exact file paths, complete code blocks, exact commands, and expected outputs. Self-review caught and fixed type-cross-package dependency questions (PretableTelemetry, usePretableModel) — those now move into react-surface alongside the internal/ files since the surface seam transitively requires them. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * scaffold(react-surface): create empty @pretable-internal/react-surface package * refactor(react-surface): move internal seam to its own private package Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(react): consume react-surface as workspace dependency * refactor(apps): consume react-surface from internal package * fix(react-surface): align typecheck tsconfig with sibling pattern Mirror @pretable/react's tsconfig.typecheck.json shape: paths point at dist .d.ts files instead of source files (avoids rootDir conflict), rootDir: "src", and a single include "src" (no wildcard recursion that tsc rejects with TS5010). Also runs prettier:write on docs and unrelated package.json files that the install changes touched but didn't format. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * build(core): dual ESM+CJS + dts emission via tsup * build(react): dual ESM+CJS + dts emission via tsup Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * build(json-stream): dual ESM+CJS + dts emission via tsup * build(packaging): publint + attw verification + CI gate Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(changesets): fixed group + github-compact changelog * chore(changesets): seed initial 0.0.1 release * ci: add release.yml — changesets/action with provenance + auto-merge * fix(react): align build-config test with dual-ESM+CJS exports shape Task 11's publint fix nested the types per condition (separate types for ESM and CJS resolution paths). The build-config test still asserted the flat pre-fix shape and broke. Update assertion to match. Also runs prettier:write on the changeset config that the install touched. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
1 parent a3adb18 commit c1fb1d3

48 files changed

Lines changed: 2687 additions & 92 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.changeset/config.json‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
{
22
"$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json",
33
"baseBranch": "main",
4-
"changelog": "@changesets/cli/changelog",
4+
"changelog": [
5+
"@svitejs/changesets-changelog-github-compact",
6+
{ "repo": "cacheplane/pretable" }
7+
],
58
"access": "public",
69
"commit": false,
7-
"fixed": [],
8-
"ignore": [],
10+
"fixed": [["@pretable/core", "@pretable/react", "@cacheplane/json-stream"]],
911
"linked": [],
12+
"ignore": [],
1013
"updateInternalDependencies": "patch"
1114
}

‎.changeset/initial-release.md‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
"@pretable/core": patch
3+
"@pretable/react": patch
4+
"@cacheplane/json-stream": patch
5+
---
6+
7+
Initial release. Pretable's wrapped-text scroll wedge (4× faster than AG Grid on S2/hypothesis), streaming row-stability win (H15 satisfied — pretable max visible-row drift = 1 vs AG Grid's 28 across 100–25,000 patches/sec), and end-to-end React adapter with reusable JSON streaming primitives.
8+
9+
See [the publishing pipeline design](https://github.com/cacheplane/pretable/blob/main/docs/superpowers/specs/2026-05-01-npm-publishing-pipeline-design.md) for context on the build, verification, and release flow.

‎.github/workflows/ci.yml‎

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,24 @@ jobs:
7171
- run: pnpm install --frozen-lockfile
7272
- run: pnpm build
7373

74+
packaging:
75+
name: Packaging — publint + attw
76+
runs-on: ubuntu-latest
77+
needs: [build]
78+
steps:
79+
- uses: actions/checkout@v6
80+
- uses: pnpm/action-setup@v5
81+
- uses: actions/setup-node@v6
82+
with:
83+
node-version: 22
84+
cache: pnpm
85+
- run: pnpm install --frozen-lockfile
86+
- run: pnpm -r --filter '@pretable/core' --filter '@pretable/react' --filter '@cacheplane/json-stream' build
87+
- run: pnpm -r --filter '@pretable/core' --filter '@pretable/react' --filter '@cacheplane/json-stream' lint:packaging
88+
7489
deploy-prod:
7590
name: Deploy → Vercel (production)
76-
needs: [test, typecheck, lint, format, build]
91+
needs: [test, typecheck, lint, format, build, packaging]
7792
runs-on: ubuntu-latest
7893
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
7994
# Required GitHub secrets:
@@ -133,7 +148,7 @@ jobs:
133148

134149
deploy-preview:
135150
name: Deploy → Vercel (preview)
136-
needs: [test, typecheck, lint, format, build]
151+
needs: [test, typecheck, lint, format, build, packaging]
137152
runs-on: ubuntu-latest
138153
if: github.event_name == 'pull_request'
139154
permissions:

‎.github/workflows/release.yml‎

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
branches: [main]
6+
7+
concurrency: ${{ github.workflow }}-${{ github.ref }}
8+
9+
jobs:
10+
release:
11+
name: Release — version PR or publish
12+
runs-on: ubuntu-latest
13+
timeout-minutes: 20
14+
permissions:
15+
contents: write
16+
pull-requests: write
17+
id-token: write
18+
env:
19+
NPM_CONFIG_PROVENANCE: true
20+
steps:
21+
- uses: actions/checkout@v6
22+
with:
23+
fetch-depth: 0
24+
- uses: pnpm/action-setup@v5
25+
- uses: actions/setup-node@v6
26+
with:
27+
node-version: 22
28+
cache: pnpm
29+
registry-url: https://registry.npmjs.org
30+
31+
- run: pnpm install --frozen-lockfile
32+
- run: pnpm typecheck
33+
- run: pnpm lint
34+
- run: pnpm test
35+
- run: pnpm build
36+
- run: pnpm -r --filter '@pretable/core' --filter '@pretable/react' --filter '@cacheplane/json-stream' lint:packaging
37+
38+
- name: Version PR or publish
39+
id: changesets
40+
uses: changesets/action@v1
41+
with:
42+
version: pnpm exec changeset version
43+
publish: pnpm exec changeset publish
44+
title: "chore: version packages"
45+
commit: "chore: version packages"
46+
env:
47+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
48+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
49+
50+
- name: Enable auto-merge on Version PR
51+
if: steps.changesets.outputs.pullRequestNumber != ''
52+
env:
53+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
54+
run: |
55+
gh pr merge \
56+
--auto \
57+
--squash \
58+
--repo ${{ github.repository }} \
59+
${{ steps.changesets.outputs.pullRequestNumber }}

‎apps/bench/package.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"@mui/material": "^9.0.0",
2929
"@mui/x-data-grid": "^9.0.2",
3030
"@pretable-internal/bench-runner": "workspace:*",
31+
"@pretable-internal/react-surface": "workspace:*",
3132
"@pretable-internal/scenario-data": "workspace:*",
3233
"@pretable-internal/stream-adapter": "workspace:*",
3334
"@pretable/react": "workspace:*",

‎apps/bench/src/__tests__/pretable-adapter.test.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { useEffect } from "react";
1010
import { afterEach, describe, expect, test, vi } from "vitest";
1111

1212
import { createScenarioDataset } from "@pretable-internal/scenario-data";
13-
import * as pretableReactInternal from "@pretable/react/internal";
13+
import * as pretableReactInternal from "@pretable-internal/react-surface";
1414

1515
import { createBenchInteractionPlan } from "../interaction-plan";
1616
import { PretableAdapter } from "../pretable-adapter";

‎apps/bench/src/bench-app.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
useState,
88
} from "react";
99
import type { PretableGrid } from "@pretable/react";
10-
import type { PretableTelemetry } from "@pretable/react/internal";
10+
import type { PretableTelemetry } from "@pretable-internal/react-surface";
1111

1212
import {
1313
createScenarioDataset,

‎apps/bench/src/bench-runtime.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type {
44
BenchRunRequest,
55
BenchRunSummary,
66
} from "@pretable-internal/bench-runner";
7-
import type { PretableTelemetry } from "@pretable/react/internal";
7+
import type { PretableTelemetry } from "@pretable-internal/react-surface";
88

99
import type { BenchQueryState } from "./bench-types";
1010

‎apps/bench/src/pretable-adapter.tsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { useCallback, useEffect, useMemo, useRef } from "react";
22

33
import type { PretableGrid } from "@pretable/react";
4-
import type { PretableTelemetry } from "@pretable/react/internal";
5-
import { PretableSurface } from "@pretable/react/internal";
4+
import type { PretableTelemetry } from "@pretable-internal/react-surface";
5+
import { PretableSurface } from "@pretable-internal/react-surface";
66
import { createBatcher } from "@pretable-internal/stream-adapter";
77
import type {
88
ScenarioDataset,

‎apps/streaming-demo/package.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
},
2121
"dependencies": {
2222
"@cacheplane/json-stream": "workspace:*",
23+
"@pretable-internal/react-surface": "workspace:*",
2324
"@pretable-internal/stream-adapter": "workspace:*",
2425
"@pretable/react": "workspace:*",
2526
"react": "^19.0.0",

0 commit comments

Comments
 (0)