diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4684bb7d..2a5ce5b2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,6 +6,9 @@ on: pull_request: branches: [main] +env: + TURBO_TELEMETRY_DISABLED: 1 + jobs: check: name: Check & Test & Build @@ -13,42 +16,34 @@ jobs: steps: - uses: actions/checkout@v6 - # setup-vp installs the Vite+ CLI, Node, the package manager, and caches - # the dep store. Run install explicitly before restoring the Vite Task - # cache, matching https://viteplus.dev/guide/github-actions-cache. - - uses: voidzero-dev/setup-vp@v1 + # pnpm (version pinned by package.json's `packageManager`) + Node, with the + # pnpm content store cached by setup-node. + - uses: pnpm/action-setup@v4 + - uses: actions/setup-node@v4 with: node-version-file: .node-version - cache: true - run-install: false + cache: pnpm - - run: vp install + - run: pnpm install --frozen-lockfile - - name: Restore Vite Task cache - id: vite-task-cache - uses: actions/cache/restore@v6 + # Turborepo local cache: build/typecheck/test outputs are content-hashed and + # restored across runs (keyed by commit, falling back to the latest prior run). + - name: Restore Turbo cache + uses: actions/cache@v6 with: - path: node_modules/.vite/task-cache - key: vite-task-${{ runner.os }}-${{ runner.arch }}-${{ github.run_id }}-${{ github.run_attempt }} + path: .turbo + key: turbo-${{ runner.os }}-${{ github.sha }} restore-keys: | - vite-task-${{ runner.os }}-${{ runner.arch }}- - - # apps/propel-docs type-checks its demos against @makeplane/propel's built - # dist (its published `exports`), and dist is gitignored — so pack propel - # before the workspace check, or those imports can't resolve (TS2307). - - run: vp run @makeplane/propel#build - - - run: vp run -w check - # Storybook stories run as browser tests (Vitest + Playwright), so CI needs - # the Chromium binary + its system deps. `pnpm` isn't on PATH under - # setup-vp, so run the package binary via `vp exec` (see viteplus.dev/guide/ci). - - run: vp exec --filter @makeplane/propel playwright install --with-deps chromium - - run: vp run -r test - - run: vp run -r build - - - name: Save Vite Task cache - if: success() - uses: actions/cache/save@v6 - with: - path: node_modules/.vite/task-cache - key: ${{ steps.vite-task-cache.outputs.cache-primary-key }} + turbo-${{ runner.os }}- + + # Format + lint + type-check (turbo `check` = check:format + check:lint + + # check:types). check:lint/check:types build each package's workspace + # dependencies first via `^build` (e.g. docs type-checks against + # @makeplane/propel's built dist), so no separate pre-build step is needed. + - run: pnpm check + + # Storybook stories run as browser tests (Vitest + Playwright). The propel + # package's `pretest` hook installs the Chromium binary + system deps + # (`playwright install --with-deps chromium` when CI=true) before the run. + - run: pnpm test + - run: pnpm build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index af953c5d..348d46ed 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,6 +4,9 @@ on: push: branches: [main] +env: + TURBO_TELEMETRY_DISABLED: 1 + jobs: release: name: Release @@ -15,23 +18,24 @@ jobs: steps: - uses: actions/checkout@v6 - - uses: voidzero-dev/setup-vp@v1 + - uses: pnpm/action-setup@v4 + - uses: actions/setup-node@v4 with: node-version-file: .node-version - cache: true + cache: pnpm + + - run: pnpm install --frozen-lockfile - name: Build packages - run: vp run -r build + run: pnpm exec turbo run build # Opens/updates a "Version Packages" PR when changesets are present, and # publishes to npm when that PR is merged (i.e. when no changesets remain). - name: Create release PR or publish uses: changesets/action@v1 with: - # changesets/action@v1 splits these strings on whitespace before exec, - # so keep each command to a single Vite+ binary invocation. - version: vp exec -w changeset version - publish: vp exec -w changeset publish + version: pnpm exec changeset version + publish: pnpm exec changeset publish env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_CONFIG_PROVENANCE: "true" diff --git a/.github/workflows/storybook.yml b/.github/workflows/storybook.yml index a8a9b901..7c00730e 100644 --- a/.github/workflows/storybook.yml +++ b/.github/workflows/storybook.yml @@ -8,6 +8,9 @@ on: pull_request: workflow_dispatch: # manual redeploy (e.g. to restore production) +env: + TURBO_TELEMETRY_DISABLED: 1 + jobs: deploy: name: Build & deploy Storybook @@ -21,31 +24,23 @@ jobs: steps: - uses: actions/checkout@v6 - - uses: voidzero-dev/setup-vp@v1 + - uses: pnpm/action-setup@v4 + - uses: actions/setup-node@v4 with: node-version-file: .node-version - cache: true - run-install: false + cache: pnpm - - run: vp install + - run: pnpm install --frozen-lockfile - - name: Restore Vite Task cache - id: vite-task-cache - uses: actions/cache/restore@v6 + - name: Restore Turbo cache + uses: actions/cache@v6 with: - path: node_modules/.vite/task-cache - key: vite-task-${{ runner.os }}-${{ runner.arch }}-${{ github.run_id }}-${{ github.run_attempt }} + path: .turbo + key: turbo-storybook-${{ runner.os }}-${{ github.sha }} restore-keys: | - vite-task-${{ runner.os }}-${{ runner.arch }}- - - - run: vp run -r build-storybook + turbo-storybook-${{ runner.os }}- - - name: Save Vite Task cache - if: success() - uses: actions/cache/save@v6 - with: - path: node_modules/.vite/task-cache - key: ${{ steps.vite-task-cache.outputs.cache-primary-key }} + - run: pnpm exec turbo run build-storybook # PR → a versioned upload aliased to the PR number, which yields a stable # preview URL (pr--propel-storybook..workers.dev) without @@ -58,11 +53,11 @@ jobs: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} workingDirectory: packages/propel - # Run our lockfile wrangler (a @makeplane/propel devDep), not the action's - # own. `packageManager: npm` makes the action invoke `npx wrangler …`, - # and under setup-vp `npx` is a symlink to `vp` — so it runs the - # installed wrangler. Omitting `wranglerVersion` skips the action's - # install (and the npx fetch that flaked on @cloudflare/workerd-*). + # Run our lockfile wrangler (a @makeplane/propel devDep) via `npx wrangler`, + # not the action's own. `packageManager: npm` makes the action invoke + # `npx wrangler …`, which resolves the wrangler in packages/propel/node_modules/.bin. + # Omitting `wranglerVersion` skips the action's install (and the fetch that + # flaked on @cloudflare/workerd-*). packageManager: npm command: >- ${{ github.event_name == 'pull_request' diff --git a/.gitignore b/.gitignore index 64d46c8d..d5f41daa 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,9 @@ storybook-static # Astro build cache .astro +# Turborepo cache +.turbo + # Test coverage coverage diff --git a/.oxfmtrc.json b/.oxfmtrc.json new file mode 100644 index 00000000..5e33a88e --- /dev/null +++ b/.oxfmtrc.json @@ -0,0 +1,10 @@ +{ + "ignorePatterns": ["**/dist/**", "**/.claude/**", "**/.agents/**"], + "sortTailwindcss": { + "functions": ["cva", "cx"], + "stylesheet": "packages/propel/tailwind.css" + }, + "sortImports": true, + "sortPackageJson": true, + "jsdoc": true +} diff --git a/.oxlintrc.json b/.oxlintrc.json new file mode 100644 index 00000000..61f72aef --- /dev/null +++ b/.oxlintrc.json @@ -0,0 +1,17 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "jsPlugins": ["./tools/oxlint-plugin-propel/src/index.ts"], + "ignorePatterns": [ + "**/dist/**", + "**/.claude/**", + "**/.agents/**", + "**/.storybook/**", + "**/storybook-static/**", + "**/vitest.config.ts", + "**/tsdown.config.ts" + ], + "rules": { + "propel/prefer-tailwind-v4-shorthand": "error", + "typescript/consistent-type-definitions": ["error", "type"] + } +} diff --git a/.vite-hooks/pre-commit b/.vite-hooks/pre-commit deleted file mode 100755 index 85fb65b4..00000000 --- a/.vite-hooks/pre-commit +++ /dev/null @@ -1 +0,0 @@ -vp staged diff --git a/AGENTS.md b/AGENTS.md index 362b82a4..d4c48a03 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,16 +1,18 @@ - +# Toolchain: pnpm + Turborepo -# Using Vite+, the Unified Toolchain for the Web - -This project is using Vite+, a unified toolchain built on top of Vite, Rolldown, Vitest, tsdown, Oxlint, Oxfmt, and Vite Task. Vite+ wraps runtime management, package management, and frontend tooling in a single global CLI called `vp`. Vite+ is distinct from Vite, and it invokes Vite through `vp dev` and `vp build`. Run `vp help` to print a list of commands and `vp --help` for information about a specific command. - -Docs are local at `node_modules/vite-plus/docs` or online at https://viteplus.dev/guide/. +This monorepo uses [pnpm](https://pnpm.io) (workspaces + catalog) for package +management and [Turborepo](https://turborepo.com) to orchestrate tasks. The +underlying tools run standalone: [tsdown](https://tsdown.dev) for library builds, +[Vitest](https://vitest.dev) for tests, and [Oxlint](https://oxc.rs) + [Oxfmt](https://oxc.rs) +for linting and formatting. Config lives in `turbo.json`, `.oxlintrc.json`, +`.oxfmtrc.json`, and per-package `tsdown.config.ts` / `vitest.config.ts`. ## Review Checklist -- [ ] Run `vp install` after pulling remote changes and before getting started. -- [ ] Run `vp check` and `vp test` to format, lint, type check and test changes. -- [ ] Check if there are `vite.config.ts` tasks or `package.json` scripts necessary for validation, run via `vp run