Skip to content

Latest commit

 

History

History
320 lines (212 loc) · 12.5 KB

File metadata and controls

320 lines (212 loc) · 12.5 KB

Contributing guide

First things 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 contributing 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.

Table of Contents

First time contributor

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 are a few resources:

You are now all set for your first contribution 🎉

Getting started

Pre-requisites

If you aim at a code contribution, you will need the following tools:

This project is fully compatible with GitHub Codespaces. However, if you prefer a local environment, then we 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).

Create a repository branch

  • 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, eg fix/issue-456
      • documentation: doc/short-description-of-the-change

If you aim at a code contribution, you will need to perform a few additional steps:

  • checkout your forked repository to your computer (doc).

  • install the node version defined in .nvmrc using nvm

    nvm install
    nvm use
  • from the local folder, install repository packages

    bun install
  • from the local folder, check that everything is working

    earthly +all

Make your changes

Keep changes small and focused. This means a pull request should only aim at one purpose: fixing a typo in the documentation, fixing one bug at a time, changing one behaviour.

Documentation

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.

Code

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:

  • bun run ts:check checks that the code is TS compliant
  • bun run lint checks that the code respects coding standards (ESLint + Prettier)
  • bun run test:[unit|integration] runs the test suites for unit tests or integration tests
  • bun run knip checks dependencies
  • earthly ./tests/+smoke-[cli|docusaurus]-test runs smoke tests for CLI or Docusaurus (includes packages build)

When you are ready, you should then run the full checks with earthly +all.

Note that bun run ts:check, bun run lint and bun run test:unit will be automatically triggered when committing code, and earthly +all will be automatically triggered when pushing local code to the remote repository.

Committing changes

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.

Coding style

You will certainly find awkward constructions and patterns, and you should feel free to improve the existing code.

Code structure

The project follows a monorepo architecture with the following key packages:

Core packages:

  • core - Main documentation generation engine
  • docusaurus - Official Docusaurus plugin
  • cli - Command line interface
  • types - Shared TypeScript types

Support packages:

  • utils - Common utilities
  • graphql - Schema loading and parsing
  • logger - Logging functionality
  • printer-legacy - Legacy markdown generation
  • diff - Schema diffing (optional)
  • helpers - Directive helpers (optional)

Each package contains:

package/
├── src/         # Source code
├── tests/       # Unit and integration test files
├── docs/        # API documentation
└── package.json # Package manifest

End-to-end (smoke) tests live outside packages in a top-level directory:

tests/e2e/
├── __data__/           # Shared fixtures (schemas, markdown, shared config options)
├── helpers/            # Shared test helpers (CLI runner)
├── cli/                # CLI-specific specs, jest config, and fixture data
│   ├── __data__/
│   ├── specs/
│   └── jest.config.mjs
└── docusaurus/         # Docusaurus-specific specs, jest config, and fixture data
    ├── __data__/
    ├── specs/
    └── jest.config.mjs

Dependencies

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

Tests

There are a lot of ways to test your code, and you should always add tests when making changes to 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 in src/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 in src/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 (aka e2e) for testing the whole plugin behaviour. If your changes affect the CLI or options, then you will need to update those tests. Smoke tests live in tests/e2e/ and are split by package (cli/ and docusaurus/). Shared fixtures and helpers are in tests/e2e/__data__/ and tests/e2e/helpers/.

    The tests run within a Docker container using Earthly and cannot be run locally.

Mutation testing

The project uses Stryker Mutator for mutation testing against unit tests. The purpose is to ensure that unit tests can 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 mutation 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

or

bun run stryker

You can read more about mutation testing here.

Build documentation

The documentation is automatically generated and published when a new release is created.

You can build the documentation locally with the command:

earthly ./website+build-docs

You can also create a local container image graphql-markdown:docs for tests:

earthly ./website+build-image
docker run --rm -it -p 8080:8080 graphql-markdown:docs

API Documentation

Generate API documentation for packages:

# Generate docs for all packages
bun run docs

The generated documentation will be available in each package's docs/ directory.

Publishing Packages

Important: This section is for maintainers with npm publish access.

The monorepo uses workspace:^ protocol for inter-package dependencies. These must be resolved to actual version numbers before publishing to npm.

⚠️ Never use npm publish directly from a package directory - it will publish unresolved workspace:^ dependencies, breaking the package for users.

Correct Publishing Process

  1. Build all packages first:
bun run build
  1. Use the publish scripts (recommended):
# Single package
./packages/tooling-config/scripts/publish-package.sh <package-name>
./packages/tooling-config/scripts/publish-package.sh --dry-run <package-name>

# All packages for a release
./packages/tooling-config/scripts/publish-release.sh
./packages/tooling-config/scripts/publish-release.sh --dry-run
  1. Or manually with bun pack + npm publish tarball:
cd packages/<package-name>
bun pm pack                    # Creates tarball with resolved deps
npm publish <tarball.tgz> --access public

The publish scripts will:

  • Pack with bun pm pack (resolves workspace:^ to versions)
  • Verify no workspace: references remain in the tarball
  • Publish using the tarball (not from directory)
  • Publish in correct dependency order

Use --dry-run to review the publish plan and validate the tarball flow without publishing anything.

Dependency Order for Publishing

Packages must be published in dependency order:

  1. types (no internal deps)
  2. utils, logger, graphql
  3. helpers, diff, printer-legacy
  4. core
  5. cli
  6. docusaurus

Troubleshooting

Common issues:

  • Build failures: Run earthly --interactive [target] then retry
  • Type errors: Check tsconfig.json in the affected package
  • Test failures: Use --verbose flag with Jest for details
  • Dependency issues: Clean install with bun ci

For other issues, please check existing GitHub issues or create a new one.