Thanks for your interest in contributing. The SDK is small and intentionally narrow in scope; please skim this page before opening issues or PRs.
By participating in this project you agree to abide by the Code of Conduct.
- Scope
- Reporting bugs and asking questions
- Working on the code (fork → PR workflow)
- Local development
- Coding conventions
- Commit messages
- Testing requirements
- Pull request review
- License
This repository accepts contributions in two areas:
-
Linux / macOS support fixes for running NeoLAB's Windows-only
NeoLABNcodeSDK.dllunder Mono. Focus area:tools/ncode-cli/andpattern/neolab/. -
Dot-pattern dilation kernels and PDF-pipeline improvements that stay within the abstractions established by
ncode/,pattern/,pattern/kernels/, andpdf/.
Out of scope: new Generators that reimplement NeoLAB's proprietary dot algorithm, application-level features (UIs, storage, upload clients), or features that require redistributing NeoLAB-licensed assets.
If you are unsure whether your idea is in scope, open an issue first — a 5-minute design conversation up front saves a 5-day implementation that gets rejected.
- Bug reports — open a GitHub issue using the Bug report template. Include the printer/driver combination if your report touches dot-mode or kernel behaviour.
- Feature requests — open a GitHub issue using the Feature request template. Describe the use case before the proposed API.
- Security issues — see
SECURITY.md. Do not open a public issue. - Questions — please use GitHub Discussions if enabled, otherwise
open an issue with the
questionlabel.
External contributors work via fork-and-pull. Direct pushes to this
repository's main branch are not permitted; the only path for an
outside change to land is a pull request from a fork.
-
Fork the repository on GitHub: click Fork in the top-right corner of the repo page. This creates
<your-username>/Ncode-SDK-for-Linuxunder your account. -
Clone your fork locally:
git clone https://github.com/<your-username>/Ncode-SDK-for-Linux.git cd Ncode-SDK-for-Linux
-
Add the upstream remote so you can sync future updates:
git remote add upstream https://github.com/Post-Math/Ncode-SDK-for-Linux.git git remote -v # origin https://github.com/<your-username>/Ncode-SDK-for-Linux.git (fetch / push) # upstream https://github.com/Post-Math/Ncode-SDK-for-Linux.git (fetch / push)
Do not push to
upstream— it will be rejected by branch protection.origin(your fork) is where your work goes.
-
Sync your fork's
mainwith upstream to start from the latest code:git checkout main git fetch upstream git merge --ff-only upstream/main git push origin main
Use
--ff-onlyto refuse anything other than a fast-forward — this keeps yourmainhistory identical to upstream. -
Create a topic branch off
main. Use a short, descriptive name prefixed with the change type:git checkout -b feat/diamond6-kernel # or: fix/mono-path-overflow # or: docs/contributing-clarifications # or: test/neolab-arg-rejection
One branch per logical change. Don't lump unrelated fixes onto the same branch — review takes longer and partial reverts become awkward.
-
Make your changes, then run the full local check before pushing:
go build ./... go vet ./... gofmt -l . # must print nothing go test ./... -timeout 5m
If any of those fail, the same gates will fail on CI and your PR cannot merge — fix locally first.
-
Commit with a clear message (see Commit messages below):
git add <files> git commit
-
Push to your fork:
git push origin feat/diamond6-kernel
-
Open a pull request from your fork's branch into
Post-Math/Ncode-SDK-for-Linux:main:- Click Compare & pull request on your fork's GitHub page, or navigate to upstream and click New pull request → compare across forks.
- The PR template will pre-populate; fill it in. Keep the description tight: what changed, why, what was tested.
- Mark the PR as Draft if you want early feedback before review.
-
Address review comments by pushing additional commits to the same branch. Do not force-push during review — it makes reviewer comments hard to follow. The PR will be squashed on merge, so the intermediate review-fix commits do not pollute
main.If review asks for a structural rework, push the rework as new commits and call out in the PR thread that the diff has changed significantly.
If your PR sits in review while upstream main advances, periodically:
git fetch upstream
git rebase upstream/main # or: git merge upstream/main
# resolve conflicts if any, then:
git push --force-with-lease origin feat/diamond6-kernelUse --force-with-lease, never plain --force — it refuses to
overwrite if a reviewer has pushed commits in the meantime.
You need:
- Go 1.25 or newer with cgo enabled (go-fitz statically links MuPDF).
- On Linux:
build-essentialandlibgl1-mesa-devfor the first cgo build. - For tests: nothing else — the test suite uses an internal stub
Generatorand synthesises its own input PDFs at runtime, so no NeoLAB credentials, DLL, or Mono runtime are required.
Verify a clean checkout:
go build ./...
go vet ./...
go test ./... -timeout 5m
gofmt -l . # must print nothingThe pdf package's integration test runs the full pipeline at 600 DPI
and takes ~50 s on a developer laptop. That is expected.
- API stability: exported names in
ncode,pattern,pattern/kernels,pattern/neolab,pattern/stub, andpdfare part of the SDK's public surface. Treat any rename, removal, or signature change as a breaking change and call it out in the PR description. - Cross-platform parity: every Go change must build on
linux/amd64,linux/arm64,darwin/arm64, andwindows/amd64. CI runs the cgo test suite on Linux and a no-cgo cross-build on the other targets — both must pass. - No new heavy dependencies without prior issue discussion. The
current dependency surface is
pdfcpu+go-fitz+hhrutter/tiffgolang.org/x/image; adding to it imposes a real audit cost on downstream consumers.
- Kernel additions must come with: an ASCII-art comment showing
the dot layout, a centroid analysis (see
docs/kernels.mdfor the invariant), and at least one test inpattern/kernels/kernels_test.goasserting the footprint stays within the ±1-pixel envelope. - Vendor-neutral language: keep technical content in code comments and docs vendor-neutral. The LICENSE file carries the project's attribution; do not introduce company-branded phrasing in source files.
- Comment what's non-obvious, not what the code says. A comment is worth writing when it captures a why that the code can't express on its own (a hidden constraint, a workaround for a specific upstream bug, an invariant a future reader could violate).
Use the imperative mood and structure messages as:
component: short summary (≤ 70 chars)
Optional body that explains the *why*. Wrap at ~72 columns. Reference
related issues by number ("fixes #123" closes the issue on merge).
Examples:
pattern/kernels: add Diamond6 kernel and centroid test
pdf: rename local var to avoid shadowing context.Context
docs/kernels: drop fabricated density numbers
Single-purpose commits are preferred over WIP commits. The maintainers squash on merge, so intermediate "fix typo" commits during review are fine — they get collapsed.
Sign-off (Signed-off-by:) is not required for this project.
- New code in
ncode/,pattern/, orpattern/kernels/must come with pure-Go unit tests (no cgo, no NeoLAB credentials). - New code in
pdf/should be exercised throughpattern/stubin integration-style tests so CI runs without external assets. pattern/neolab/changes must keep the existing tests passing; if you add subprocess interactions, swapcmdBuilderfor a fake in the test (seepattern/neolab/generator_test.gofor the pattern) and assert on the args the Generator would have produced.
If a bug fix is hard to express as a regression test, say so in the PR description and explain why.
- A maintainer will pick the PR up. Initial response target is 5 business days; if the PR has had no comment after a week, ping the thread.
- Expect at least one round of review feedback. The reviewer's job is to ensure the change matches the SDK's scope, conventions, and cross-platform constraints — not to find typos.
- Merges are squash-only. Your branch's intermediate commits are
collapsed into one commit on
mainwhose message is taken from the PR title and description. Phrase those accordingly. - After merge, you may delete your fork's branch. CI, branch protection, and the auto-delete setting take care of the rest.
By contributing, you agree that your contributions will be licensed
under the same Apache License 2.0 that covers the rest of the
repository (see LICENSE). Be aware of the AGPL-3.0
transitive obligation that binaries built from this SDK incur via
go-fitz — see the AGPL-3.0 transitive dependency section in the
README.