Skip to content

Latest commit

 

History

History
117 lines (76 loc) · 5.13 KB

File metadata and controls

117 lines (76 loc) · 5.13 KB

Contributing to Utopia

中文

Welcome. This file covers what is specific to this repository; general open-source etiquette is assumed.

Branches and how changes land

Branch What it is
main Stable, matches the released version. Only maintainers merge into it, from dev
dev Integration branch. Every contribution lands here first

Your path as a contributor:

git switch dev && git pull
git switch -c fix/some-thing        # branch off dev, not main
# make changes, commit with -s (see DCO below)
git push -u origin fix/some-thing

Then open a PR with base dev, not main. A maintainer merges once CI and review pass.

Merging dev → main is done by maintainers on their own schedule; contributors don't need to think about it. Two rules keep the two branches from drifting apart, and both are for maintainers:

  • Back-merge main into dev right after a release. The dev → main merge commit lives only on main, so without this main reads as ahead even though the trees are identical, and the gap grows by one every release.
  • Urgent fixes go through dev too. A PR opened straight against main is the one thing that makes the two branches genuinely diverge, and then someone has to reconcile them by hand.

Both branches are protected: pull request required, CI (backend and web) must pass, no force pushes, no deletions, and admins are held to the same rules.

Issue first, or straight to a PR

Change What to do
Bug fixes, docs, i18n strings, tests Open a PR directly
New features, dependency changes Open an issue first and describe the use case
Data model, ontology contract, public API Discuss in an issue, then land an ADR before writing code

docs/decisions/ is where this project's reasoning lives. An ADR records why this and not that, including the approaches that were tried and failed. For a change of any size, that document outlives the code.

Local setup

Requires Docker, Rust 1.85+, Node 20+, pnpm.

docker compose up -d db                 # Postgres with pgvector
cargo run -p utopia-server              # runs migrations, :1516
cd web && pnpm install && pnpm dev      # :5173, proxies /api to the backend

Before you push

CI runs exactly this. Green locally means green in CI:

cargo fmt --all --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
cd web && pnpm install --frozen-lockfile && pnpm build   # build type-checks

Database-backed tests skip without the env var

This is the easiest thing to get wrong here. A green cargo test --workspace does not mean everything ran. A number of tests begin like this:

let Ok(url) = std::env::var("UTOPIA_DATABASE_URL") else {
    eprintln!("skipping: UTOPIA_DATABASE_URL not set");
    return Ok(());
};

They guard what the compiler cannot see: table aliases inside SQL strings, how NULL behaves in a comparison, rows an INNER JOIN silently drops, whether a recursive CTE expands the same ancestor twice under diamond inheritance. cargo check and clippy say nothing about any of it.

If you touched SQL under crates/utopia-store/, set it and run again:

export UTOPIA_DATABASE_URL=postgres://utopia:utopia@localhost:5432/utopia
cargo test --workspace

Things review will send back

Don't collide migration numbers. migrations/ rolls forward by number. Check the latest number on main before opening a PR — two branches each writing an 0011_ has happened, and after the merge neither one runs.

UI strings go in i18n. Add to both web/src/i18n/en.ts and zh.ts; no hard-coded strings in components.

Comments explain why. This repository comments densely and deliberately records the traps it fell into ("the first version used OR, and the Elon Musk article then produced a snapshot every 6KB"). Follow that. A comment restating what the code does will be asked to go.

Commit messages: one English sentence, stating the motivation. No long body. Skim git log for the register.

Every workflow declares its own permissions:. The repository default is now read-and-write, because one workflow commits a generated chart. A workflow without a permissions: block inherits that default, so leaving it out silently hands write access to something that only needed to read. Declare the minimum the job actually needs — contents: read for anything that just builds or tests.

DCO: sign off every commit

We use the DCO, not a CLA. You keep the copyright on your code; you are certifying that you have the right to submit it under Apache-2.0.

Commit with -s and git adds the line for you:

git commit -s -m "Fix the thing"

which appends:

Signed-off-by: Your Name <your@email>

Forgot? git commit --amend -s for the last commit, or git rebase --signoff HEAD~3 for several (adjust the count), then git push -f.

Use a real name and a reachable email address.

License

By contributing you agree that your work is released under Apache-2.0.