Contributing
Building the project, running the tests and proposing a change.
Thank you for helping. Bug reports, fixes, documentation and new features are all welcome. For anything larger than a small fix, please open an issue first, so we can agree on the approach before you spend time on it.
Setting up
You need:
- Rust: rustup installs the pinned version from
rust-toolchain.toml; - Node.js 22 or later, and pnpm (
corepack enableinstalls the pinned version); - Python 3 with
jsonschema, for the schema checks.
git clone https://github.com/eddiesr93/inkoxide && cd inkoxide
scripts/build-node.sh # build the native binding into packages/inkoxide
pnpm install
Optional, for the full local check: poppler and numpy/Pillow (visual regression), qpdf
(PDF structure), cargo-deny, and the nightly toolchain scripts/fuzz.sh --toolchain prints,
with cargo-fuzz (fuzzing).
Architecture explains how the repository is organised and how a document goes from React to PDF.
Making a change
cargo test --workspace # the engine
pnpm test # the TypeScript packages
scripts/ci.sh --quick # formatting, tests and schema checks
scripts/ci.sh # everything, including clippy and the visual diff
- Engine changes need a test: a unit test next to the code, or a fixture in
fixtures/docs/when the change affects output. - Output changes show up in the visual regression test. Check
target/visual/*-diff.png, and when the new output is right, regenerate the references withscripts/update-expected.sh(on Linux) and commit them with the change. - Schema changes start in
packages/schema/document.v1.json. Then update the serde structs incrates/core/src/schema/, runnode scripts/gen-schema-types.mjs,python3 scripts/gen-schema-doc.pyandpython3 scripts/gen-fuzz-dict.py, teach the fuzz generator (fuzz/src/lib.rs) the new properties, and add an entry topackages/schema/CHANGELOG.md. Changes must be backwards compatible within schema version 1. - React and Tailwind changes need a test in
packages/*/test. A new Tailwind utility belongs inpackages/tailwind/src/supported.ts; its examples are tests, andpnpm exec tsx scripts/gen-tailwind-docs.tsregeneratesdocs/TAILWIND_SUPPORT.md. - Screenshots in the READMEs come from
examples/. After changing an example or the output, runpnpm examples(needs poppler) and commit the new images. - User-facing changes get a line in CHANGELOG.md under "Unreleased".
Pull requests
- Keep each pull request to one change, with a title that says what it does ("Repeat table footers on every page", not "Fix tables").
- The
ciworkflow must pass. It runs formatting, clippy, the Rust and TypeScript tests and the schema checks on Linux. - Rust is formatted with
cargo fmtand linted with clippy (pedantic). TypeScript is formatted with oxfmt (pnpm format) and linted with oxlint (pnpm lint).
Releasing
Maintainers release from main:
- Bump the version of
inkoxide,@inkoxide/wasm,@inkoxide/render,@inkoxide/react,@inkoxide/tailwindand@inkoxide/styletogether (the Cargo workspace and the sixpackage.jsonfiles;scripts/check-versions.pychecks them), since they share one version, and runnode scripts/gen-react-version.mjs. Bump@inkoxide/schemaonly if the schema changed; it has its own version. Move the "Unreleased" entries in CHANGELOG.md and packages/schema/CHANGELOG.md under the new versions. - Dispatch the
releaseworkflow, first withdry_runon. It stops unless theciworkflow passed for the commit (a dry run only warns). It builds the native bindings on every platform and the WebAssembly engine, and publishes every package whose version is not on npm yet, in dependency order:@inkoxide/wasmwith the engine packages, before@inkoxide/render. npm trusts the workflow (trusted publishing), so no token is involved and every package is published with provenance. A real release publishes from thereleaseenvironment, which admits onlymain; npm trusts that environment alone. Then it tags the commit and creates the GitHub release from the newest changelog section:v0.2.0for a heading## 0.2.0 - <date>,@inkoxide/[email protected]for## @inkoxide/render 0.1.1 - <date>.
A new package needs its trusted publisher on npm (the release.yml workflow and the release
environment) before the workflow can publish it. Where npm lets that be set only on a package
that exists, the maintainer publishes its first version by hand, from the staged copy
(node scripts/npm-release.mjs <bin-dir> <staging-dir>), then sets the trusted publisher.
Licence
By contributing, you agree that your contributions are licensed under the MIT licence of this project.
Synced from CONTRIBUTING.md in the inkoxide repository.