mirror of
https://github.com/pnpm/pnpm.git
synced 2026-04-11 02:29:48 -04:00
258 lines
8.9 KiB
Markdown
258 lines
8.9 KiB
Markdown
# Contributing
|
|
|
|
## Table of contents
|
|
|
|
- [Setting Up the Environment](#setting-up-the-environment)
|
|
- [Working with Git Worktrees](#working-with-git-worktrees)
|
|
- [Running Tests](#running-tests)
|
|
- [Submitting a Pull Request (PR)](#submitting-a-pull-request-pr)
|
|
- [After your pull request is merged](#after-your-pull-request-is-merged)
|
|
- [Coding Style Guidelines](#coding-style-guidelines)
|
|
- [Commit Message Guidelines](#commit-message-guidelines)
|
|
- [Commit Message Format](#commit-message-format)
|
|
- [Revert](#revert)
|
|
- [Type](#type)
|
|
- [Scope](#scope)
|
|
- [Subject](#subject)
|
|
- [Body](#body)
|
|
- [Footer](#footer)
|
|
|
|
## Setting Up the Environment
|
|
|
|
1. Run `pnpm install` in the root of the repository to install all dependencies.
|
|
1. Run `pnpm add ./pnpm/dev -g` to make pnpm from the repository available in the command line via the `pd` command.
|
|
1. Run `pnpm run compile` to create an initial build of pnpm from the source in the repository.
|
|
1. Now you can change any source code file and run `pd [command] [flags]` to run `pnpm` directly from the source code by compiling all the files without typechecking in memory.
|
|
1. Alternatively, for recompiling all the projects with typechecking after your changes, again run `pnpm run compile` in the root of the repository.
|
|
1. In order to run all the tests in the repository, run `pnpm run test-main`. You may also run tests of specific projects by running `pnpm test` inside a project's directory or using `pnpm --filter <project name> test`.
|
|
|
|
Some of the e2e tests run node-gyp, so you might need to install some build-essentials on your system for those tests to pass. On Fedora, install these:
|
|
|
|
```shell
|
|
sudo dnf install make automake gcc gcc-c++ kernel-devel
|
|
```
|
|
|
|
## Working with Git Worktrees
|
|
|
|
Worktrees let you check out multiple branches simultaneously in separate directories,
|
|
which is useful for working on several issues in parallel without stashing or switching branches.
|
|
This is particularly powerful when running multiple AI coding agents (e.g. Claude Code) at the
|
|
same time — each agent gets its own isolated worktree, so they can work concurrently without
|
|
interfering with each other.
|
|
|
|
The repo includes a `pnpm worktree:new <branch>` script that creates a worktree as a sibling
|
|
of the repo root. For a branch named `feat/my-feature` it creates `../feat-my-feature` (slashes
|
|
are replaced with dashes).
|
|
|
|
Because a script cannot change your shell's working directory, the repo also provides shell
|
|
helpers (`shell/wt.sh` for bash/zsh, `shell/wt.fish` for fish) that wrap the script and `cd`
|
|
into the new worktree automatically.
|
|
|
|
### One-time setup
|
|
|
|
**fish** — add to `~/.config/fish/config.fish` so `wt` is available in every future session:
|
|
|
|
```fish
|
|
source /path/to/pnpm/shell/wt.fish
|
|
```
|
|
|
|
**bash/zsh** — add to `~/.bashrc` or `~/.zshrc`:
|
|
|
|
```sh
|
|
source /path/to/pnpm/shell/wt.sh
|
|
```
|
|
|
|
To use `wt` in your current terminal without restarting it, also run the `source` command directly once.
|
|
|
|
### Usage
|
|
|
|
```shell
|
|
# Create a worktree for an existing branch and switch to it
|
|
wt fix/4444
|
|
|
|
# Create a worktree for a new branch (branched from main) and switch to it
|
|
wt feat/my-feature
|
|
|
|
# Create a worktree for a GitHub PR (works for forks too) and switch to it
|
|
wt 10000
|
|
```
|
|
|
|
Passing a number is interpreted as a PR number. The PR is fetched via
|
|
`git fetch origin pull/<number>/head` into a local branch named `pr-<number>`, so it works
|
|
for both same-repo branches and forks.
|
|
|
|
If you only need the worktree path (e.g. to open it in an editor) without switching directories,
|
|
run the underlying script directly:
|
|
|
|
```shell
|
|
pnpm worktree:new feat/my-feature
|
|
pnpm worktree:new 10000
|
|
```
|
|
|
|
## Running Tests
|
|
|
|
You can run the tests of the project that you modified by going to the project's directory and running:
|
|
|
|
```shell
|
|
pnpm test
|
|
```
|
|
|
|
Alternatively, you can run it from anywhere by specifying the name of the project using the `--filter` option:
|
|
|
|
```shell
|
|
pnpm --filter core test
|
|
```
|
|
|
|
If you want to pass options to Jest, use the `pnpm run test` command and append any needed options. For instance, if you want to run a single test in a single file, run:
|
|
|
|
```shell
|
|
pnpm --filter core run test test/lockfile.ts -t "lockfile has dev deps even when installing for prod only"
|
|
```
|
|
|
|
## Submitting a Pull Request (PR)
|
|
|
|
Before you submit your Pull Request (PR) consider the following guidelines:
|
|
|
|
- Search [GitHub](https://github.com/pnpm/pnpm/pulls) for an open or closed PR
|
|
that relates to your submission. You don't want to duplicate effort.
|
|
- Make your changes in a new git branch:
|
|
|
|
```shell
|
|
git checkout -b my-fix-branch main
|
|
```
|
|
|
|
- Create your patch, following [code style guidelines](#coding-style-guidelines), and **including appropriate test cases**.
|
|
- Run `pnpm changeset` in the root of the repository and describe your changes. The resulting files should be committed as they will be used during release.
|
|
- Run the full test suite and ensure that all tests pass.
|
|
- Commit your changes using a descriptive commit message that follows our
|
|
[commit message conventions](#commit-message-guidelines). Adherence to these conventions
|
|
is necessary because release notes are automatically generated from these messages.
|
|
|
|
```shell
|
|
git commit -a
|
|
```
|
|
|
|
Note: the optional commit `-a` command line option will automatically "add" and "rm" edited files.
|
|
|
|
- Push your branch to GitHub:
|
|
|
|
```shell
|
|
git push origin my-fix-branch
|
|
```
|
|
|
|
- In GitHub, send a pull request to `pnpm:main`.
|
|
- If we suggest changes then:
|
|
|
|
- Make the required updates.
|
|
- Re-run the test suites to ensure tests are still passing.
|
|
- Rebase your branch and force push to your GitHub repository (this will update your Pull Request):
|
|
|
|
```shell
|
|
git rebase main -i
|
|
git push -f
|
|
```
|
|
|
|
That's it! Thank you for your contribution!
|
|
|
|
### After your pull request is merged
|
|
|
|
After your pull request is merged, you can safely delete your branch and pull the changes
|
|
from the main (upstream) repository:
|
|
|
|
- Delete the remote branch on GitHub either through the GitHub web UI or your local shell as follows:
|
|
|
|
```shell
|
|
git push origin --delete my-fix-branch
|
|
```
|
|
|
|
- Check out the main branch:
|
|
|
|
```shell
|
|
git checkout main -f
|
|
```
|
|
|
|
- Delete the local branch:
|
|
|
|
```shell
|
|
git branch -D my-fix-branch
|
|
```
|
|
|
|
- Update your main with the latest upstream version:
|
|
|
|
```shell
|
|
git pull --ff upstream main
|
|
```
|
|
|
|
## Coding Style Guidelines
|
|
|
|
[](https://github.com/standard/standard)
|
|
|
|
Use the [Standard Style](https://github.com/standard/standard).
|
|
|
|
## Commit Message Guidelines
|
|
|
|
[](http://commitizen.github.io/cz-cli/)
|
|
|
|
We have very precise rules over how our git commit messages can be formatted. This leads to **more
|
|
readable messages** that are easy to follow when looking through the **project history**.
|
|
|
|
### Commit Message Format
|
|
|
|
Each commit message consists of a **header**, a **body** and a **footer**. The header has a special
|
|
format that includes a **type**, a **scope** and a **subject**:
|
|
|
|
<type>(<scope>): <subject>
|
|
<BLANK LINE>
|
|
<body>
|
|
<BLANK LINE>
|
|
<footer>
|
|
|
|
The **header** is mandatory and the **scope** of the header is optional.
|
|
|
|
Any line of the commit message cannot be longer than 100 characters! This allows the message to be easier
|
|
to read on GitHub as well as in various git tools.
|
|
|
|
#### Revert
|
|
|
|
If the commit reverts a previous commit, it should begin with `revert:`, followed by the header of the reverted commit. In the body it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit being reverted.
|
|
|
|
#### Type
|
|
|
|
Must be one of the following:
|
|
|
|
- **feat**: A new feature
|
|
- **fix**: A bug fix
|
|
- **docs**: Documentation only changes
|
|
- **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing
|
|
semi-colons, etc)
|
|
- **refactor**: A code change that neither fixes a bug nor adds a feature
|
|
- **perf**: A code change that improves performance
|
|
- **test**: Adding missing tests
|
|
- **chore**: Changes to the build process or auxiliary tools and libraries such as documentation
|
|
generation
|
|
|
|
#### Scope
|
|
|
|
The scope could be anything specifying place of the commit change. For example
|
|
`plugin-example`, `render-md`, etc.
|
|
|
|
#### Subject
|
|
|
|
The subject contains succinct description of the change:
|
|
|
|
- use the imperative, present tense: "change" not "changed" nor "changes"
|
|
- don't capitalize first letter
|
|
- no dot (.) at the end
|
|
|
|
#### Body
|
|
|
|
Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes".
|
|
The body should include the motivation for the change and contrast this with previous behavior.
|
|
|
|
#### Footer
|
|
|
|
The footer should contain any information about **Breaking Changes** and is also the place to
|
|
reference GitHub issues that this commit **Closes**.
|
|
|
|
**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines. The rest of the commit message is then used for this.
|