Split agent and contributor docs by project

This commit is contained in:
Rūdolfs Ošiņš
2026-10-22 11:06:33 +02:00
parent fd4436bb8f
commit 6c0ddd64dc
9 changed files with 264 additions and 401 deletions
-53
View File
@@ -1,53 +0,0 @@
---
name: radicle-ecosystem
description: Map of the sibling Radicle repositories that radicle-httpd depends on (heartwood, radicle-git, radicle-job, rips, radicle.dev), with the key crates and files to read in each. Use when working on Rust code in radicle-httpd, when you need protocol or domain context, or when a type comes from a crate outside this repo.
---
# Radicle ecosystem (sibling repos)
`radicle-httpd` depends on crates from sibling repositories. Read
source from these paths when working on Rust code.
## heartwood (`../heartwood`)
Core Radicle protocol implementation. Key crates used by httpd:
- `radicle` — standard library (storage, identity, COBs, git, node)
- `radicle-cob` — collaborative objects (issues, patches as CRDTs)
- `radicle-crypto` — Ed25519 signing, SSH key handling
- `radicle-core` — fundamental types (`RepoId`, etc.)
Key files:
- `../heartwood/HACKING.md` — development guide, environment variables
- `../heartwood/ARCHITECTURE.md` — high-level architecture
- `../heartwood/crates/radicle/src/lib.rs` — main library entry point
## radicle-git (`../radicle-git`)
Git library wrappers. Key crate:
- `radicle-surf` — code browsing (files, diffs, commits, branches,
tags). This is what httpd uses to serve repository content.
Key file: `../radicle-git/radicle-surf/src/lib.rs`
## radicle-job (`../radicle-job`)
Decentralized job execution (CI/CD) on the Radicle network.
Key file: `../radicle-job/README.md`
## RIPs — protocol specs (`../rips`)
- `../rips/0001-heartwood.md` — protocol overview
- `../rips/0002-identity.md` — identity system (DIDs, Ed25519)
- `../rips/0003-storage-layout.md` — git storage layout
## Radicle documentation (`../radicle.dev`)
Read these when you need domain context for UI work:
- `../radicle.dev/_guides/user.md` — end-to-end user workflows
(init, clone, seed, issues, patches, code review, private repos)
- `../radicle.dev/_guides/protocol.md` — protocol internals
(gossip, replication, identity documents, COB data model, trust)
- `../radicle.dev/_guides/seeder.md` — seed node operation
(seeding policies, httpd setup, DNS-SD)
- `../radicle.dev/_posts/2025-07-23-using-radicle-ci-for-development.md` — CI integration
- `../radicle.dev/_posts/2025-08-12-canonical-references.md` — canonical refs design
+100
View File
@@ -0,0 +1,100 @@
# radicle-gui
Monorepo for Radicle's graphical interfaces. It holds two independent
projects, each with its own npm package, Cargo workspace, toolchain files,
checks and conventions:
- **Explorer** (`explorer/`): the Svelte web app for browsing Radicle
repositories, its TypeScript HTTP client, and the `radicle-httpd` and
`radicle-search` backends it talks to. See `explorer/AGENTS.md`.
- **Desktop** (`desktop/`): the Tauri desktop app. See `desktop/AGENTS.md`.
This file covers what applies to both. Each project's `AGENTS.md` is the
source of truth for anything inside it.
## Layout
| Path | What it is |
|---|---|
| `explorer/` | Web app, HTTP client, `radicle-httpd` and `radicle-search` |
| `desktop/` | Tauri app: Svelte frontend in `src/`, Rust in `crates/` |
| `docs/adr/` | Decisions that affect the whole repository |
| `.github/workflows/` | GitHub CI: `explorer-*.yml` for explorer, `desktop-*.yml` for desktop |
| `.buildkite/` | Radicle CI pipelines (explorer only) |
| `.ryph/` | Dev machine image and setup for agents, see `.ryph/environment.md` |
## Working in this repo
- Work out which project a change belongs to first, and run every command
from that project's directory. There are no root `npm` or `cargo`
commands.
- A change that touches both projects is two changes: check each project
with its own commands.
- Explorer's components use legacy Svelte syntax (`$:`, stores,
`export let`), desktop's use Svelte 5 runes.
- Record a bigger architectural change as a new ADR, numbered after the last
one and in the same format: in `docs/adr/` if it affects the whole
repository, in the project's own `docs/adr/` otherwise.
- Before opening a patch or tagging a release, read `CONTRIBUTING.md` for
patch labels and release tags. Never create or match the old
`releases/<version>` tags; they predate the monorepo.
## Shared conventions
- Prefer `undefined` over `null`
- Do not add comments unless explicitly asked. When writing comments,
use proper English sentences
- Ask before adding new dependencies: each one is a supply-chain risk, and
installs are gated by `min-release-age` and `strict-allow-scripts`
- Use npm, never `yarn` or `pnpm`: the lockfiles and `.npmrc` settings are
npm's
- Run tests through the `npm run` scripts, not `npm test` (neither project
has one), `npx vitest` or `npx playwright test`: the scripts set `TZ=UTC`
and, in explorer, `NODE_CONFIG_ENV`, which the tests rely on
- Use ES private fields (`#field`), not the TypeScript `private` keyword
### Svelte components
- CSS: scoped styles with design tokens (`var(--color-text-primary)`,
`var(--txt-body-m-regular)`, `var(--border-radius-sm)`); use `:global()`
for styling slotted or `{@html}` content
- Loading states: `{#await promise}` blocks for inline async;
local `loading` boolean with `try/catch` for imperative fetches
## Commit messages
- Imperative mood: "Add feature" not "Added feature"
- Capitalize subject, no trailing period, about 50 chars
- Prefix commits that touch a single component with it: `explorer:`,
`httpd:` or `desktop:`, e.g. "desktop: Add release view". Commits that span
most of the repository have no prefix
- Each commit should be understandable, testable and revertable on its own
## Radicle ecosystem (sibling repos)
Both projects build on crates from sibling repositories, which may be
checked out next to this one. If present, read their source when a type
comes from outside this repo or you need protocol context:
- `../heartwood`: the protocol. Crates `radicle`, `radicle-cob`,
`radicle-crypto` and `radicle-core`. Start with `HACKING.md` and
`ARCHITECTURE.md`
- `../radicle-git`: `radicle-surf`, the code browsing (files, diffs, commits)
that httpd and desktop serve
- `../radicle-job`: CI job COBs
- `../rips`: protocol specs: `0001-heartwood.md`, `0002-identity.md`,
`0003-storage-layout.md`
- `../radicle.dev`: user docs. `_guides/user.md` covers workflows,
`_guides/protocol.md` covers gossip, replication and the COB model, and
`_guides/seeder.md` covers seed nodes and httpd setup
## Domain glossary
- **RID** — Repository ID (`rad:z3gqc...`)
- **DID** — Decentralized Identifier, user identity (`did:key:z6Mk...`)
- **NID** — Node ID, the public key in a DID
- **COB** — Collaborative Object (issue, patch, or identity as a Git DAG)
- **Delegate** — authorized repo maintainer; signatures determine canonical state
- **Patch** — pull-request equivalent with immutable revisions and reviews
- **Seed** — hosting/replicating a repo; seed nodes are always-on servers
- **Canonical refs** — branches/tags resolved by delegate quorum
+109
View File
@@ -0,0 +1,109 @@
# Contributing
This repository holds two projects, each with its own development guide:
`explorer/README.md` and `desktop/README.md`. This file covers what
applies to both.
* Before adding any code dependencies, check with the maintainers if this is okay.
* Write properly formatted comments: they should be english sentences, eg:
// Return the current UNIX time.
* Follow the guidelines when proposing code changes (see below).
* Write properly formatted git commits (see below).
## Proposing changes
When proposing changes via a patch:
* Isolate changes in separate commits to make the review process easier.
* Don't make unrelated changes, unless it happens to be an obvious improvement to
code you are touching anyway ("boyscout rule").
* Rebase on `master` when needed.
* Keep your changesets small, specific and uncontroversial, so that they can be
merged more quickly.
* If the change is substantial or requires re-architecting certain parts of the
codebase, write an ADR first, in `docs/adr/` if it affects the whole
repository or in the project's own `docs/adr/` otherwise, and get consensus
on that before proposing the code changes.
## Writing Git commit messages
A properly formed git commit subject line should always be able to complete the
following sentence:
If applied, this commit will _____
For example, the following message is well formed:
Add support for .gif files
In addition, it should be capitalized and *must not* include a period. Prefix
commits that touch a single component with it: `explorer:` for the web app,
`httpd:` for `radicle-httpd` and `radicle-search`, and `desktop:` for the
desktop app. Commits that span most of the repository have no prefix. Either
way, each commit should be understandable, testable and revertable as one
coherent change.
When it comes to formatting, here's a model git commit message[1]:
Capitalized, short (50 chars or less) summary
More detailed explanatory text, if necessary. Wrap it to about 72
characters or so. In some contexts, the first line is treated as the
subject of an email and the rest of the text as the body. The blank
line separating the summary from the body is critical (unless you omit
the body entirely); tools like rebase can get confused if you run the
two together.
Write your commit message in the imperative: "Fix bug" and not "Fixed bug"
or "Fixes bug." This convention matches up with commit messages generated
by commands like git merge and git revert.
Further paragraphs come after blank lines.
- Bullet points are okay, too.
- Typically a hyphen or asterisk is used for the bullet, followed by a
single space, with blank lines in between, but conventions vary here.
- Use a hanging indent.
[1]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
## Patch labels
Label every new patch with each component it touches, so reviewers and
filters can tell the projects apart:
| Label | Covers |
|---|---|
| `explorer` | the web app in `explorer/`: `src/`, `http-client/`, `workers/`, its tests and config |
| `desktop` | anything under `desktop/` |
| `httpd` | `explorer/crates/radicle-httpd/` and `explorer/crates/radicle-search/` |
A patch that touches several components gets several labels. Changes to
shared files (`.github/`, `.buildkite/`, `.ryph/`, root docs) get the labels
of the components they affect. `git push` can't set labels, so add them
once the patch is open:
```sh
rad patch label <patch-id> --add explorer --add httpd
```
## Releases and tags
Each project is released on its own. Release tags are
`releases/<component>/<version>`; the `refs/tags/releases/*` rule in the
repository's identity decides when they become canonical.
| Component | How it's released | Tag |
|---|---|---|
| Explorer web app | Deployed continuously, no releases or tags | — |
| `radicle-httpd` + `radicle-search` | Together, one version, see `explorer/RELEASE.md` | `releases/httpd/<version>` |
| Desktop app | `desktop/scripts/release`, see `desktop/README.md` | `releases/desktop/<version>` |
The older `releases/<version>` tags (httpd 0.22.0–0.29.0, desktop
0.9.0–0.16.0) are left over from before the two repositories were merged.
Never create, match or describe against them; scripts must always match a
component's own prefix.
+4 -38
View File
@@ -6,14 +6,12 @@ structs using ts-rs (`crates/radicle-types/`).
The app lives in `desktop/` of the radicle-gui monorepo. It is its own npm
package and Cargo workspace: run every command here from `desktop/`, and all
paths in this file are relative to it. The repository root holds the Radicle
web explorer, which has its own `CLAUDE.md`. Release tags are
`releases/desktop/<version>`.
paths in this file are relative to it. Conventions shared with explorer
are in the root `AGENTS.md`.
## Tech stack
## Svelte syntax and aliases
- Svelte 5 with runes syntax (`$state`, `$derived`, `$props`, `$effect`)
- TypeScript, Vite, Vitest, Playwright
- Path aliases: `@app` (src), `@bindings` (crates/radicle-types/bindings), `@tests`
## Commands
@@ -21,7 +19,7 @@ web explorer, which has its own `CLAUDE.md`. Release tags are
### Development
```sh
npm run tauri dev # full Tauri dev build with hot reload
npm run dev # full Tauri dev build with hot reload and devtools
npm run start:http # test-http-api backend on :8081 (no Tauri runtime)
npm start # Vite dev server; in a browser it talks to test-http-api
```
@@ -145,37 +143,16 @@ Ports have full default implementations, so a driver only implements
a domain `Service` backed by the SQLite adapter instead of the ports; new
lists over large data sets should do the same.
## Domain glossary
- **NID** — Node ID, the public key in a DID (`did:key:z6Mk...`)
- **COB** — Collaborative Object (issue, patch, or identity as a Git DAG)
- **Delegate** — authorized repo maintainer; signatures determine canonical state
- **Seed** — hosting/replicating a repo; seed nodes are always-on servers
- **Canonical refs** — branches/tags resolved by delegate quorum
## Code conventions
- Prefer `undefined` over `null`
- Do not add comments unless explicitly asked. When writing comments,
use proper English sentences
- Ask before adding new dependencies
- When proposing a bigger architectural change, record it as a new ADR in
`docs/adr/`, numbered after the last one and in the same format
### Svelte components
- Props use `$props()`: `const { foo, bar = undefined }: Props = $props()`
- CSS: scoped styles with design tokens (`var(--color-text-primary)`,
`var(--txt-body-m-regular)`, `var(--border-radius-sm)`); use `:global()`
for styling slotted or `{@html}` content
- Loading states: `{#await promise}` blocks for inline async;
local `loading` boolean with `try/catch` for imperative fetches
### TypeScript
- Import backend types from `@bindings/*` — these are generated by ts-rs, never
hand-write interfaces that duplicate them
- Use ES private fields (`#field`), not the TypeScript `private` keyword
- Call Tauri commands via `invoke<T>("command_name", { arg })` from `@app/lib/invoke`
### Rust backend
@@ -188,14 +165,3 @@ lists over large data sets should do the same.
- `rust-toolchain.toml` tracks heartwood's. When bumping the `radicle` crate,
check heartwood's toolchain too: an older rustc fails inside the dependency
with a confusing error (e.g. E0382 in `cob/identity.rs` for radicle 0.25)
## Commit messages
- Imperative mood: "Add feature" not "Added feature"
- Capitalize subject, no trailing period, max 50 chars
## Do NOT
- Do not use `npm test` — no default test script exists
- Do not use `yarn` or `pnpm` — use npm
- Do not use `npx vitest` or `npx playwright test` — use the `npm run` scripts
+21 -158
View File
@@ -1,145 +1,28 @@
# radicle-gui
# radicle-explorer
Monorepo for Radicle's graphical interfaces. It holds two independent
projects, each with its own npm package, Cargo workspace, toolchain files,
checks and conventions:
The Svelte web app for browsing Radicle repositories, its TypeScript HTTP
client, and the `radicle-httpd` and `radicle-search` backends it talks to.
- **Explorer** (repository root): the Svelte web app for browsing Radicle
repositories, its TypeScript HTTP client, and the `radicle-httpd` and
`radicle-search` backends it talks to.
- **Desktop** (`desktop/`): the Tauri desktop app. Its own `desktop/CLAUDE.md`
is the source of truth for anything under `desktop/`.
The project lives in `explorer/` of the radicle-gui monorepo. It is its own
npm package and Cargo workspace: run every command here from `explorer/`,
and all paths in this file are relative to it. Conventions shared with
desktop are in the root `AGENTS.md`.
## Layout
| Path | Project | What it is |
|---|---|---|
| `src/`, `public/`, `tests/` | explorer | Svelte web app and its unit, e2e and visual tests |
| `http-client/` | explorer | TypeScript client for the httpd API |
| `crates/radicle-httpd/` | explorer | HTTP daemon serving the API (Rust), with its own `CLAUDE.md` for code conventions |
| `crates/radicle-search/` | explorer | Search service, released together with httpd (Rust) |
| `workers/` | explorer | Cloudflare workers (open-graph images) |
| `scripts/` | explorer | Check, CI and e2e helper scripts |
| `desktop/` | desktop | Tauri app: Svelte frontend in `desktop/src/`, Rust in `desktop/crates/` |
| `.github/workflows/` | both | GitHub CI: `explorer-*.yml` for explorer, `desktop-*.yml` for desktop |
| `.buildkite/` | explorer | Radicle CI pipelines |
| `.ryph/` | both | Dev machine image and setup for agents, see `.ryph/environment.md` |
## Working in this repo
- Work out which project a change belongs to first, and run every command
from that project's root: the repository root for explorer, `desktop/`
for desktop. Root `npm` and `cargo` commands never cover `desktop/`, and
the root lint and format checks skip it on purpose.
- The two projects don't share code. A change that touches both is two
changes: check each project with its own commands.
- The rules under "Explorer" below don't apply in `desktop/`. In particular,
explorer uses legacy Svelte syntax while desktop uses Svelte 5 runes.
### Plan mode
- Propose the minimal MVP first — no tests, no docs, no speculative extras
- Tests are added only when explicitly requested after MVP review
- Keep plans concise: short bullet points listing what changes and where
- Skip obvious details and boilerplate explanations
### Shared conventions
- Prefer `undefined` over `null`
- Do not add comments unless explicitly asked. When writing comments,
use proper English sentences
- Ask before adding new dependencies
- Use npm, never `yarn` or `pnpm`
- Do not use `npm test` — neither project has a default test script
- Do not use `npx vitest` or `npx playwright test` — use the `npm run` scripts
### Commit messages
- Imperative mood: "Add feature" not "Added feature"
- Capitalize subject, no trailing period, max 50 chars
- Prefix backend-only commits with `httpd:`
### Patches
Label every new patch with each component it touches, so reviewers and
filters can tell the projects apart:
| Label | Covers |
|---|---|
| `explorer` | the web app at the root: `src/`, `http-client/`, `workers/`, its tests and config |
| `desktop` | anything under `desktop/` |
| `httpd` | `crates/radicle-httpd/` and `crates/radicle-search/` |
A patch that touches several components gets several labels. Changes to
shared files (`.github/`, `.buildkite/`, `.ryph/`, root docs) get the labels
of the components they affect. `git push` can't set labels, so add them
once the patch is open:
```sh
rad patch label <patch-id> --add explorer --add httpd
```
### Releases and tags
Each project is released on its own. Release tags are
`releases/<component>/<version>`; the `refs/tags/releases/*` rule in the
repository's identity decides when they become canonical.
| Component | How it's released | Tag |
|---|---|---|
| Explorer web app | Deployed continuously, no releases or tags | — |
| `radicle-httpd` + `radicle-search` | Together, one version, see `RELEASE.md` | `releases/httpd/<version>` |
| Desktop app | `desktop/scripts/release`, see `desktop/README.md` | `releases/desktop/<version>` |
The older `releases/<version>` tags (httpd 0.22.0–0.29.0, desktop
0.9.0–0.16.0) are left over from before the two repositories were merged.
Never create, match or describe against them; scripts must always match a
component's own prefix.
### Radicle ecosystem (sibling repos)
See the `radicle-ecosystem` skill for the map of sibling repositories
(heartwood, radicle-git, radicle-job, rips, radicle.dev) and the key
crates and files in each.
### Domain glossary
- **RID** — Repository ID (`rad:z3gqc...`)
- **DID** — Decentralized Identifier, user identity (`did:key:z6Mk...`)
- **NID** — Node ID, public key suffix of a DID
- **COB** — Collaborative Object (issue, patch, or identity as a Git DAG)
- **Delegate** — authorized repo maintainer; signatures determine canonical state
- **Patch** — pull-request equivalent with immutable revisions and reviews
- **Seed** — hosting/replicating a repo; seed nodes are always-on servers
- **Canonical refs** — branches/tags resolved by delegate quorum
## Explorer (repository root)
Everything in this section applies to the repository root only. Run all
commands from there.
### Tech stack
- Svelte 5 with legacy syntax (`$:`, stores, `export let`). Do not use
Svelte 5 runes (`$state`, `$derived`, `$props`) here
- TypeScript, Vite, Vitest, Playwright, Zod
- Rust for `crates/radicle-httpd` and `crates/radicle-search`
### Checks and linting (tsc, svelte-check, eslint, prettier)
## Checks and linting (tsc, svelte-check, eslint, prettier)
```sh
npm run check
npm run format # auto-fix prettier issues
```
### Unit tests
## Unit tests
```sh
npm run test:unit
npm run test:http-client:unit
```
### E2E tests
## E2E tests
```sh
npm run test:e2e -- --project chromium
@@ -155,7 +38,7 @@ or test fixtures requires a full run.
SKIP_SETUP=true npm run test:e2e -- --project chromium
```
### Rust backend (`crates/`)
## Rust backend (`crates/`)
The same commands CI runs:
@@ -176,7 +59,7 @@ npm run test:e2e:local -- --project chromium
npm run test:http-client:unit:local
```
### API changes across layers
## API changes across layers
Adding or changing an API endpoint typically touches three layers:
1. `crates/radicle-httpd/` — Rust handler (add route, types, logic)
@@ -188,49 +71,29 @@ or remove fields/endpoints unless explicitly deprecating. The frontend
must handle older nodes gracefully: treat new API fields as optional
and fall back when they're absent.
### Pre-push checklist
## Pre-push checklist
`npm run check:ci` runs everything below except the `:local` variants, plus
the build smoke test, from the GitHub workflows, and stops at the first
failure. It logs each step's output, duration and exit code to
`tests/tmp/check-ci.log`.
`npm run check:ci` runs the checks, unit, http-client, e2e and build smoke
tests from the GitHub workflows, and stops at the first failure. It logs
each step's output, duration and exit code to `tests/tmp/check-ci.log`. If
Rust code changed, also run the Rust commands and the `:local` variants
above.
1. `npm run check`
2. `npm run test:unit`
3. `npm run test:http-client:unit`
4. `npm run test:e2e -- --project chromium`
5. If Rust code changed: clippy, fmt, cargo test (see above),
plus `:local` variants of e2e and http-client tests
## Svelte components
### Svelte components
- Script order (enforced by prettier): `<script context="module">`,
`<script lang="ts">`, `<style>`, markup
- Optional props use `export let foo: T = undefined`, not `?:`
- CSS: scoped styles with design tokens (`var(--color-text-primary)`,
`var(--txt-body-m-regular)`, `var(--border-radius-sm)`); use `:global()`
for styling slotted or `{@html}` content
- Loading states: `{#await promise}` blocks for inline async;
local `loading` boolean with `try/catch` for imperative fetches
### `{@html}` and untrusted data (XSS)
## `{@html}` and untrusted data (XSS)
- Avoid `{@html}` with backend-derived data (branch/ref names, aliases,
descriptions); when unavoidable, its argument must be DOMPurify-sanitized
(`sanitizeConfig` in `src/lib/markdown.ts`) or built from `escape()`'d
parts, in the component that renders it.
### TypeScript / HTTP client
## TypeScript / HTTP client
- Derive types from Zod schemas (`z.infer<typeof fooSchema>`), never
hand-write interfaces that duplicate a schema
- Schema naming: `fooSchema` (camelCase + Schema suffix) → type `Foo`
- Use ES private fields (`#field`), not the TypeScript `private` keyword
- API timestamps are in seconds; multiply by 1000 for JS `Date`
- Relative imports inside `http-client/` use `.js` extension (ESM)
## Desktop (`desktop/`)
See `desktop/CLAUDE.md`. In short: Tauri with a Svelte 5 frontend that uses
runes, a hexagonal Rust backend in `desktop/crates/`, and its own checks
(`npm run check:ci` from `desktop/`).
-145
View File
@@ -1,145 +0,0 @@
# CONTRIBUTING
Contributions are very welcome. When contributing code, please follow these
simple guidelines.
* Make sure you run `npm run check` for code formatting problems.
* Run our test suite `npm run test:*` to avoid regressions or bugs.
* Before adding any code dependencies, check with the maintainers if this is okay.
* Write properly formatted comments: they should be english sentences, eg:
// Return the current UNIX time.
* Follow the guidelines when proposing code changes (see below).
* Write properly formatted git commits (see below).
Running Tests
-------------
The test suite includes end-to-end (e2e) tests that run against the built
application.
**Basic usage:**
npm run test:e2e
**Skipping setup:**
The test suite performs setup operations before running tests:
* Building the application bundle
* Creating test fixtures (repositories with test data)
On subsequent test runs, you can skip this setup to save time:
SKIP_SETUP=true npm run test:e2e
Use this when:
* You haven't changed any source code since the last test run
* The test fixtures are already created
* You want to iterate quickly on test development
**Note:** If you've made code changes or are getting unexpected test failures,
remove the `SKIP_SETUP` flag to ensure tests run against the latest build.
**Common usage patterns:**
* First time run: `npm run test:e2e -- --project chromium`
* Subsequent runs (no code changes): `SKIP_SETUP=true npm run test:e2e -- --project chromium`
* Single test by line number: `SKIP_SETUP=true npm run test:e2e -- tests/e2e/repo/commits.spec.ts:90 --project chromium`
**Testing with local radicle-httpd build:**
If you're developing radicle-httpd and want to test changes locally:
npm run test:e2e:local
This will:
1. Compile radicle-httpd from the `radicle-httpd/` directory
2. Run the full test suite against the locally compiled binary
**Running e2e tests in Docker:**
If your host OS isn't supported by Playwright's browser builds (e.g. a very
new or unusual Linux distribution), run the suite inside a container instead.
Requires Docker with the Compose plugin.
scripts/test-e2e-docker
Any arguments are forwarded to `npm run test:e2e` (defaulting to
`--project chromium` when none are given):
scripts/test-e2e-docker tests/e2e/repo.spec.ts
scripts/test-e2e-docker --project chromium -g "some test name"
`SKIP_SETUP=true` is forwarded the same as for the native runner:
SKIP_SETUP=true scripts/test-e2e-docker
To test against a radicle-httpd you compile from source (the equivalent of
`npm run test:e2e:local`), pass `--local`:
scripts/test-e2e-docker --local
Notes:
* The first image build is slow (it downloads Chromium); subsequent runs are
cached. `--local` additionally installs a Rust toolchain and compiles
radicle-httpd on first use.
* The repo is bind-mounted, so test artifacts and the binary/fixture cache
land on the host as usual. `node_modules`, the cargo cache, and httpd's
build directory live in container-private volumes, leaving your host copies
untouched.
Proposing changes
-----------------
When proposing changes via a patch:
* Isolate changes in separate commits to make the review process easier.
* Don't make unrelated changes, unless it happens to be an obvious improvement to
code you are touching anyway ("boyscout rule").
* Rebase on `master` when needed.
* Keep your changesets small, specific and uncontroversial, so that they can be
merged more quickly.
* If the change is substantial or requires re-architecting certain parts of the
codebase, write a proposal in english first, and get consensus on that before
proposing the code changes.
Writing Git commit messages
---------------------------
A properly formed git commit subject line should always be able to complete the
following sentence:
If applied, this commit will _____
For example, the following message is well formed:
Add support for .gif files
In addition, it should be capitalized and *must not* include a period.
When it comes to formatting, here's a model git commit message[1]:
Capitalized, short (50 chars or less) summary
More detailed explanatory text, if necessary. Wrap it to about 72
characters or so. In some contexts, the first line is treated as the
subject of an email and the rest of the text as the body. The blank
line separating the summary from the body is critical (unless you omit
the body entirely); tools like rebase can get confused if you run the
two together.
Write your commit message in the imperative: "Fix bug" and not "Fixed bug"
or "Fixes bug." This convention matches up with commit messages generated
by commands like git merge and git revert.
Further paragraphs come after blank lines.
- Bullet points are okay, too.
- Typically a hyphen or asterisk is used for the bullet, followed by a
single space, with blank lines in between, but conventions vary here.
- Use a hanging indent.
---
[1]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
+28 -5
View File
@@ -188,12 +188,35 @@ git clone https://seed.example.com/heartwood.git
```
## Development
Run `npm run check` before proposing a patch, along with the test suites:
`npm run test:unit`, `npm run test:http-client:unit` and `npm run test:e2e`.
E2E tests build the app and create fixtures before running. If neither the
source nor the fixtures changed since the last run, skip that with
`SKIP_SETUP=true`:
```sh
npm run test:e2e -- --project chromium
SKIP_SETUP=true npm run test:e2e -- tests/e2e/repo/commits.spec.ts:90 --project chromium
```
When changing `radicle-httpd`, `npm run test:e2e:local` compiles it from
`crates/radicle-httpd/` and runs the suite against that build instead of
the released binary.
If Playwright's browsers don't support your OS, `scripts/test-e2e-docker`
runs the suite in a container (Docker with the Compose plugin). It forwards
its arguments and `SKIP_SETUP` to `npm run test:e2e`, and `--local` tests
against httpd built from source. The first run downloads Chromium and is
slow.
## Contributing
* For detailed contribution guidelines, refer to the [CONTRIBUTING.md][con]
file
* To propose changes, open an [issue][iss] or submit a [patch][pat] using
Radicle
See [CONTRIBUTING.md][con] for how to propose changes and write commit
messages. Open an [issue][iss] or a [patch][pat] using Radicle.
## Getting in touch
@@ -209,7 +232,7 @@ The UI is distributed under the terms of GPLv3. See [LICENSE][lic] for details.
[app]: https://radicle.network
[con]: ./CONTRIBUTING.md
[con]: ../CONTRIBUTING.md
[def]: ./config/default.json
[env]: ./config/custom-environment-variables.json
[iss]: https://radicle.network/nodes/iris.radicle.network/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5/issues
+1 -1
View File
@@ -1,7 +1,7 @@
# radicle-httpd
Rust backend for the Radicle web explorer, released together with
`radicle-search` (see `RELEASE.md` at the repository root).
`radicle-search` (see `RELEASE.md` in `explorer/`).
## Code conventions
+1 -1
View File
@@ -72,7 +72,7 @@ export default async function globalSetup(): Promise<() => void> {
// Evaluated once at startup; captured by async setup operations.
// Set SKIP_SETUP=true to skip both build and fixture creation on subsequent runs.
// See CONTRIBUTING.md for details.
// See README.md for details.
const shouldSetup = !process.env.SKIP_SETUP;
if (shouldSetup) {