docs: refresh contributing & building guides, surface CLA signing flow (#15503)

This commit is contained in:
donqu1xotevincent
2026-08-21 08:15:26 +08:00
committed by GitHub
parent 73e2d10973
commit 3feb17cde3
5 changed files with 213 additions and 47 deletions
+153 -41
View File
@@ -1,68 +1,83 @@
# Building AFFiNE Web
> **Warning**:
>
> **Warning**
> This document is not guaranteed to be up-to-date.
> If you find any outdated information, please feel free to open an issue or submit a PR.
>
> **Note**
> For developing & building desktop client app, please refer to [building-desktop-client-app.md](./building-desktop-client-app.md)
> This guide covers building and developing the **web app**.
> For the desktop client app, see [building-desktop-client-app.md](./building-desktop-client-app.md).
> For running the server (cloud features) locally, see [developing-server.md](./developing-server.md).
## Table of Contents
- [Sign the CLA first](#sign-the-cla-first)
- [Prerequisites](#prerequisites)
- [Setup Environment](#setup-environment)
- [Start Development Server](#start-development-server)
- [Testing](#testing)
- [Linting and Type Checking](#linting-and-type-checking)
- [Submitting a Pull Request](#submitting-a-pull-request)
- [Troubleshooting](#troubleshooting)
- [Related Documents](#related-documents)
## Sign the CLA first
AFFiNE requires every contributor to sign the [Contributor License Agreement](../.github/CLA.md) before a pull request can be **merged**. The `license/cla` status check on your PR stays red — and blocks the merge — until every committer on the PR has signed. Signing takes less than a minute, so do it before (or right after) opening your first PR:
1. Open **<https://cla-assistant.io/toeverything/AFFiNE>**.
2. Sign in with your GitHub account and agree.
If you opened your PR before signing, the CLA-assistant bot will have left a comment on it with a signing link. After signing, click the **recheck** link in that same comment (or push a new commit) to refresh the check.
If `license/cla` is still red after you signed:
- **Every committer must sign.** The bot's comment lists each commit author in the PR — every name marked with :x: still needs to sign, including co-authors.
- **Your commit email must be linked to your GitHub account.** CLA assistant matches commits to GitHub users by the commit author email. Run `git log --format='%an %ae'` and make sure those emails appear in your [GitHub email settings](https://github.com/settings/emails). Otherwise, either add the email to GitHub, or rewrite the commits with the correct identity and force-push.
## Prerequisites
AFFiNE client has both **Node.js** & **Rust** toolchains.
### Install Node.js
### Node.js
We suggest develop our product under node.js LTS(Long-term support) version
Develop with the Node.js version pinned in [`.nvmrc`](../.nvmrc) (currently Node.js **22**; `package.json` requires `>=22.12.0 <23.0.0`).
#### Option 1: Manually install node.js
install [Node LTS version](https://nodejs.org/en/download)
> Up to now, the major node.js version is 20.x
#### Option 2: Use node version manager
install [fnm](https://github.com/Schniz/fnm)
The easiest way is a version manager that reads `.nvmrc`:
```sh
fnm use
# with fnm (https://github.com/Schniz/fnm)
fnm use --install-if-missing
# or with nvm (https://github.com/nvm-sh/nvm)
nvm install && nvm use
```
### Install Rust Tools
Alternatively, install Node.js 22 (LTS) manually from <https://nodejs.org/en/download>.
Please follow the official guide at https://www.rust-lang.org/tools/install.
### Yarn
### Setup Node.js Environment
This setup requires modern yarn (currently `4.x`), run this if your yarn version is `1.x`
Reference: [Yarn installation doc](https://yarnpkg.com/getting-started/install)
We use modern Yarn (currently **4.x**, pinned by the `packageManager` field in `package.json`). Yarn 1 will not work. Enable it via [Corepack](https://yarnpkg.com/corepack), which ships with Node.js:
```sh
corepack enable
corepack prepare yarn@stable --activate
```
```sh
# install dependencies
yarn install
```
After this, `yarn` inside the repository automatically resolves to the pinned version — verify with `yarn -v` (it should print `4.x`, not `1.x`).
### Clone repository
### Rust
#### Linux & MacOS
Install the Rust toolchain via [rustup](https://rustup.rs/). The required version is pinned in [`rust-toolchain.toml`](../rust-toolchain.toml), and rustup installs it automatically the first time you build inside the repository.
## Setup Environment
### Clone the repository
#### Linux & macOS
```sh
git clone https://github.com/toeverything/AFFiNE
cd AFFiNE
```
#### Windows
@@ -80,30 +95,55 @@ git config --global core.symlinks true
git clone https://github.com/toeverything/AFFiNE
```
### Install dependencies
```sh
yarn install
```
This also initializes the workspace (`yarn affine init`) and installs the git hooks through the `postinstall` script.
### Build Native Dependencies
Run the following script. It will build the native module at [`/packages/frontend/native`](/packages/frontend/native) and build Node.js binding using [NAPI.rs](https://napi.rs/).
This could take a while if you build it for the first time.
Note: use `strip` from system instead of `binutils` if you are running MacOS. [see problem here](https://github.com/toeverything/AFFiNE/discussions/2840)
Run the following script. It will build the native module at [`packages/frontend/native`](../packages/frontend/native) and build Node.js binding using [NAPI.rs](https://napi.rs/). This could take a while if you build it for the first time.
```sh
yarn affine @affine/native build
```
> Note: use `strip` from system instead of `binutils` if you are running macOS. [See problem here](https://github.com/toeverything/AFFiNE/discussions/2840)
### Build Server Dependencies
Only needed if you plan to run the local server (cloud features) or the cloud E2E suites:
```sh
yarn affine @affine/server-native build
```
## Start Development Server
```sh
yarn dev
```
You will be prompted to choose which package to run — pick **`@affine/web`** for the web app, then open **<http://localhost:8080>**.
You can skip the prompt with the `-p` (`--package`) flag:
```sh
yarn dev -p @affine/web
```
Other dev targets include `@affine/server`, `@affine/electron`, `@affine/mobile`, `@affine/admin`, `@affine/ios` and `@affine/android`.
Running `@affine/web` alone is enough for most editor and UI work — workspaces are stored locally in the browser. To work on **cloud** features (accounts, sync, collaboration, AI), run the local server as well: follow [developing-server.md](./developing-server.md).
## Testing
Adding test cases is strongly encouraged when you contribute new features and bug fixes.
We use [Playwright](https://playwright.dev/) for E2E test, and [vitest](https://vitest.dev/) for unit test.
To test locally, please make sure browser binaries are already installed via `npx playwright install`.
Start server before tests by following [`docs/developing-server.md`](./developing-server.md) first.
We use [Vitest](https://vitest.dev/) for unit tests and [Playwright](https://playwright.dev/) for E2E tests.
### Unit Test
@@ -113,8 +153,80 @@ yarn test
### E2E Test
```shell
# there are `affine-local`, `affine-migration`, `affine-local`, `affine-prototype` e2e tests,
# which are run under different situations.
yarn workspace @affine-test/affine-local e2e
Install the browser binaries once before the first run:
```sh
npx playwright install
```
The E2E suites live in [`tests`](../tests):
| Suite | Run with | Notes |
| ---------------------- | ------------------------------------------------------ | --------------------------------------------------- |
| `affine-local` | `yarn workspace @affine-test/affine-local e2e` | Web app, no server needed |
| `affine-cloud` | `yarn workspace @affine-test/affine-cloud e2e` | Requires the [local server](./developing-server.md) |
| `affine-cloud-copilot` | `yarn workspace @affine-test/affine-cloud-copilot e2e` | Requires the local server |
| `affine-desktop` | `yarn workspace @affine-test/affine-desktop e2e` | Desktop (Electron) app |
| `affine-desktop-cloud` | `yarn workspace @affine-test/affine-desktop-cloud e2e` | Desktop + local server |
| `affine-mobile` | `yarn workspace @affine-test/affine-mobile e2e` | Mobile UI |
There is also `@affine-test/blocksuite` (`yarn workspace @affine-test/blocksuite test`) for BlockSuite integration tests.
## Linting and Type Checking
CI runs these checks on every PR — running them locally first saves you a review round trip:
```sh
# lint (oxlint) + format check (oxfmt)
yarn lint
# auto-fix lint & format issues
yarn lint:fix
# TypeScript type check
yarn typecheck
```
## Submitting a Pull Request
1. Make sure you have [signed the CLA](#sign-the-cla-first).
2. Fork the repository and create your branch from **`canary`** (the default development branch).
3. Make your changes. Add or update tests where it makes sense, and run `yarn lint`, `yarn typecheck` and the relevant test suites locally.
4. Open the PR against the `canary` branch of `toeverything/AFFiNE`.
5. Give the PR a title that follows [Conventional Commits](https://www.conventionalcommits.org/) — this is enforced by the `PR Title Lint` CI check:
```text
type(scope): short description
# examples
fix(editor): keep text selection after paste
feat(core): add custom icons for folders
docs: update building guide
```
- **Types**: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert`
- **Scopes** (optional; if present, must be one of): `admin`, `electron`, `server`, `core`, `web`, `mobile`, `ios`, `android`, `mobile-native`, `docs`, `component`, `env`, `graphql`, `hooks`, `i18n`, `native`, `templates`, `debug`, `nbstore`, `infra`, `editor`, `tools`, `y-octo`, `client`
6. Your PR can be merged once:
- the **`license/cla`** check is green — every committer has signed the CLA;
- CI passes — build & tests, PR title lint;
- a maintainer has reviewed and approved it. Reviewers are assigned automatically, and an automated reviewer may also leave comments — please address or answer them.
## Troubleshooting
- **`yarn install` fails or complains about the Node/Yarn version** — check that `node -v` matches [`.nvmrc`](../.nvmrc) (`fnm use` / `nvm use`) and that Corepack is enabled (`yarn -v` should print `4.x`, not `1.x`).
- **Native module fails to build on macOS** — make sure `strip` is the system one, not the one from `binutils` ([details](https://github.com/toeverything/AFFiNE/discussions/2840)).
- **`EPERM: operation not permitted, symlink` on Windows** — enable Developer Mode and symlinks before cloning; see [Windows](#windows).
- **App fails to start after pulling the latest `canary`** — dependencies or Rust bindings may have changed: re-run `yarn install` and `yarn affine @affine/native build`.
- **Playwright can't find browsers** — run `npx playwright install`.
- **The `license/cla` check stays red** — see [Sign the CLA first](#sign-the-cla-first).
## Related Documents
- [developing-server.md](./developing-server.md) — run the AFFiNE server locally (cloud features)
- [building-desktop-client-app.md](./building-desktop-client-app.md) — build the desktop (Electron) client
- [contributing/tutorial.md](./contributing/tutorial.md) — a walkthrough of the codebase
- [types-of-contributions.md](./types-of-contributions.md) — ways to contribute beyond code
- [issue-triaging.md](./issue-triaging.md) — how issues are triaged
- [contributing/releases.md](./contributing/releases.md) — how releases are cut
- [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md)