Skip to main content

Contributing to bestax-bulma

Thanks for your interest in contributing! This page mirrors the highlights of the repository's CONTRIBUTING.md — which stays the canonical source — and gives you a copy-pasteable local development command reference for the pnpm toolchain.

Requirements​

Before opening a PR, make sure:

  • All tests pass (pnpm test & pnpm test:coverage) — coverage must stay ≥ 95%.
  • Lint, format, and type checks pass (pnpm lint, pnpm format:check, pnpm typecheck).
  • Storybook covers UI changes — any UI change needs a corresponding story.
  • Docs are updated for new or changed behavior.
  • CI passes (pnpm all) and the PR targets main (direct pushes to main aren't allowed).

Prerequisites​

Use Node 22 (the LTS this repo targets — see .nvmrc). The repo uses pnpm, pinned via the packageManager field. The simplest way to get the exact version on any Node is to enable Corepack (bundled with Node):

corepack enable

pnpm powers the project's supply-chain hardening — lifecycle/postinstall scripts are blocked by default and a 3-day release-age cooldown prevents installing just-published versions. See pnpm-workspace.yaml for the exact settings.

Local Development Commands​

Everything here is safe to run locally; nothing publishes (see the note at the end).

1. One-time setup​

corepack enable # makes `pnpm` use the pinned [email protected]
pnpm install --frozen-lockfile # exact CI-parity install (fails if the lockfile drifts)
# or just `pnpm install` for a normal dev install

2. Run the whole CI suite locally (the big one)​

pnpm run all
# = turbo: build, typecheck, test, test:coverage, bundle:stats, lint,
# format:check && build-storybook (bulma-ui)

3. Individual checks​

pnpm run build # turbo build all packages
pnpm run typecheck
pnpm run test # jest in every package + the docs and scripts/ node:test suites
pnpm run test:coverage # coverage (bulma-ui 99%; every other jest package 95%, 78% branches)
pnpm run lint
pnpm run format:check # prettier check (use `pnpm run format` to auto-fix)
pnpm run bundle:stats # writes bulma-ui/dist/stats.html

4. Docusaurus (docs site → http://localhost:3000)​

pnpm docs # dev server (hot reload)

# production build + preview:
pnpm exec turbo run build --filter=@allxsmith/bestax-docs # builds docs + bulma-ui dep
pnpm --filter @allxsmith/bestax-docs run serve # serves the built site

The build also regenerates /llms.txt and /llms-full.txt under docs/build/.

5. Storybook (→ http://localhost:6006)​

pnpm storybook # dev server
pnpm --filter @allxsmith/bestax-bulma run build-storybook # static build -> bulma-ui/storybook-static

6. Turbo directly (filters + caching)​

pnpm exec turbo run build --filter=@allxsmith/bestax-bulma # one package (+ its deps)
pnpm exec turbo run test --filter=create-bestax
pnpm exec turbo run build # everything (cached on re-run)
pnpm exec turbo run build --force # ignore turbo cache

7. create-bestax — scaffold a throwaway app​

Scaffold outside the repo so it's a standalone app (inside the repo you'd need --ignore-workspace):

pnpm --filter create-bestax run build
node "$PWD/create-bestax/dist/index.js" /tmp/my-bestax-app -t vite-ts -b complete -i fontawesome -y
cd /tmp/my-bestax-app && pnpm install && pnpm dev # verify the generated app runs

8. Supply-chain / pnpm hardening checks​

pnpm audit --audit-level=high # the CI gate (should exit 0)
pnpm approve-builds # shows which install scripts are blocked/allowed
pnpm why serialize-javascript # trace a transitive dep (confirms the >=7.0.3 override)
pnpm why prettier # confirm a single pinned version
pnpm outdated -r # what's behind (the cooldown may hold some back)
pnpm list --depth 0 # top-level deps per workspace
pnpm dedupe --check # report duplicate versions without changing anything

Want to see the cooldown block something? Try adding a just-published package — pnpm refuses it (then discard the change):

pnpm add -w some-brand-new-package # expect ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION
git checkout package.json pnpm-lock.yaml # undo

9. Preview the release without publishing (semantic-release dry-run)​

Runs the real commit analysis and next-version calc, but publishes nothing:

export GITHUB_TOKEN=your_token # the github plugin needs a repo-read token even in dry-run
for pkg in bulma-ui create-bestax bestax-migrate bestax-mcp eslint-plugin; do
( cd "$pkg" && pnpm exec semantic-release --dry-run --no-ci )
done

It prints "The next release version is X.Y.Z" per package (or "no release") from your local commits — no npm publish, no tag, no GitHub release.

Safe to run; never publishes

Everything above is safe. The only things that actually publish are pnpm exec semantic-release without --dry-run (CI-only, on merge to main) and a manual pnpm publish --provenance --embed-readme --access public — neither of which is in this list. Those flags are not optional, and a bare pnpm publish ships unattested and loses the npm page's README.

You are unlikely to need a manual publish at all. Every package's prepack and prepublishOnly hooks refuse publishers they recognise as not being pnpm, so a stray npm publish or npm pack exits with an explanation rather than producing an unresolved workspace: specifier (#412) — though --ignore-scripts skips both, and neither travels with a tarball packed elsewhere. Why each flag matters and what the guard does and does not cover: VERSIONING.md and scripts/require-pnpm-publish.mjs.

Workflow & conventions​

  1. Branch off main, make your change in the right workspace (bulma-ui, docs, create-bestax, bestax-migrate, bestax-mcp, or eslint-plugin).
  2. Add/update tests (bulma-ui holds 99% coverage; every other jest package 95%, 78% branches) and Storybook stories for UI changes.
  3. Run pnpm all, then open a PR targeting main.

Commits follow Conventional Commits — the type and scope drive semantic-release. Releasing types (feat, fix, perf, refactor, style, revert) must carry one of the scopes in RELEASE_SCOPES (bulma-ui, docs, create-bestax, bestax-migrate, bestax-mcp, eslint-plugin); docs, chore, ci, build, and test don't publish — note docs is both a valid scope and a non-releasing type, so docs(bulma-ui): and docs: alike publish nothing. A scoped revert(scope): commit releases nothing — the only revert rule is commit-analyzer's default, and its revertPattern matches a Revert "…" or bare revert: … header (never the parenthesized revert(scope): form) followed by a This reverts commit <sha> body; ship a rollback with a follow-up fix(scope): commit. An unscoped revert: … is stopped by commitlint's scope rule, but git's own Revert "…" form is the real hazard: commitlint's default ignore rules let it through unexamined, and its generated body trips the default revert rule with no scope to confine it, so it would patch-release every package. Publishing uses npm OIDC trusted publishing with provenance (no long-lived token). See CONTRIBUTING.md for the full details.

AI-assisted development & review​

Every PR gets an automatic CodeRabbit review (address or refute its comments — it re-reviews on each push), and maintainers can invoke the @claude assistant (maintainer-only, since it spends the maintainer's Claude usage). Issues labeled claude-fix are implemented autonomously: Claude opens a PR labeled ai-loop that iterates with the AI reviewers until it converges, and a human always reviews and squash-merges the result. Don't touch the loop labels (ai-loop, needs-human-review, ai-loop-paused) on PRs you don't own. Full details: AI-Assisted Development.