diff --git a/.github/CLA.md b/.github/CLA.md index 530146a257..c319e6ce05 100644 --- a/.github/CLA.md +++ b/.github/CLA.md @@ -1,4 +1,4 @@ - + # AFFiNE Contributor License Agreement @@ -35,4 +35,6 @@ You accept and agree to the following terms and conditions for your past, presen ## How To Sign -Visit https://cla-assistant.io/toeverything/AFFiNE and sign it. +Visit ****, sign in with your GitHub account, and agree. + +Once signed, the `license/cla` check on your pull requests passes automatically. If you signed after opening a PR, click the **recheck** link in the CLA bot's comment on the PR (or push a new commit) to refresh the check. Note that every committer on a PR must sign, and each commit's author email must be linked to a GitHub account. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..9e2fca9e25 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,18 @@ + + +## Description + + + +## Checklist + +- [ ] I have signed the [AFFiNE Contributor License Agreement](https://cla-assistant.io/toeverything/AFFiNE) — required before merge; the `license/cla` check must be green ([how it works](https://github.com/toeverything/AFFiNE/blob/canary/docs/BUILDING.md#sign-the-cla-first)) +- [ ] The PR targets the `canary` branch and its title follows [Conventional Commits](https://www.conventionalcommits.org/) +- [ ] Tests are added or updated where it makes sense +- [ ] `yarn lint` and `yarn typecheck` pass locally diff --git a/README.md b/README.md index c1a5f037e8..537c3615ba 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ Thanks for checking us out, we appreciate your interest and sincerely hope that Calling all developers, testers, tech writers and more! Contributions of all types are more than welcome, you can read more in [docs/types-of-contributions.md](docs/types-of-contributions.md). If you are interested in contributing code, read our [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md) and feel free to check out our GitHub issues to get stuck in to show us what you’re made of. -**Before you start contributing, please make sure you have read and accepted our [Contributor License Agreement]. To indicate your agreement, simply edit this file and submit a pull request.** +**Before you start contributing, please sign our [Contributor License Agreement] — it takes less than a minute with your GitHub account. Pull requests cannot be merged until every committer has signed (the `license/cla` check on your PR). Full text: [CLA.md](.github/CLA.md).** For **bug reports**, **feature requests** and other **suggestions** you can also [create a new issue](https://github.com/toeverything/AFFiNE/issues/new/choose) and choose the most appropriate template for your feedback. @@ -216,10 +216,9 @@ See [LICENSE] for details. [update page]: https://affine.pro/blog?tag=Release%20Note [jobs available]: ./docs/jobs.md [latest packages]: https://github.com/toeverything/AFFiNE/pkgs/container/affine-self-hosted -[contributor license agreement]: https://github.com/toeverything/affine/edit/canary/.github/CLA.md +[contributor license agreement]: https://cla-assistant.io/toeverything/AFFiNE [stars-icon]: https://img.shields.io/github/stars/toeverything/AFFiNE.svg?style=flat&logo=github&colorB=red&label=stars [codecov]: https://codecov.io/gh/toeverything/affine/branch/canary/graphs/badge.svg?branch=canary -[node-version-icon]: https://img.shields.io/badge/node-%3E=18.16.1-success [typescript-version-icon]: https://img.shields.io/github/package-json/dependency-version/toeverything/affine/dev/typescript [react-version-icon]: https://img.shields.io/github/package-json/dependency-version/toeverything/AFFiNE/react?filename=packages%2Ffrontend%2Fcore%2Fpackage.json&color=rgb(97%2C228%2C251) [blocksuite-icon]: https://img.shields.io/github/package-json/dependency-version/toeverything/AFFiNE/@blocksuite/store?color=6880ff&filename=packages%2Ffrontend%2Fcore%2Fpackage.json&label=blocksuite diff --git a/docs/BUILDING.md b/docs/BUILDING.md index 9d72a88e62..f0deb79923 100644 --- a/docs/BUILDING.md +++ b/docs/BUILDING.md @@ -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 ****. +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 . -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 ****. + +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) diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index d0d1c9c07e..1549db21ee 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -1 +1,36 @@ -# Please visit https://docs.affine.pro/contributing +# Contributing to AFFiNE + +Thank you for your interest in contributing! ❤️ AFFiNE welcomes contributions of all kinds — code, docs, bug reports, feature ideas and translations. See [types-of-contributions.md](./types-of-contributions.md) for the full picture. + +This page is the five-minute overview. The full contributor handbook lives at . + +## Before your first pull request: sign the CLA + +We can only merge pull requests whose authors have signed the [Contributor License Agreement](../.github/CLA.md). Every PR is checked automatically (the `license/cla` status check), and an unsigned CLA is the single most common reason PRs get stuck before merge. + +**How to sign (takes under a minute):** + +1. Open . +2. Sign in with your GitHub account and agree. + +Already opened a PR? Sign, then click the **recheck** link in the CLA bot's comment on your PR (or push a new commit). Note that **every** committer on the PR must sign, and each commit's author email must be [linked to a GitHub account](https://github.com/settings/emails). See [BUILDING.md — Sign the CLA first](./BUILDING.md#sign-the-cla-first) for troubleshooting. + +## Contribution flow + +1. **Find something to work on.** Browse [good first issues](https://github.com/toeverything/AFFiNE/contribute) or the [issue tracker](https://github.com/toeverything/AFFiNE/issues). Issues that are still in triage haven't been reviewed yet — better not to start work on those. For bigger changes, open a [discussion](https://github.com/toeverything/AFFiNE/discussions) or talk to us on [Discord](https://affine.pro/redirect/discord) first. +2. **Set up your environment.** Follow [BUILDING.md](./BUILDING.md) for the web app. For the server (cloud features) see [developing-server.md](./developing-server.md); for the desktop client see [building-desktop-client-app.md](./building-desktop-client-app.md). +3. **Make your change** on a branch created from `canary`. Add tests where it makes sense, and run `yarn lint`, `yarn typecheck` and the relevant tests locally. +4. **Open a PR to `canary`** with a [Conventional Commits](https://www.conventionalcommits.org/) title, e.g. `fix(editor): keep selection after paste` — the title format is enforced by CI. +5. **Get it merged.** A PR merges once the `license/cla` check is green, CI passes, and a maintainer approves the review. + +## Code of conduct + +Please read our [Code of Conduct](./CODE_OF_CONDUCT.md). + +## Useful links + +- Codebase tour: [contributing/tutorial.md](./contributing/tutorial.md) +- How issues are triaged: [issue-triaging.md](./issue-triaging.md) +- Release process: [contributing/releases.md](./contributing/releases.md) +- Reporting security issues: [SECURITY.md](../SECURITY.md) +- Community: [Discord](https://affine.pro/redirect/discord) · [GitHub Discussions](https://github.com/toeverything/AFFiNE/discussions)