Skip to content

Commit

Permalink
docs: update CONTRIBUTING.md (#9590)
Browse files Browse the repository at this point in the history
### Description

I noticed our contributing guide had fallen out of date, so did some
work here to give it some updates.

It likely isn't useful to review this using the diff because I ended up
re-writing almost all of it. Instead, you may want to view the file
itself directly.
  • Loading branch information
anthonyshew authored Dec 10, 2024
1 parent 88eeee7 commit 6047d60
Showing 1 changed file with 147 additions and 134 deletions.
281 changes: 147 additions & 134 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,103 +1,101 @@
# Contributing to Turbo
Thank you for your interest in contributing to Turborepo!

Thanks for your interest in contributing to Turbo!
- [General dependencies](#general-dependencies)
- [Optional dependencies](#optional-dependencies)
- [Structure of the repository](#structure-of-the-repository)
- [Building Turborepo](#building-turborepo)
- [TLS implementation](#tls-implementation)
- [Running tests](#running-tests)
- [Manually testing `turbo`](#manually-testing-turbo)
- [Repositories to test with](#repositories-to-test-with)
- [Debugging tips](#debugging-tips)
- [Verbose logging](#verbose-logging)
- [Crash logs](#crash-logs)
- [Terminal UI debugging](#terminal-ui-debugging)
- [Publishing `turbo` to the npm registry](#publishing-turbo-to-the-npm-registry)
- [Contributing to examples](#contributing-to-examples)
- [Contributing to an existing example](#contributing-to-an-existing-example)
- [Philosophy for new examples](#philosophy-for-new-examples)
- [Designing a new example](#designing-a-new-example)
- [Testing examples](#testing-examples)

- [Contributing to Turbo](#contributing-to-turbo)
- [General Dependencies](#general-dependencies)
- [Linux Dependencies](#linux-dependencies)
- [Contributing to Turborepo](#contributing-to-turborepo)
- [Building Turborepo](#building-turborepo)
- [TLS Implementation](#tls-implementation)
- [Running Turborepo Tests](#running-turborepo-tests)
- [Turborepo Tests](#turborepo-tests)
- [Debugging Turborepo](#debugging-turborepo)
- [Benchmarking Turborepo](#benchmarking-turborepo)
- [Updating `turbo`](#updating-turbo)
- [Manually testing `turbo`](#manually-testing-turbo)
- [Publishing `turbo` to the npm registry](#publishing-turbo-to-the-npm-registry)
- [Creating a new release blog post](#creating-a-new-release-blog-post)
- [Troubleshooting](#troubleshooting)
## General dependencies

## General Dependencies
You will need to have these dependences installed on your machine to work on this repository:

- [Rust](https://www.rust-lang.org/tools/install)
- [cargo-groups](https://github.com/nicholaslyang/cargo-groups)
- NodeJS v18
- npm v10.5.0 (note: this is determined by the GitHub Actions CI, when in doubt, look at what the runner is using)
- capnproto
- protoc
- [Rust](https://www.rust-lang.org/tools/install) ([Repository toolchain](https://github.com/vercel/turborepo/blob/main/rust-toolchain.toml))
- [NodeJS](https://nodejs.org/en) v20
- [pnpm](https://pnpm.io/) v8

### Linux Dependencies
### Optional dependencies

- LLD (LLVM Linker), as it's not installed by default on many Linux distributions (e.g. `apt install lld`).
- For running tests locally, `jq` and `zstd` are also required.
- macOS: `brew install jq zstd`
- Linux: ``sudo apt update && sudo apt install jq zstd`
- Windows: `choco install jq zstandard
- On Linux, ensure LLD (LLVM Linker) is installed, as it's not installed by default on many Linux distributions (e.g. `apt install lld`).

## Contributing to Turborepo
## Structure of the repository

### Building Turborepo
In general, there are two major areas in the repository:

Dependencies
- The `crates` directory with the Rust code for the `turbo` binary
- The `packages` directory with JavaScript packages
- the `examples` directory with examples of how to use Turborepo with other tools and frameworks
- The `docs` directory with the documentation for Turborepo

1. Install [turborepo crate](./crates/turborepo/README.md) build requirements
## Building Turborepo

1. Run `pnpm install` at root

Building

- Building `turbo` CLI: `cargo build --package turbo`
- Using `turbo` to build `turbo` CLI: `./turbow.js`
1. Run `pnpm install` at the root of the repository
2. Run `cargo build`

### TLS Implementation

Turborepo uses `reqwest`, a Rust HTTP client, to make requests to the Turbo API. `reqwest` supports two TLS
Turborepo uses [`reqwest`](https://docs.rs/reqwest/latest/reqwest/) to make requests to the Remote Cache.

`reqwest` supports two TLS
implementations: `rustls` and `native-tls`. `rustls` is a pure Rust implementation of TLS, while `native-tls`
is a wrapper around OpenSSL. Turborepo allows users to select which implementation they want with the `native-tls`
and `rustls-tls` features. By default, the `rustls-tls` feature is selected---this is done so that `cargo build` works
out of the box. If you wish to select `native-tls`, you may do so by passing
`--no-default-features --features native-tls`
to the build command.
is a wrapper around OpenSSL. You may select which implementation you want with the `native-tls`
and `rustls-tls` features.

By default, the `rustls-tls` feature is selected so that `cargo build` works
out of the box. If you wish to select `native-tls`, you may do so by running `cargo build --no-default-features --features native-tls`.

## Running tests

> [!IMPORTANT]
> You will need to have `jq` and `zstd` installed on your system in order to run tests. See [General dDependencies](#general-dependencies) for instructions on how to install these tools.
### Running Turborepo Tests
First, install Turborepo globally with your package manager of choice. For instance, with npm, `npm install -g turbo`. This will install the `turbo` binary in your system's `PATH`, making it globally available.

Install dependencies
Now, from the root directory, you can run:

On macOS:
- Unit tests

```bash
brew install jq zstd
cargo test
```

#### Turborepo Tests
- A module's unit tests

First: `npm install -g turbo`.

Then from the root directory, you can run:
```bash
cargo test -p <module>
```

- Go unit tests
```bash
pnpm test -- --filter=cli
```
- Rust unit tests ([install `nextest` first](https://nexte.st/book/pre-built-binaries.html))
```bash
cargo nextest run -p turborepo-lib --features rustls-tls
```
You can also use the built in [`cargo test`](https://doc.rust-lang.org/cargo/commands/cargo-test.html)
directly with `cargo test -p turborepo-lib`.
- CLI Integration tests
- Integration tests
```bash
pnpm test -- --filter=turborepo-tests-integration
```
- A single Integration test
e.g to run everything in `tests/run-summary`:
- A single integration test
e.g to run everything in `turborepo-tests/integration/tests/run-summary`:

```
# build first because the next command doesn't run through turbo
```bash
# Build `turbo` first because the next command doesn't run through `turbo`
pnpm -- turbo run build --filter=cli
pnpm test -F turborepo-tests-integration -- "run-summary"
```

Note: this is not through turbo, so you'll have to build turbo yourself first.

- Updating Integration Tests
- Updating integration tests

```
turbo run build --filter=cli
Expand All @@ -110,100 +108,115 @@ Then from the root directory, you can run:
pnpm --filter turborepo-tests-integration test:interactive tests/turbo-help.t
```

- Example tests
```bash
pnpm test -- --filter=turborepo-tests-examples -- <example-name> <packagemanager>
```
## Manually testing `turbo`

## Debugging Turborepo
After [building `turbo`](#building-turborepo), you can manually test `turbo` for the behaviors you're affecting with your changes. We recommend setting an alias to the built binary so you can call it with your alias.

1. Install `go install github.com/go-delve/delve/cmd/dlv@latest`
1. In VS Code's "Run and Debug" tab, select `Build Basic` to start debugging the initial launch of `turbo` against the
`build` target of the Basic Example. This task is configured in [launch.json](./.vscode/launch.json).
```bash
alias devturbo='~/projects/turbo/target/debug/turbo'
devturbo run build --skip-infer
```

## Benchmarking Turborepo
> [!IMPORTANT]
> The `--skip-infer` flag is required so that `turbo` doesn't try to use a locally installed binary of `turbo`. Forgetting to use this flag will cause `devturbo` to defer to the binary installed into the repository.
Follow the instructions in the [`benchmark/README.md`](./benchmark/README.md).
A non-exhaustive list of things to check on:

## Updating `turbo`
- Features related to your changes
- Test with and without daemon
- Installation scenarios
- Global only. `turbo` is installed as global binary without a local `turbo` in repository.
- Local only. `turbo` is installed as local binary without global `turbo` in PATH. turbo` is invoked via a root package
script.
- Global and local. `turbo` is installed as global binary, and local `turbo` in repository. Global `turbo` delegates to
local `turbo`

You might need to update `packages/turbo` in order to support a new platform. When you do that you will need to link the
module in order to be able to continue working. As an example, with `npm link`:
### Repositories to test with

```sh
cd ~/repos/vercel/turbo/packages/turbo
npm link
There are many open-source Turborepos out in the community that you can test with. A few are listed below:

# Run your build, e.g. `go build ./cmd/turbo` if you're on the platform you're adding.
cd ~/repos/vercel/turbo/cli
go build ./cmd/turbo
- [Next.js](https://github.com/vercel/next.js)
- [tldraw](https://github.com/tldraw/tldraw)
- [Tailwind CSS](https://github.com/tailwindlabs/tailwindcss)
- [Vercel CLI](https://github.com/vercel/vercel)
- This repository! Keep in mind that you'll be building and running `turbo` in the same repository, which can be confusing at times.

# You can then run the basic example specifying the build asset path.
cd ~/repos/vercel/turbo/examples/basic
TURBO_BINARY_PATH=~/repos/vercel/turbo/cli/turbo.exe npm install
TURBO_BINARY_PATH=~/repos/vercel/turbo/cli/turbo.exe npm link turbo
```
## Debugging tips

If you're using a different package manager replace npm accordingly.
### Verbose logging

## Manually testing `turbo`
Verbose logging can be enabled by using the `-v`, `-vv`, or `-vvv` flag on your `turbo` command, depending on the level of logging you're looking for.

Before releasing, it's recommended to test the `turbo` binary manually.
Here's a checklist of testing strategies to cover:
```bash
turbo build --vvv
```

- Test `login`, `logout`, `login --sso-team`, `link`, `unlink`
- Test `prune` (Note `turbo` here is the unreleased turbo binary)
- `pnpm dlx create-turbo@latest prune-test --package-manager pnpm && cd prune-test`
- `turbo --skip-infer prune docs && cd out && pnpm install --frozen-lockfile`
- `turbo --skip-infer build`
- Test `--dry-run` and `--graph`.
- Test with and without daemon.
### Crash logs

There are also multiple installation scenarios worth testing:
In the event of a crash, Rust's crash logs will be written to your temp directory. When `turbo` crashes, the location of the crash log will be printed to the console.

- Global-only. `turbo` is installed as global binary, no local `turbo` in repository.
- Local-only. `turbo` is installed as local binary, no global `turbo` in PATH. turbo` is invoked via a root package
script.
- Global + local. `turbo` is installed as global binary, and local `turbo` in repository. Global `turbo` delegates to
local `turbo`
### Terminal UI debugging

Here are a few repositories that you can test on:
The architecture of the Terminal UI makes for a tricky debugging experience. Because the UI writes to the console through `stdout` in a specific way, using `println!()` statements won't work as expected.

- [next.js](https://github.com/vercel/next.js)
- [tldraw](https://github.com/tldraw/tldraw)
- [tailwindcss](https://github.com/tailwindlabs/tailwindcss)
- [vercel](https://github.com/vercel/vercel)
Instead, use `eprintln!()` to print to `stdout` and output `stdout` to a file:

```bash
# devturbo is an alias to the debug binary of `turbo` in this case
devturbo run build --ui=tui --skip-infer 2&> ~/tmp/logs.txt
```

These lists are by no means exhaustive. Feel free to add to them with other strategies.
> [!IMPORTANT]
> The `--skip-infer` flag is required so that `turbo` doesn't try to use a locally installed binary of `turbo`. Forgetting to use this flag will cause `devturbo` to defer to the binary installed into the repository rather than the one you're developing.
## Publishing `turbo` to the npm registry

See [the publishing guide](./release.md#release-turborepo).
See [the publishing guide](./release.md).

## Creating a new release blog post
## Contributing to examples

Creating a new release post can be done via a turborepo generator. Run the following command from anywhere within the
repo:
Contributing to examples helps the Turborepo community by showcasing how to use Turborepo in real-world scenarios with other tools and frameworks. They can be found in [the examples directory](https://github.com/vercel/turborepo/tree/main/examples) of this repository.

```bash
turbo generate run "blog - release post"
```
The `basic` example is the default used by `create-turbo`.

This will walk you through creating a new blog post from start to finish.
For simplicity, each example is treated as a standalone "repository", separate from the rest of the repository, with its own dependencies, lockfile, `turbo` version, etc. You are able to run code and make code updates in an example without needing to install the dependencies of the rest of the repository.

NOTE: If you would like to update the stats (GitHub stars / npm downloads / time saved) for an existing blog post that
has yet to be published (useful if time has passed since the blog post was created, and up to date stats are required
before publishing) - run:
> [!NOTE]
> You may find that opening your code editor directly in the example's directory that you're working on can give you a better sense of how the example will feel to community members who download the example.
```bash
turbo generate run "blog - "blog - update release post stats"
```
### Contributing to an existing example

To contribute to an existing example, create your code updates and submit a pull request to the repository. No special steps are required to contribute to an example.

### Philosophy for new examples

and choose the blog post you would like to update.
Turborepo works with any framework, tool, or even language. Because of this, the community often expresses interest in creating new examples to showcase Turborepo working with other tooling.

## Troubleshooting
However, we aim to have as few examples in the repository while still showcasing Turborepo's flexibility. By having fewer examples, the core team has a better chance to maintain the collection of examples, keeping them at a higher quality. The ecosystem evolves quickly, and keeping every example up-to-date for every tool requires a wealth of attention. Our goal is to balance the needs of the core team and the community together to keep the Turboverse in a healthy state.

See [Troubleshooting][].
Due to these considerations, we ask that you first [open a Discussion](https://github.com/vercel/turborepo/discussions/categories/ideas) before working on a new example for the repository. It's best to make sure ahead of time that the example you'd like to propose will be accepted. Once you have received approval, you can work on and create a pull request for your example.

#### Designing a new example

Each example should have a specific focus when compared to the `basic` example. The goal is for an example to show how to use a singular, distinct technology's usage in a Turborepo.

You're encouraged to start with the [`basic` example](https://github.com/vercel/turborepo/tree/main/examples/basic) and add your specific tool of interest to it. Each example should have as few modifications to the `basic` example as possible required to showcase the tool or framework.

Key characteristics of a great example include:

- One technology added to the `basic` example
- An updated README at the root of the example directory. Make sure to include any steps required to run the example
- All tasks in `turbo.json` in the example run successfully without any code changes needed
- Works with every package manager listed in our [Support Policy](https://turbo.build/repo/docs/getting-started/support-policy#package-managers)

Once you've created your example (with prior approval, as discussed above), you can submit a pull request to the repository.

### Testing examples

To test out the experience of your example with `create-turbo`, run `create-turbo` with the `--example` flag pointed to a URL to your example's source code:

```
npx create-turbo@latest --example https://github.com/your-org/your-repo/tree/your-branch/...
```

[workspaces]: https://doc.rust-lang.org/book/ch14-03-cargo-workspaces.html
[troubleshooting]: troubleshooting.md
This will allow you to use the example as a uesr would.

0 comments on commit 6047d60

Please sign in to comment.