---
title: "Contribution guide"
description: "Set up the repository, run the checks and follow the rules that keep providers consistent."
canonical_url: "https://docs-8831a2g1f-poetry.vercel.app/contributing/guidelines"
---
# Contribution guide

> Set up the repository, run the checks and follow the rules that keep providers consistent.

Thanks for helping with `forges`. This page covers how to set up the repository, the checks a change has to pass and the rules that keep the providers consistent. By taking part, you agree to the [Code of Conduct](https://github.com/danielroe/forges/blob/main/CODE_OF_CONDUCT.md).

## Set up

You need Node.js 22.18 or later and [pnpm](https://pnpm.io). The repository pins the versions it develops with in `devEngines`.

```sh
pnpm install
pnpm test:unit
```

## Commands

<table>
<thead>
  <tr>
    <th>
      Command
    </th>
    
    <th>
      What it does
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        pnpm dev
      </code>
    </td>
    
    <td>
      Runs the unit tests in watch mode
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pnpm test:unit
      </code>
    </td>
    
    <td>
      Runs the unit tests once
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pnpm test:types
      </code>
    </td>
    
    <td>
      Type-checks <code>
        src
      </code>
      
      , <code>
        test
      </code>
      
       and <code>
        scripts
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pnpm test:capabilities
      </code>
    </td>
    
    <td>
      Fails for a capability that a provider declares <code>
        true
      </code>
      
       and no test called
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pnpm test:knip
      </code>
    </td>
    
    <td>
      Finds unused files, exports and dependencies
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pnpm test:size
      </code>
    </td>
    
    <td>
      Checks the browser bundle budgets. Run <code>
        pnpm build
      </code>
      
       first
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pnpm lint
      </code>
      
      , <code>
        pnpm lint:fix
      </code>
    </td>
    
    <td>
      Lints, and fixes what it can
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pnpm capability-matrix
      </code>
    </td>
    
    <td>
      Regenerates the capability tables in the docs
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pnpm record-fixtures <forge>
      </code>
    </td>
    
    <td>
      Records responses from a live forge
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pnpm check:all
      </code>
    </td>
    
    <td>
      Runs lint, tests, the engines check, a build and the size check
    </td>
  </tr>
</tbody>
</table>

## Project layout

<table>
<thead>
  <tr>
    <th>
      Path
    </th>
    
    <th>
      Content
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        src/<forge>/
      </code>
    </td>
    
    <td>
      One provider each: its factory, normalisation and webhook handling
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        src/model.ts
      </code>
      
      , <code>
        src/provider.ts
      </code>
      
      , <code>
        src/define.ts
      </code>
    </td>
    
    <td>
      The shared model, the provider interface and <code>
        defineForgeProvider()
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        src/fake/
      </code>
      
      , <code>
        src/testing/
      </code>
    </td>
    
    <td>
      The in-memory forge and the test helpers
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        test/
      </code>
    </td>
    
    <td>
      Unit tests, recorded fixtures and the shared recording steps
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        examples/
      </code>
    </td>
    
    <td>
      Small, tested projects that use the library
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        docs/
      </code>
    </td>
    
    <td>
      The documentation site
    </td>
  </tr>
</tbody>
</table>

## Rules

- Declare a capability `true` only when a test calls it. Use `'experimental'` for anything that isn't verified against a recording of the live forge.
- After you change a provider's capabilities, run `pnpm capability-matrix`. A test fails if the docs are out of date.
- Import source files with the `.ts` extension, so that `node scripts/<name>.ts` runs without a build.
- Don't add runtime dependencies. Don't import Node.js built-in modules from a provider.
- Keep errors, warnings and `skipped` reasons free of credentials.
- Add a test for each change. For a new read, record a fixture instead of writing one by hand.

To add a forge or an operation, read [Write a provider](https://docs-8831a2g1f-poetry.vercel.app/contributing/write-a-provider) and [Record fixtures](https://docs-8831a2g1f-poetry.vercel.app/contributing/record-fixtures).

## Commit messages

Commits follow [Conventional Commits](https://www.conventionalcommits.org). Releases are cut from the commit messages, so the type decides the version bump. Use the provider as the scope when a change concerns one forge:

```text
feat(github): adopt asynchronous direct merges
fix(gitlab): read nested group paths
docs: explain webhook verification
```

Use the same format for the title of a pull request.

## Pull requests

- Keep a pull request to one change.
- Run `pnpm check:all` before you push. CI runs the same checks.
- Describe what changed and why. Link the issue it closes.

## Writing documentation

The documentation lives in `docs/content`. Write short sentences in the second person, and prefer a code example to a long explanation. Avoid em-dashes and filler words. Run the site locally with:

```sh
pnpm --filter forges-docs dev
```

## Reporting a problem

Open an [issue](https://github.com/danielroe/forges/issues) with steps to reproduce. For a forge-specific bug, name the forge and, for a self-hosted forge, its version.


## Sitemap

See the full [sitemap](https://docs-8831a2g1f-poetry.vercel.app/sitemap.md) for all pages.
