Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 24 additions & 40 deletions .github/workflows/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ on:
push:
branches: main

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
FLATBREAD_CI: true

jobs:
build:
runs-on: ${{ matrix.os }}
Expand All @@ -21,7 +31,7 @@ jobs:
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: ^9.15.0
version: 10.33.0
run_install: false

- name: Use Node.js ${{ matrix.node-version }}
Expand All @@ -31,12 +41,10 @@ jobs:
registry-url: https://registry.npmjs.org/
cache: 'pnpm'

- name: Set an escape hatch exclusive to this monorepo
id: escape_hatch
run: |
echo "FLATBREAD_CI=true" >> $GITHUB_ENV
- run: pnpm install --frozen-lockfile

- run: pnpm i
- name: Typecheck
run: pnpm typecheck

- name: Build
run: pnpm build
Expand All @@ -56,7 +64,7 @@ jobs:
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: ^9.15.0
version: 10.33.0
run_install: false

- name: Use Node.js ${{ matrix.node-version }}
Expand All @@ -66,12 +74,7 @@ jobs:
registry-url: https://registry.npmjs.org/
cache: 'pnpm'

- name: Set an escape hatch exclusive to this monorepo
id: escape_hatch
run: |
echo "FLATBREAD_CI=true" >> $GITHUB_ENV

- run: pnpm i
- run: pnpm install --frozen-lockfile

- name: Lint
run: pnpm lint
Expand All @@ -91,7 +94,7 @@ jobs:
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: ^9.15.0
version: 10.33.0
run_install: false

- name: Use Node.js ${{ matrix.node-version }}
Expand All @@ -101,15 +104,7 @@ jobs:
registry-url: https://registry.npmjs.org/
cache: 'pnpm'

- name: Set an escape hatch exclusive to this monorepo
id: escape_hatch
run: |
echo "FLATBREAD_CI=true" >> $GITHUB_ENV

- run: pnpm i

- name: Build
run: pnpm build
- run: pnpm install --frozen-lockfile

- name: Test
run: pnpm test
Expand All @@ -129,7 +124,7 @@ jobs:
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: ^9.15.0
version: 10.33.0
run_install: false

- name: Use Node.js ${{ matrix.node-version }}
Expand All @@ -139,15 +134,10 @@ jobs:
registry-url: https://registry.npmjs.org/
cache: 'pnpm'

- name: Set an escape hatch exclusive to this monorepo
id: escape_hatch
run: |
echo "FLATBREAD_CI=true" >> $GITHUB_ENV

- run: pnpm i
- run: pnpm install --frozen-lockfile

- name: Build SvelteKit Integration
run: pnpm play:build
run: pnpm build && pnpm --dir examples/sveltekit build

integration-nextjs:
runs-on: ${{ matrix.os }}
Expand All @@ -164,7 +154,7 @@ jobs:
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: ^9.15.0
version: 10.33.0
run_install: false

- name: Use Node.js ${{ matrix.node-version }}
Expand All @@ -174,13 +164,7 @@ jobs:
registry-url: https://registry.npmjs.org/
cache: 'pnpm'

- name: Set an escape hatch exclusive to this monorepo
id: escape_hatch
run: |
echo "FLATBREAD_CI=true" >> $GITHUB_ENV

- run: pnpm i
- run: pnpm install --frozen-lockfile

- name: Build Next.js integration
# TODO: extract the Flatbread build to a separate job that this job can depend on
run: pnpm build && cd examples/nextjs && pnpm build
run: pnpm build && pnpm --dir examples/nextjs build
16 changes: 12 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ Thanks for your interest in contributing! This guide covers local development an

## Prerequisites

- Node 16+
- pnpm
- Node 20.19+
- pnpm 10.33.x via Corepack (`corepack enable && corepack prepare pnpm@10.33.0 --activate`)
- Clean git working tree (commit/stash your work first)

## Local development
Expand All @@ -14,6 +14,7 @@ Thanks for your interest in contributing! This guide covers local development an
- Build all packages: `pnpm build`
- Run dev across packages: `pnpm dev`
- Work in examples (Next.js preferred): `pnpm play`
- Check local CI parity before opening a PR: `pnpm verify`

## Working on a package

Expand Down Expand Up @@ -42,12 +43,19 @@ pnpm build

- Keep PRs small and focused; link related issues.
- Ensure CI passes all checks.
- Run `pnpm verify` locally when your change touches source, tests, package metadata, or CI.
- Add test coverage for both positive and negative cases:
- Positive: expected success paths and typical inputs.
- Negative: invalid inputs, edge cases, and error handling/failure modes.
- Place tests in the relevant package and use its existing runner/config (Vitest in most packages; some legacy tests use Ava).
- Place tests in the relevant package and use its existing runner/config.
- Root `pnpm test` builds the workspace, runs the AVA suite configured by `ava.config.js`, then runs the package-local Vitest suites.
- Vitest is currently used by `@flatbread/codegen` and `@flatbread/utils`.
- Most other packages are covered by the root AVA suite or do not yet expose a package-local `test` script.
- `pnpm lint` is the enforced Prettier formatting gate. `pnpm lint:eslint` is an optional/manual root ESLint check until the linting stack is modernized.
- Helpful commands:
- All packages: `pnpm -r test`
- Local CI parity: `pnpm verify`
- Root test suite: `pnpm test`
- Package-local test scripts where present: `pnpm -r --if-present test`
- Single package: `pnpm -F <package-name> test`
- Watch (where supported): `pnpm -F <package-name> test:watch`

Expand Down
181 changes: 181 additions & 0 deletions docs/tooling-modernization.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
# Tooling modernization notes

This note records the modernization decisions from the proof DAG run used to
scope this stack. The changes are intentionally conservative: make current
checks reachable and deterministic first, then defer broad lint/test runner
replacement until the repository has fewer overlapping toolchain generations.

## Stack entries

### 1. Package test toolchain and root scripts

Objective:

- Modernize the packages that already use Vitest:
`@flatbread/codegen` and `@flatbread/utils`.
- Add root scripts that expose typechecking, split test runners, and a full
local verification path.
- Pin the package manager and Node floor used by the modern Vite/Vitest stack.

Rationale:

- The Vitest suites existed but were not reachable from `pnpm test`.
- The updated Vitest packages need aligned local `vite`, `typescript`,
`@types/node`, and `tsup` versions to avoid peer drift.
- Package-local `tsconfig.json` files keep TS 6 options scoped to the updated
packages instead of forcing every package off the older shared TS 4.7 path at
once.

Migration notes:

- `pnpm test` now builds the workspace, runs AVA, then runs the Vitest suites.
- Root `typecheck` is a pilot scoped to `@flatbread/proof`, the only package
with a dedicated typecheck script today.
- `prepublish:ci` now uses a frozen install plus declaration generation instead
of recursively updating dependency ranges.

Rollback:

- Revert `package.json`, `tsconfig.json`,
`packages/codegen/package.json`, `packages/codegen/tsconfig.json`,
`packages/utils/package.json`, `packages/utils/tsconfig.json`, and
`pnpm-lock.yaml`.

### 2. CI verification hardening

Objective:

- Make installs deterministic.
- Enforce lint, typecheck, build, and tests in CI.
- Fix integration coverage so the SvelteKit job exercises the SvelteKit example.

Rationale:

- The prior workflow used mutable `pnpm i` installs.
- `lint` only ran Prettier, `typecheck` was absent, and package Vitest suites
were not part of the root test script.
- `integration-sveltekit` previously ran `pnpm play:build`, which builds the
Next.js example.

Migration notes:

- The workflow pins pnpm to `10.33.0` and uses `pnpm install --frozen-lockfile`.
- `pnpm-workspace.yaml` explicitly approves native build scripts that are
required by the current toolchain and examples, including `esbuild`, `sharp`,
and `sqlite3`.
- `FLATBREAD_CI` is set once at workflow scope.
- `permissions: contents: read` and cancellation concurrency reduce the default
token scope and cancel superseded PR runs.
- SvelteKit integration now runs root build and `examples/sveltekit` build.
`svelte-check` remains deferred because the existing route data types report
a pre-existing `data.allPostCategories` error after `svelte-kit sync`.

Rollback:

- Revert `.github/workflows/pipeline.yml`. The local scripts from the previous
entry remain independently useful.

### 3. Config hygiene from adversarial audit

Objective:

- Remove pnpm configuration that package manifests cannot enforce.
- Make workspace path aliases and example package metadata explicit.

Rationale:

- `pnpm.peerDependencyRules` only applies from the workspace root, so package
local copies in `@flatbread/codegen` and `flatbread` created warning noise
without changing install behavior.
- The Next.js example invoked the `flatbread` CLI without declaring the
workspace dependency it relies on.
- Root path aliases should cover workspace packages consistently for editor and
package-local TS config consumers.

Rollback:

- Revert the config hygiene commit to restore the previous package metadata,
path aliases, and lockfile entries.

### 4. Decision record and deferred follow-ups

Objective:

- Document major modernization choices, especially the decision not to adopt
Biome or Oxc in this pass.
- Leave reviewers with clear follow-up seams.

Rollback:

- Revert this document only.

## Biome and Oxc evaluation

Biome and Oxc were evaluated as possible replacements or partial replacements
for ESLint and Prettier. They are not adopted in this stack.

Why not adopt Biome now:

- Prettier currently checks the whole repository, including Markdown and YAML.
A partial Biome migration would require careful single-writer boundaries to
avoid formatting the same files with two tools.
- The examples already use framework-specific ESLint stacks:
Next.js uses `eslint-config-next`, and SvelteKit uses `eslint-plugin-svelte`.
Biome would not replace those framework rules cleanly.
- A packages-only Biome pilot may still be worthwhile, but it should be a
dedicated PR with explicit excludes in `.prettierignore`.

Why not adopt Oxc now:

- Oxlint is best as a fast lint accelerator, not a complete replacement for
framework ESLint rules and TypeScript-aware project policy.
- Root ESLint is not currently enforced by `pnpm lint`, and its dependency graph
is already skewed. Adding Oxlint before deciding whether to repair or demote
root ESLint would increase the number of lint surfaces.

Recommended future pilot:

1. Repair root linting first: either migrate root packages to ESLint 9 flat
config with explicit `typescript-eslint` dependencies, or remove the dormant
root ESLint script and rely on compiler plus formatter checks.
2. If the repo still wants a Rust-based formatter/linter, pilot Biome only for
`packages/**/src/**/*.{ts,tsx,js,mjs,cjs}` and keep Prettier responsible for
Markdown, YAML, snapshots, and framework examples.
3. Consider Oxlint only after the ESLint boundary is explicit, as an additional
fast lint signal rather than the primary rule authority.

## Runtime impact

Measured locally in this cloud workspace:

- Proof audit DAG: 5/5 tasks completed in about 1 minute 9 seconds.
- Adversarial follow-up DAG: 5/5 tasks completed in about 55 seconds.
- Updated `@flatbread/codegen` + `@flatbread/utils` builds completed in about
4 seconds after the package-local TS configs were added.
- `pnpm typecheck` for the current proof pilot completed in about 2.5 seconds.

CI impact must be measured from GitHub Actions after merge or on the draft PR:

- Frozen installs should reduce nondeterministic lockfile drift, not necessarily
raw runtime.
- Cancellation concurrency should reduce wasted runner minutes on superseded PR
pushes.
- The old SvelteKit integration job duplicated Next.js coverage. The new job
spends those runner cells on actual SvelteKit build coverage instead of
duplicate Next.js validation.

## Deferred recommendations

- Migrate or remove dormant root ESLint in a dedicated linting PR.
- Unify AVA and Vitest after deciding whether package-local tests should all
move to Vitest, or keep both with the contributor guide's current split.
- Add package-level `typecheck` scripts and move toward project references or a
monorepo `tsc -b` flow.
- Add coverage collection and thresholds around critical paths after test runner
boundaries are settled.
- Audit deprecated runtime dependencies such as Apollo Server v3 and
Express-GraphQL separately from this tooling stack.
- Confirm whether `@nrwl/workspace` is still used; remove it in its own PR if
it is dead weight.
- Resolve the existing SvelteKit route data typing issue, then add
`svelte-check` to CI.
1 change: 1 addition & 0 deletions examples/nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"@types/react-dom": "^19.1.7",
"eslint": "^9.33.0",
"eslint-config-next": "15.4.4",
"flatbread": "workspace:*",
"tailwindcss": "^4.1.11",
"typescript": "^5.9.2"
}
Expand Down
2 changes: 1 addition & 1 deletion examples/sveltekit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"repository": {
"type": "git",
"url": "git+https://github.com/FlatbreadLabs/flatbread.git",
"directory": "playground"
"directory": "examples/sveltekit"
},
"author": "Tony Ketcham <ketcham.dev@gmail.com>",
"license": "MIT",
Expand Down
Loading
Loading