First thing first, thank you for taking the time to contribute.
Take this document as a set of guidelines, not rules, for contributing to this project. In any case, use your best judgment and feel free to propose changes to this document in a pull request.
If this is your first time contribution to an open source project, then you should start with the section First time contributor, and then continue with Getting started.
Don't forget to read our code of conduct.
We all started somewhere. And, before getting started, you might want to be familiar with some of the basic concepts used in open source projects:
- code versioning with Git
- project forking with Github
- pushing a pull request with Github
Many people did a great job at explaining those concepts, here a few resources:
- How to Contribute to Open Source: a guide to making open source contributions
- Hello Open Source: a repository to learn about open source code contributions flow
- First Contributions: a repository to learn how to make your first contribution
You are now all set for your first contribution 🎉
If you aim at a code contribution, you will need the following tools:
- git
- nvm (macOS and Linux) or nvm-windows (Windows)
- docker or podman*
- earthly
- typescript
If you do not yet have an IDE, then I recommend VS Code for this project.
* For using podman
with earthly
, you need to run earthly config global.container_frontend podman-shell
(see earthly ticket).
- Fork this repository (doc)
- Create a new branch in your forked repository (doc)
- We are using a branch naming convention:
- feature:
feature/short-description-of-the-change
- fix:
fix/short-description-of-the-fix
, you can also reference an existing issue, egfix/issue-456
- documentation:
doc/short-description-of-the-change
- feature:
- We are using a branch naming convention:
If you aim at a code contribution, you will need to perform few additional steps:
-
checkout your forked repository to your computer (doc).
-
install the node version defined in
.nvmrc
using nvmnvm install nvm use
-
from the local folder, install repository packages
npm install
-
from the local folder, check that everything is working
earthly +all
Keep changes small and focused. This means a pull request should only aim at one purpose: fixing typo in the documentation, fixing one bug at a time, changing one behavior.
The project uses Markdown for writing documentation (doc).
You should edit the documentation, or add new documentation files, directly in your branch from your Github fork.
We are using a monorepo, so you might want to read about monorepo before jumping into the code.
The code base is full TypeScript using NodeJS, and Jest for tests. The codebase can seem a bit messy, so start by reading the section coding style.
When making your changes, remember to check your code by running:
npm run ts:check
checks that the code is TS compliantnpm run lint
checks that the code respects coding standards (ESLint + Prettier)npm test
runs the test suitesearthly +smoke-test
runs smoke tests (includes packages build)
When you are ready, you should then run the full checks with earthly +all
.
Note that
npm run ts:check
,npm run lint
andnpm test
will be automatically triggered when committing code, andearthly +all
will be automatically triggered when pushing local code to the remote repository.
This project uses the conventional commits format for commit messages. When you run git commit
, commitizen will be automatically triggered and you should get some prompts on the terminal that help you write a good commit message.
You will certainly find awkward constructions and patterns, and you should feel free to improve the existing code.
The quickest way to understand the code structure is to look at the folder structure:
packages
contains packages sourcesdocusaurus
contains Docusaurus plugin 📦@graphql-markdown/docusaurus
src
contains all TS files used by the package.tests
folder contains all tests needed (see tests section).scripts
contains scripts used for running smoke tests.
core
contains core logic 📦@graphql-markdown/core
assets
folder contains assets used by the plugin, e.g. the default homepagegenerated.md
.src
contains all TS files used by the package.tests
folder contains all tests needed (see tests section).
utils
contains shared libraries 📦@graphql-markdown/utils
src
contains all TS files used by the package.tests
folder contains all tests needed (see tests section).
graphql
contains utilities for loading and parsing GraphQL schema 📦@graphql-markdown/graphql
src
contains all TS files used by the package.tests
folder contains all tests needed (see tests section).
logger
contains GraphQL-Markdown 📦@graphql-markdown/logger
src
contains all TS files used by the package.tests
folder contains all tests needed (see tests section).
printer-legacy
contains legacy code for exporting markdown 📦@graphql-markdown/printer-legacy
src
contains all TS files used by the package.tests
folder contains all tests needed (see tests section).
diff
contains diff methods (optional) 📦@graphql-markdown/diff
src
contains all TS files used by the package.tests
folder contains all tests needed (see tests section).
helpers
contains helpers for customized directives feature (optional) 📦@graphql-markdown/helpers
src
contains all TS files used by the package.tests
folder contains all tests needed (see tests section).
config
folder configuration files for development tools.docs
folder contains online documentation.scripts
folder contains scripts for monorepo (eg. packages version check).website
folder contains Docusaurus file for generating website.
The project uses classes, it is for historical reason and that was not necessarily a good choice. So, you should not feel obliged to do the same.
As a rule of thumb, try to avoid adding external packages unless you have a really good reason.
For example, it is very tempting to use lodash
, but usually developers only need one or two functions from it. In many cases, this can be replaced by a custom function, but if you cannot then always prefer individual packages, e.g. lodash.get
.
When choosing an external package, always look at the following:
- is it maintained? last release, last commit, last reply to an issue
- what is the size? the smaller the better
- how many dependencies? the lesser the merrier
There are a lot of ways to test your code, and you should always add tests when making changes into the code.
There are 3 types of tests used in this project, all based on Jest:
-
unit
for testing individual units of code (class methods and functions). If your changes are located insrc/utils
then this is likely where you should add your tests.You should always mock external calls (see Jest mock).
-
integration
for testing the logic of the main classes. If your changes are located insrc/lib
, then you will need to add your tests here.If your tests interact with the filesystem, then you should make use of file system mocking with
memfs
. -
smoke
(akae2e
) for testing the whole plugin behavior. If your changes affect the CLI or options then you will need to update those tests.The tests run within a Docker container using Earthly.
The project uses Stryker Mutator for mutation testing against unit tests. The purpose is to ensure that unit tests are able to capture changes in the code, i.e. not just "always pass".
As a contributor, you do not need to do anything. However, if the mutation testing score falls below a certain threshold when running mutations tests against your PR, this likely means that you need to improve your tests (even if the test coverage is good).
Mutation testing can be run locally with the command:
earthly +mutation-test
You can read more about mutation testing here.
The documentation is automatically generated and published when a new release is created.
You can build the documentation locally with the command:
earthly +build-docs
You can also create a local container image graphql-markdown:docs
for tests:
earthly +build-image
docker run --rm -it -p 8080:8080 graphql-markdown:docs