Skip to content

Latest commit

 

History

History
178 lines (135 loc) · 6.99 KB

File metadata and controls

178 lines (135 loc) · 6.99 KB

Contributing

Thanks for your interest in contributing. This is a pnpm workspace driven by Nx that publishes fifteen packages across six products - the plugins, their renderers and the shared cores - so most commands below are run from the repository root.

Which package a change belongs to is usually obvious from the package table. If it is not, open an issue first; the boundary between a plugin, a core and a renderer is deliberate, and putting something on the wrong side of it is the one kind of change that is expensive to undo.

Getting started

The quickest way to a working environment is Docker, which brings up the whole stack at once:

git clone https://github.com/qkix/strapi-plugins.git
cd strapi-plugin-better-blocks
docker compose up --build

That builds the plugins and the renderers and starts a Strapi v5 app (SQLite) at http://localhost:1337/admin, seeded with the showcase articles and an admin account (admin@example.com / admin12#). The renderer examples come up alongside it, all reading that same content:

Example URL
React http://localhost:5173
Astro http://localhost:4321
Nuxt http://localhost:3000

To wipe the seeded database and uploaded media and start again:

docker compose down -v && docker compose up --build

See examples/README.md for what gets seeded and how to run a single example.

Without Docker

Node 20 or 22 - the Strapi SDK refuses 23 and newer.

pnpm install
pnpm build   # every publishable package

pnpm --filter @qkix/example-strapi-app develop
pnpm --filter @qkix/example-nuxt-app dev   # or -react-app / -astro-app

Development workflow

  1. Create a branch from main.

  2. Make your change in the package it belongs to.

  3. Verify it. For plugin work that means the Strapi admin; for renderer work, the matching example app - and docker compose up --build, because the plugins and renderers are compiled into the image, so a plain docker compose restart does not pick up source changes. An example app's own source hot-reloads with no rebuild.

  4. Run the checks CI runs:

    pnpm lint
    pnpm typecheck
    pnpm test

To work on one package, filter:

pnpm --filter @qkix/strapi-plugin-better-blocks test
pnpm exec nx run @qkix/better-blocks-vue-renderer:build

Nx only reruns what a change actually affects, so a second run is mostly cache.

Where things belong

The shared cores. The Better Blocks document types and the framework-independent logic live in packages/better-blocks-core; chart specs, validation and SVG rendering live in packages/chartkit-core. If you add a block attribute or a chart option, add it there first - every renderer reads it from that one place, and the boundary lint rule keeps the dependency direction honest.

Adding a block type to the Better Blocks editor is a public API, not an edit to the editor package. See Registering a block type: one definition object teaches the editor, the validator, the migrator and every renderer about the block. Chartkit's chart block is the worked example.

Renderers stay in step. A feature that changes rendered markup should land in the React, Astro and Vue renderers together, or it becomes a difference nobody remembers to close. Each has its own test suite and they share a characterization suite over the core helpers.

Pull requests

  • Keep PRs focused - one feature or fix per PR.
  • Fill out the PR template.
  • Make sure CI passes (lint, typecheck, test, build) on both Node 20 and 22.
  • Add screenshots or GIFs for UI changes.
  • Documentation ships with the code: a change to a package's behavior updates that package's README in the same PR.

Package labels (pkg: …) are applied automatically from the paths a PR touches, so a new package needs an entry in .github/labeler.yml and in the issue forms.

Commit messages decide what gets released

Conventional commits, and the type is not cosmetic - nx release reads it to decide who gets a new version.

Files that belong to no package - pnpm-lock.yaml, nx.json, the root package.json - count as touching every package. A type that never bumps (chore, docs, ci, build, refactor, test) is harmless there, but fix or feat gives all fourteen packages a release whose changelog entry says nothing about them.

So type by what ships, not by what the work felt like:

The change Type
Behaviour a package's users get feat / fix
Examples, tooling, CI, lockfile bumps chore / ci / build
READMEs, screenshots, roadmaps docs

Adding a dependency to an example app is a chore, however much it fixed something locally - nothing shipped. Check with nx show projects --affected --files=<path> when unsure.

The scope is the package's directory name. feat(strapi-plugin-rewind), not feat(rewind). nx resolves a scope against project names and directory names, and a scope it cannot resolve is not an error - the commit is treated as an indirect change to every package it touched and quietly downgraded to a patch. So feat(rewind) ships a feature as a patch and says nothing about it. Check a scope with nx show projects --projects=<scope> before relying on it.

And the scope that counts is the one in the pull request title. main only takes squash merges, so however many commits a branch has, one commit lands - with the PR title as its subject. Splitting a branch into one commit per package looks tidy and changes nothing: the split is discarded on merge and every package but the one named in the title drops to an indirect patch.

For a change that is a feature for more than one package, name them all. nx splits a scope on commas:

feat(chartkit-core,chartkit-editor,strapi-plugin-chartkit): per-chart colors

Packages that merely depend on one of those get their patch automatically and do not belong in the list.

Releases are cut with nx release: versions, tags and changelogs are per package, so a change to one does not bump the others. The release workflow is manual and defaults to a dry run. A feat is a minor and a fix is a patch, at 0.x the same as anywhere else - but a breaking change goes to 1.0.0, so pass an explicit version to the workflow to keep a pre-1.0 package in 0.x.

Reporting bugs

Use the bug report template and include which package you are using, its version, your Strapi version, and steps to reproduce.

Feature requests

Use the feature request template. A description of the problem is worth more than a description of the solution - it leaves room for a better one.