mirror of
https://seed.radicle.dev/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5.git
synced 2026-11-12 05:50:35 +08:00
explorer: run prettier format
This commit is contained in:
+24
-24
@@ -3,10 +3,10 @@
|
||||
The Svelte web app for browsing Radicle repositories, its TypeScript HTTP
|
||||
client, and the `radicle-httpd` and `radicle-search` backends it talks to.
|
||||
|
||||
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`.
|
||||
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`.
|
||||
|
||||
## Checks and linting (tsc, svelte-check, eslint, prettier)
|
||||
|
||||
@@ -29,10 +29,10 @@ npm run test:e2e -- --project chromium
|
||||
npm run test:e2e -- tests/e2e/<file>.spec.ts --project chromium
|
||||
```
|
||||
|
||||
`SKIP_SETUP=true` skips fixture creation for faster iteration.
|
||||
Only use it when you are solely editing `.spec.ts` files and fixtures
|
||||
already exist from a previous full run. Any change to app code, httpd,
|
||||
or test fixtures requires a full run.
|
||||
`SKIP_SETUP=true` skips fixture creation for faster iteration. Only use it when
|
||||
you are solely editing `.spec.ts` files and fixtures already exist from a
|
||||
previous full run. Any change to app code, httpd, or test fixtures requires a
|
||||
full run.
|
||||
|
||||
```sh
|
||||
SKIP_SETUP=true npm run test:e2e -- --project chromium
|
||||
@@ -50,9 +50,9 @@ cargo test --workspace --all-features
|
||||
cargo test -p radicle-httpd
|
||||
```
|
||||
|
||||
E2E and http-client tests run against a stable pre-built httpd by
|
||||
default. When changing `crates/radicle-httpd/`, also test against the
|
||||
local build and run both to verify backwards compatibility:
|
||||
E2E and http-client tests run against a stable pre-built httpd by default. When
|
||||
changing `crates/radicle-httpd/`, also test against the local build and run both
|
||||
to verify backwards compatibility:
|
||||
|
||||
```sh
|
||||
npm run test:e2e:local -- --project chromium
|
||||
@@ -62,22 +62,22 @@ npm run test:http-client:unit:local
|
||||
## API changes across layers
|
||||
|
||||
Adding or changing an API endpoint typically touches three layers:
|
||||
|
||||
1. `crates/radicle-httpd/` — Rust handler (add route, types, logic)
|
||||
2. `http-client/` — TypeScript client (add fetch function, types)
|
||||
3. `src/` — Svelte UI (consume the new data)
|
||||
|
||||
**Backwards compatibility:** Only add to the backend API — never rename
|
||||
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.
|
||||
**Backwards compatibility:** Only add to the backend API — never rename 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
|
||||
|
||||
`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.
|
||||
`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.
|
||||
|
||||
## Svelte components
|
||||
|
||||
@@ -87,13 +87,13 @@ above.
|
||||
|
||||
- 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.
|
||||
(`sanitizeConfig` in `src/lib/markdown.ts`) or built from `escape()`'d parts,
|
||||
in the component that renders it.
|
||||
|
||||
## TypeScript / HTTP client
|
||||
|
||||
- Derive types from Zod schemas (`z.infer<typeof fooSchema>`), never
|
||||
hand-write interfaces that duplicate a schema
|
||||
- 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`
|
||||
- API timestamps are in seconds; multiply by 1000 for JS `Date`
|
||||
- Relative imports inside `http-client/` use `.js` extension (ESM)
|
||||
|
||||
+69
-26
@@ -2,54 +2,97 @@
|
||||
|
||||
## radicle-httpd + radicle-search 0.30.0
|
||||
|
||||
- **`tar.zst` archive downloads**: `/raw/{rid}/archive/{ref}.tar.zst` joins the tar, tar.gz and zip formats; it needs the `zstd` binary in `PATH`
|
||||
- **Archive ref errors**: Unknown refs now return 404 and malformed ones 400, instead of 500
|
||||
- **Runtime log format**: `RADICLE_HTTPD_LOG_FORMAT` selects `text` (default) or `json` logs at startup, with the access log emitted as structured fields in JSON; this replaces the `logfmt` build feature
|
||||
- **Batched search reindexing**: radicle-search ignores seed events and reindexes each touched repo once per batch (`RADICLE_SEARCH_BATCH_SECS`, default 30s), so a flapping peer no longer pins meilisearch at 100% CPU
|
||||
- Updated `rustls-webpki` and `webpki-roots` to clear advisories reported by `cargo audit`
|
||||
- **`tar.zst` archive downloads**: `/raw/{rid}/archive/{ref}.tar.zst` joins the
|
||||
tar, tar.gz and zip formats; it needs the `zstd` binary in `PATH`
|
||||
- **Archive ref errors**: Unknown refs now return 404 and malformed ones 400,
|
||||
instead of 500
|
||||
- **Runtime log format**: `RADICLE_HTTPD_LOG_FORMAT` selects `text` (default) or
|
||||
`json` logs at startup, with the access log emitted as structured fields in
|
||||
JSON; this replaces the `logfmt` build feature
|
||||
- **Batched search reindexing**: radicle-search ignores seed events and
|
||||
reindexes each touched repo once per batch (`RADICLE_SEARCH_BATCH_SECS`,
|
||||
default 30s), so a flapping peer no longer pins meilisearch at 100% CPU
|
||||
- Updated `rustls-webpki` and `webpki-roots` to clear advisories reported by
|
||||
`cargo audit`
|
||||
|
||||
## radicle-httpd + radicle-search 0.29.0
|
||||
|
||||
- **Complete commit lists for merge-commit diffs**: The diff endpoint no longer stops the walk early when the head merges the target branch in, which reduced such patches to a single commit
|
||||
- **Complete commit lists for merge-commit diffs**: The diff endpoint no longer
|
||||
stops the walk early when the head merges the target branch in, which reduced
|
||||
such patches to a single commit
|
||||
|
||||
## radicle-httpd + radicle-search 0.28.0
|
||||
|
||||
- **Releases API**: New `/repos/{rid}/releases` endpoints serve radicle-artifact release COBs, with Releases and Release views in the UI that degrade gracefully on older nodes
|
||||
- **`Git-Protocol` header passed through**: Git HTTP routes forward the header to `git-http-backend`, fixing clients that require Git wire protocol version 2
|
||||
- Updated `chacha20`, `h2` and `lru` to clear advisories reported by `cargo audit`
|
||||
- **Releases API**: New `/repos/{rid}/releases` endpoints serve radicle-artifact
|
||||
release COBs, with Releases and Release views in the UI that degrade
|
||||
gracefully on older nodes
|
||||
- **`Git-Protocol` header passed through**: Git HTTP routes forward the header
|
||||
to `git-http-backend`, fixing clients that require Git wire protocol version 2
|
||||
- Updated `chacha20`, `h2` and `lru` to clear advisories reported by
|
||||
`cargo audit`
|
||||
|
||||
## radicle-httpd + radicle-search 0.27.0
|
||||
|
||||
- **Commit-count endpoint**: New `/repos/{rid}/stats/commits/{sha}` counts reachable commits from the commit-graph, avoiding the full history walk of `/stats/tree`
|
||||
- **Diff-stats endpoint**: New `/repos/{rid}/diff/{base}/{oid}/stats` returns line counts without building hunks, 6–15x faster than `/diff`; it skips rename detection, so counts can differ slightly on renamed or copied files
|
||||
- **Faster file browsing**: Blob requests no longer walk the whole history to find a file's last commit, which took seconds to minutes on large repositories
|
||||
- **Repository reads off the async workers**: Synchronous libgit2 and COB reads run on the blocking pool, so one slow read no longer stalls queued requests
|
||||
- **Repo aliases in the JSON and raw APIs**: `--alias` path segments resolve there too, not just on the git routes, and the repo endpoint exposes an optional `alias` field
|
||||
- **Higher open-file limit**: Raised at startup, fixing spurious "missing object" errors in storage with thousands of packfiles
|
||||
- **Commit-count endpoint**: New `/repos/{rid}/stats/commits/{sha}` counts
|
||||
reachable commits from the commit-graph, avoiding the full history walk of
|
||||
`/stats/tree`
|
||||
- **Diff-stats endpoint**: New `/repos/{rid}/diff/{base}/{oid}/stats` returns
|
||||
line counts without building hunks, 6–15x faster than `/diff`; it skips rename
|
||||
detection, so counts can differ slightly on renamed or copied files
|
||||
- **Faster file browsing**: Blob requests no longer walk the whole history to
|
||||
find a file's last commit, which took seconds to minutes on large repositories
|
||||
- **Repository reads off the async workers**: Synchronous libgit2 and COB reads
|
||||
run on the blocking pool, so one slow read no longer stalls queued requests
|
||||
- **Repo aliases in the JSON and raw APIs**: `--alias` path segments resolve
|
||||
there too, not just on the git routes, and the repo endpoint exposes an
|
||||
optional `alias` field
|
||||
- **Higher open-file limit**: Raised at startup, fixing spurious "missing
|
||||
object" errors in storage with thousands of packfiles
|
||||
- **Empty job COBs excluded**: Job listings omit jobs with no runs
|
||||
- **`RUST_LOG` in the default logger**: Honoured without the `logfmt` feature, defaulting to `info`
|
||||
- **`RUST_LOG` in the default logger**: Honoured without the `logfmt` feature,
|
||||
defaulting to `info`
|
||||
- Updated radicle crates, cargo dependencies and the Rust toolchain (1.97.1)
|
||||
|
||||
## radicle-httpd + radicle-search 0.26.0
|
||||
|
||||
- **Repository search**: New optional `radicle-search` indexing daemon backs a `/repos/search?q=…` endpoint for typo-tolerant search over repo names and descriptions, plus faster `/repos?sort=activity|seeding` listings; httpd falls back to its built-in storage walk when the daemon is absent, so existing behavior is unchanged
|
||||
- **Git archive downloads**: Additional formats ZIP and TAR are now supported. Also, a prefix is added to the archive by default, which can be disabled by using the query `?prefix=false`. This query string is immediately deprecated. It only exists as a workaround for users to adapt their download scripts etc. to accommodate for the prefix. It will be removed in a future version.
|
||||
- **Streaming archive downloads**: Archives are streamed to the client instead of being buffered in memory, avoiding excessive memory use on large repositories
|
||||
- **Faster archive HEAD requests**: `HEAD` requests no longer build an archive that is then discarded
|
||||
- **Streaming git operations**: Clone, fetch, and push stream request and response bodies and accept gzip-compressed requests, reducing memory use on large operations
|
||||
- **Repository search**: New optional `radicle-search` indexing daemon backs a
|
||||
`/repos/search?q=…` endpoint for typo-tolerant search over repo names and
|
||||
descriptions, plus faster `/repos?sort=activity|seeding` listings; httpd falls
|
||||
back to its built-in storage walk when the daemon is absent, so existing
|
||||
behavior is unchanged
|
||||
- **Git archive downloads**: Additional formats ZIP and TAR are now supported.
|
||||
Also, a prefix is added to the archive by default, which can be disabled by
|
||||
using the query `?prefix=false`. This query string is immediately deprecated.
|
||||
It only exists as a workaround for users to adapt their download scripts etc.
|
||||
to accommodate for the prefix. It will be removed in a future version.
|
||||
- **Streaming archive downloads**: Archives are streamed to the client instead
|
||||
of being buffered in memory, avoiding excessive memory use on large
|
||||
repositories
|
||||
- **Faster archive HEAD requests**: `HEAD` requests no longer build an archive
|
||||
that is then discarded
|
||||
- **Streaming git operations**: Clone, fetch, and push stream request and
|
||||
response bodies and accept gzip-compressed requests, reducing memory use on
|
||||
large operations
|
||||
|
||||
## radicle-httpd 0.25.0
|
||||
|
||||
- **Canonical and peer refs in repo API**: The repo endpoint now exposes canonical refs and per-peer refs, letting clients discover branches and tags resolved by delegate quorum as well as those from individual nodes
|
||||
- **Job COBs endpoint**: New `/repos/{rid}/jobs/{sha}` endpoint serves job collaborative objects, enabling clients to query CI/CD job state
|
||||
- **Canonical and peer refs in repo API**: The repo endpoint now exposes
|
||||
canonical refs and per-peer refs, letting clients discover branches and tags
|
||||
resolved by delegate quorum as well as those from individual nodes
|
||||
- **Job COBs endpoint**: New `/repos/{rid}/jobs/{sha}` endpoint serves job
|
||||
collaborative objects, enabling clients to query CI/CD job state
|
||||
|
||||
## radicle-httpd 0.24.0
|
||||
|
||||
- **Windows support**: The HTTP daemon now runs on Windows with platform-specific adaptations
|
||||
- **Windows support**: The HTTP daemon now runs on Windows with
|
||||
platform-specific adaptations
|
||||
- **Faster API responses**: Improved `/node` endpoint performance
|
||||
- **Git namespace paths**: Direct access to node ref namespaces via `/{rid}.git/{nid}/` remote URLs, simplifying clones and fetches from specific nodes
|
||||
- **Git namespace paths**: Direct access to node ref namespaces via
|
||||
`/{rid}.git/{nid}/` remote URLs, simplifying clones and fetches from specific
|
||||
nodes
|
||||
- Updated dependencies and internal improvements
|
||||
|
||||
## radicle-httpd 0.23.0
|
||||
|
||||
- **Live config reload**: Update configuration without restarting by sending a SIGHUP signal
|
||||
- **Live config reload**: Update configuration without restarting by sending a
|
||||
SIGHUP signal
|
||||
|
||||
+55
-65
@@ -9,20 +9,20 @@ It lives in the `explorer/` folder of the radicle-gui repository, next to the
|
||||
|
||||
**Deployment Options:**
|
||||
|
||||
* **Public Server:** The Radicle team maintains a public instance at [radicle.network][app]
|
||||
* **Local-first:** Run the UI locally
|
||||
* **Self-hosting:** Deploy the UI on your own server
|
||||
|
||||
- **Public Server:** The Radicle team maintains a public instance at
|
||||
[radicle.network][app]
|
||||
- **Local-first:** Run the UI locally
|
||||
- **Self-hosting:** Deploy the UI on your own server
|
||||
|
||||
## Local-first
|
||||
|
||||
**Prerequisites:**
|
||||
|
||||
* Recent versions of [Node.js][nod] (24 or higher) and [npm][npm] installed
|
||||
- Recent versions of [Node.js][nod] (24 or higher) and [npm][npm] installed
|
||||
|
||||
Run the following commands to access the web UI locally:
|
||||
|
||||
``` shell
|
||||
```shell
|
||||
git clone https://seed.radicle.dev/z4V1sjrXqjvFdnCUbxPFqd5p4DtH5.git radicle-gui
|
||||
cd radicle-gui/explorer
|
||||
npm install
|
||||
@@ -31,7 +31,6 @@ npm start
|
||||
|
||||
Then open http://localhost:3000 in your favourite browser.
|
||||
|
||||
|
||||
## Self-Hosting the UI
|
||||
|
||||
There are several ways to deploy the UI publicly. Here are two common options:
|
||||
@@ -68,8 +67,8 @@ There are two ways to configure the UI: **at build time** and **at run time**.
|
||||
|
||||
### Build-Time Configuration
|
||||
|
||||
This method is recommended when deploying to static hosting platforms such
|
||||
as Vercel.
|
||||
This method is recommended when deploying to static hosting platforms such as
|
||||
Vercel.
|
||||
|
||||
#### Option 1: Create a `local.json` file
|
||||
|
||||
@@ -86,7 +85,6 @@ as Vercel.
|
||||
> For advanced configuration options, refer to the [`node-config`][nco]
|
||||
> documentation.
|
||||
|
||||
|
||||
### Run-Time Configuration
|
||||
|
||||
This method is useful when the app is distributed as a precompiled static
|
||||
@@ -105,42 +103,40 @@ VITE_RUNTIME_CONFIG=true npm run build
|
||||
This will inject a blocking script into the `index.html` that attempts to load
|
||||
the configuration from a pre-defined location (`/config.json`) on the server.
|
||||
|
||||
The config file must be served as static content and must be publicly accessible.
|
||||
The structure of the runtime `config.json` must match the shape of the
|
||||
application's base configuration defined in `config/default.json`.
|
||||
|
||||
The config file must be served as static content and must be publicly
|
||||
accessible. The structure of the runtime `config.json` must match the shape of
|
||||
the application's base configuration defined in `config/default.json`.
|
||||
|
||||
### Homepage
|
||||
|
||||
The `nodes.homepage` key controls what is rendered at the root URL (`/`):
|
||||
|
||||
* `"node"` (default) — show the node view of the user's primary seed
|
||||
directly, as if the user had navigated to `/nodes/<your-node>`. The
|
||||
primary seed is resolved from `preferredSeeds` (see [`default.json`][def]).
|
||||
This is the default so that a self-hosted deployment acts as a dedicated
|
||||
front-end for its own seed.
|
||||
* `"landing"` — serve the full Radicle marketing site: the landing page and
|
||||
its `/learn`, `/install` and documentation (`/glossary`, `/guides/*`)
|
||||
sub-routes. This is opt-in and intended for the canonical
|
||||
[radicle.network][app] deployment; the marketing sub-routes are only
|
||||
reachable in this mode.
|
||||
- `"node"` (default) — show the node view of the user's primary seed directly,
|
||||
as if the user had navigated to `/nodes/<your-node>`. The primary seed is
|
||||
resolved from `preferredSeeds` (see [`default.json`][def]). This is the
|
||||
default so that a self-hosted deployment acts as a dedicated front-end for its
|
||||
own seed.
|
||||
- `"landing"` — serve the full Radicle marketing site: the landing page and its
|
||||
`/learn`, `/install` and documentation (`/glossary`, `/guides/*`) sub-routes.
|
||||
This is opt-in and intended for the canonical [radicle.network][app]
|
||||
deployment; the marketing sub-routes are only reachable in this mode.
|
||||
|
||||
The cross-seed Explore page is always available at `/explore`, regardless of
|
||||
the `homepage` setting.
|
||||
The cross-seed Explore page is always available at `/explore`, regardless of the
|
||||
`homepage` setting.
|
||||
|
||||
#### radicle.network deployment
|
||||
|
||||
`default.json` keeps `homepage` set to `"node"`, so self-hosted deployments
|
||||
are unaffected. The canonical radicle.network deployment opts into the
|
||||
marketing site at **build time** without changing that default. To deploy
|
||||
radicle.network, run `npm run deploy`.
|
||||
`default.json` keeps `homepage` set to `"node"`, so self-hosted deployments are
|
||||
unaffected. The canonical radicle.network deployment opts into the marketing
|
||||
site at **build time** without changing that default. To deploy radicle.network,
|
||||
run `npm run deploy`.
|
||||
|
||||
#### Node-homepage deployment
|
||||
|
||||
If you operate your own seed node and want the explorer to act as a
|
||||
dedicated front-end for it (the default behaviour), put your own node first
|
||||
(and ideally as the only entry) in `preferredSeeds` so it is always picked
|
||||
as the primary seed.
|
||||
If you operate your own seed node and want the explorer to act as a dedicated
|
||||
front-end for it (the default behaviour), put your own node first (and ideally
|
||||
as the only entry) in `preferredSeeds` so it is always picked as the primary
|
||||
seed.
|
||||
|
||||
Example `local.json`:
|
||||
|
||||
@@ -156,26 +152,25 @@ Example `local.json`:
|
||||
}
|
||||
```
|
||||
|
||||
With this configuration, opening `/` lands the visitor on the node view
|
||||
for `seed.example.com`. Keeping `preferredSeeds` to a single entry
|
||||
ensures the primary seed is deterministic; if you list multiple, users
|
||||
are bucketed across them and may land on a different node.
|
||||
|
||||
With this configuration, opening `/` lands the visitor on the node view for
|
||||
`seed.example.com`. Keeping `preferredSeeds` to a single entry ensures the
|
||||
primary seed is deterministic; if you list multiple, users are bucketed across
|
||||
them and may land on a different node.
|
||||
|
||||
## Repository aliases
|
||||
|
||||
`radicle-httpd` can map a short, human-readable alias to a repository ID
|
||||
(RID), so a repository can be referred to by name instead of its full
|
||||
`rad:` identifier. Aliases are configured on the node with the
|
||||
`--alias <name> <rid>` flag, which may be repeated:
|
||||
`radicle-httpd` can map a short, human-readable alias to a repository ID (RID),
|
||||
so a repository can be referred to by name instead of its full `rad:`
|
||||
identifier. Aliases are configured on the node with the `--alias <name> <rid>`
|
||||
flag, which may be repeated:
|
||||
|
||||
```sh
|
||||
radicle-httpd --alias heartwood rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5
|
||||
```
|
||||
|
||||
An alias works anywhere the RID is accepted: `git clone`, the HTTP API, the
|
||||
raw endpoints, and Explorer URLs — the router resolves it transparently.
|
||||
With the alias above, these two Explorer URLs point at the same repository:
|
||||
An alias works anywhere the RID is accepted: `git clone`, the HTTP API, the raw
|
||||
endpoints, and Explorer URLs — the router resolves it transparently. With the
|
||||
alias above, these two Explorer URLs point at the same repository:
|
||||
|
||||
```
|
||||
https://radicle.network/nodes/seed.example.com/rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5/issues
|
||||
@@ -188,7 +183,6 @@ and the repository can be cloned over Git by its alias:
|
||||
git clone https://seed.example.com/heartwood.git
|
||||
```
|
||||
|
||||
|
||||
## Development
|
||||
|
||||
Run `npm run check` before proposing a patch, along with the test suites:
|
||||
@@ -204,44 +198,40 @@ SKIP_SETUP=true npm run test:e2e -- tests/e2e/repo/commits.spec.ts:90 --project
|
||||
```
|
||||
|
||||
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.
|
||||
`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
|
||||
|
||||
See [CONTRIBUTING.md][con] for how to propose changes and write commit
|
||||
messages. Open an [issue][iss] or 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
|
||||
|
||||
To get in touch with the maintainers, sign up to our
|
||||
[official chat on Zulip][zul].
|
||||
|
||||
To get in touch with the maintainers, sign up to our [official chat on
|
||||
Zulip][zul].
|
||||
|
||||
## License
|
||||
|
||||
The UI is distributed under the terms of GPLv3. See [LICENSE][lic] for details.
|
||||
|
||||
|
||||
|
||||
[app]: https://radicle.network
|
||||
[con]: ../CONTRIBUTING.md
|
||||
[def]: ./config/default.json
|
||||
[env]: ./config/custom-environment-variables.json
|
||||
[iss]: https://radicle.network/nodes/iris.radicle.network/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5/issues
|
||||
[iss]:
|
||||
https://radicle.network/nodes/iris.radicle.network/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5/issues
|
||||
[lic]: ./LICENSE
|
||||
[nco]: https://github.com/node-config/node-config/wiki/Configuration-Files
|
||||
[nod]: https://nodejs.org
|
||||
[npm]: https://www.npmjs.com
|
||||
[pat]: https://radicle.network/nodes/iris.radicle.network/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5/patches
|
||||
[pat]:
|
||||
https://radicle.network/nodes/iris.radicle.network/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5/patches
|
||||
[rad]: https://radicle.dev
|
||||
[try]: https://caddyserver.com/docs/caddyfile/patterns#single-page-apps-spas
|
||||
[zul]: https://radicle.zulipchat.com/#narrow/stream/369278-web
|
||||
|
||||
+25
-11
@@ -3,10 +3,10 @@
|
||||
`radicle-httpd` and `radicle-search` are released **together** from this
|
||||
workspace: a single tag, a single changelog, and one build run that produces
|
||||
artifacts for both binaries. They share the same version number, bumped in
|
||||
lockstep. On [files.radicle.dev][files] each binary gets its own release
|
||||
folder — `releases/radicle-httpd/<version>/` and, as a sibling,
|
||||
`releases/radicle-search/<version>/` — so existing `radicle-httpd` download
|
||||
URLs are unaffected and `radicle-search` is downloaded independently.
|
||||
lockstep. On [files.radicle.dev][files] each binary gets its own release folder
|
||||
— `releases/radicle-httpd/<version>/` and, as a sibling,
|
||||
`releases/radicle-search/<version>/` — so existing `radicle-httpd` download URLs
|
||||
are unaffected and `radicle-search` is downloaded independently.
|
||||
|
||||
The release tooling lives in [`crates/radicle-httpd/build/`][build].
|
||||
|
||||
@@ -14,8 +14,8 @@ The release tooling lives in [`crates/radicle-httpd/build/`][build].
|
||||
|
||||
Releases cover **only** the `radicle-httpd` and `radicle-search` binaries. The
|
||||
web front-end (`radicle-explorer`) is not released this way: it is deployed
|
||||
continuously (rolling release) and must always remain compatible with the
|
||||
latest `radicle-httpd`/`radicle-search` release.
|
||||
continuously (rolling release) and must always remain compatible with the latest
|
||||
`radicle-httpd`/`radicle-search` release.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@@ -30,6 +30,7 @@ latest `radicle-httpd`/`radicle-search` release.
|
||||
## Prepare Release
|
||||
|
||||
1. Create release branch:
|
||||
|
||||
```sh
|
||||
git checkout -b release/httpd/<version>
|
||||
```
|
||||
@@ -40,12 +41,14 @@ latest `radicle-httpd`/`radicle-search` release.
|
||||
- `crates/radicle-search/Cargo.toml`
|
||||
|
||||
3. Update lockfiles:
|
||||
|
||||
```sh
|
||||
cargo build
|
||||
```
|
||||
|
||||
4. Generate changelog (the version is read from
|
||||
`crates/radicle-httpd/Cargo.toml`):
|
||||
|
||||
```sh
|
||||
crates/radicle-httpd/build/changelog >> CHANGELOG.md
|
||||
```
|
||||
@@ -54,6 +57,7 @@ latest `radicle-httpd`/`radicle-search` release.
|
||||
change belongs to `radicle-httpd` or `radicle-search`.
|
||||
|
||||
6. Commit release:
|
||||
|
||||
```sh
|
||||
git commit -m "Release <version>"
|
||||
```
|
||||
@@ -71,13 +75,15 @@ latest `radicle-httpd`/`radicle-search` release.
|
||||
## Tag Release
|
||||
|
||||
Create and sign the release tag (one tag covers both binaries):
|
||||
|
||||
```sh
|
||||
crates/radicle-httpd/build/tag <version>
|
||||
```
|
||||
|
||||
Publish the tag to Radicle. Push only this tag: every tag under `releases/`
|
||||
that a delegate pushes becomes canonical, so `--tags` would also publish any
|
||||
stray local ones.
|
||||
Publish the tag to Radicle. Push only this tag: every tag under `releases/` that
|
||||
a delegate pushes becomes canonical, so `--tags` would also publish any stray
|
||||
local ones.
|
||||
|
||||
```sh
|
||||
git push rad refs/tags/releases/httpd/<version>
|
||||
rad sync
|
||||
@@ -87,11 +93,13 @@ rad sync
|
||||
|
||||
Run the reproducible build (Linux x86_64 or macOS). A single run compiles the
|
||||
workspace and packages **both** binaries — one archive per binary per target:
|
||||
|
||||
```sh
|
||||
crates/radicle-httpd/build/build
|
||||
```
|
||||
|
||||
This writes to `crates/radicle-httpd/build/artifacts/`:
|
||||
|
||||
- `radicle-httpd-<version>-<target>.tar.xz` (binary + man page)
|
||||
- `radicle-search-<version>-<target>.tar.xz` (binary)
|
||||
|
||||
@@ -104,6 +112,7 @@ each with a `.sig` and `.sha256` alongside.
|
||||
The upload publishes each binary into its own sibling folder on
|
||||
[files.radicle.dev][files] and creates the version-less and `latest` symlinks
|
||||
for both:
|
||||
|
||||
```sh
|
||||
SSH_LOGIN=<username> crates/radicle-httpd/build/upload
|
||||
```
|
||||
@@ -119,6 +128,7 @@ SSH_LOGIN=<username> crates/radicle-httpd/build/upload
|
||||
**Topic:** `radicle-httpd + radicle-search <version>`
|
||||
|
||||
**Message:**
|
||||
|
||||
````markdown
|
||||
# 👾 radicle-httpd + radicle-search <version>
|
||||
|
||||
@@ -127,6 +137,7 @@ SSH_LOGIN=<username> crates/radicle-httpd/build/upload
|
||||
## Installation
|
||||
|
||||
Download binaries from:
|
||||
|
||||
- https://files.radicle.dev/releases/radicle-httpd/<version>
|
||||
- https://files.radicle.dev/releases/radicle-search/<version>
|
||||
- https://radicle.dev/download
|
||||
@@ -141,18 +152,21 @@ SSH_LOGIN=<username> crates/radicle-httpd/build/upload
|
||||
<copy output from crates/radicle-httpd/build/checksums>
|
||||
```
|
||||
|
||||
:info: This release was built on <platform>. Build reproducibility across platforms is unsupported; checksums may differ if rebuilt elsewhere.
|
||||
:info: This release was built on <platform>. Build reproducibility across
|
||||
platforms is unsupported; checksums may differ if rebuilt elsewhere.
|
||||
````
|
||||
|
||||
## Notes
|
||||
|
||||
> **Important:**
|
||||
>
|
||||
> - macOS binaries are unsigned and not notarized; download via CLI only
|
||||
> - Build reproducibility across platforms is not guaranteed
|
||||
|
||||
## Podman Setup
|
||||
|
||||
We use `podman` for reproducible builds across machines. It's preferred over Docker because it runs without a daemon and doesn't require root access.
|
||||
We use `podman` for reproducible builds across machines. It's preferred over
|
||||
Docker because it runs without a daemon and doesn't require root access.
|
||||
|
||||
On first run, you may need to configure UID/GID ranges:
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
# radicle-search
|
||||
|
||||
Optional indexing daemon for Radicle. Runs alongside `radicle-node` and
|
||||
maintains a Meilisearch index of repo metadata that `radicle-httpd` can
|
||||
use to serve fast, typo-tolerant repo listings and full-text search.
|
||||
maintains a Meilisearch index of repo metadata that `radicle-httpd` can use to
|
||||
serve fast, typo-tolerant repo listings and full-text search.
|
||||
|
||||
When configured, httpd routes `/repos?sort=activity|seeding` and
|
||||
`/repos/search?q=…` through the index. When absent or unreachable, httpd
|
||||
transparently falls back to its built-in storage walk — no configuration
|
||||
on the client side, no API contract changes.
|
||||
transparently falls back to its built-in storage walk — no configuration on the
|
||||
client side, no API contract changes.
|
||||
|
||||
## What each repository document contains
|
||||
|
||||
@@ -29,23 +29,24 @@ Only public repos this node seeds are indexed.
|
||||
|
||||
## How it stays up to date
|
||||
|
||||
1. **Bootstrap.** On startup and after every event-stream reconnect, the
|
||||
daemon walks the storage tree end-to-end and re-upserts everything.
|
||||
1. **Bootstrap.** On startup and after every event-stream reconnect, the daemon
|
||||
walks the storage tree end-to-end and re-upserts everything.
|
||||
2. **Real time.** Subscribes to the node's control socket (same stream as
|
||||
`rad node events`) and reacts to:
|
||||
- `RefsFetched`, `LocalRefsAnnounced`, `CanonicalRefUpdated`, `RefsSynced`
|
||||
→ re-index the affected repo.
|
||||
- `RefsAnnounced` → re-index only if the rid is one we locally seed
|
||||
(filtered against an in-memory cache, so gossip about repos we don't
|
||||
host is dropped at near-zero cost).
|
||||
- `RefsFetched`, `LocalRefsAnnounced`, `CanonicalRefUpdated`, `RefsSynced` →
|
||||
re-index the affected repo.
|
||||
- `RefsAnnounced` → re-index only if the rid is one we locally seed (filtered
|
||||
against an in-memory cache, so gossip about repos we don't host is dropped
|
||||
at near-zero cost).
|
||||
- `SeedDiscovered` and `SeedDropped` are ignored; the seeding count they
|
||||
affect is refreshed by the periodic rescan.
|
||||
|
||||
Affected repos are collected and re-indexed together every
|
||||
`RADICLE_SEARCH_BATCH_SECS` (default 30s), so a burst of events for the
|
||||
same repo costs a single re-index.
|
||||
3. **Periodic rescan.** Every `RADICLE_SEARCH_RESCAN_SECS` (default 1h)
|
||||
as a safety net for missed events.
|
||||
`RADICLE_SEARCH_BATCH_SECS` (default 30s), so a burst of events for the same
|
||||
repo costs a single re-index.
|
||||
|
||||
3. **Periodic rescan.** Every `RADICLE_SEARCH_RESCAN_SECS` (default 1h) as a
|
||||
safety net for missed events.
|
||||
|
||||
## Setup
|
||||
|
||||
@@ -77,19 +78,18 @@ For production set a master key with `--master-key <KEY>` and run with
|
||||
|
||||
### 2. Build and run radicle-search
|
||||
|
||||
`radicle-search` is a member of the Cargo workspace rooted at the
|
||||
repository root (it lives under `crates/`), so build it from there. Cargo
|
||||
places the binary in the workspace-wide `target/`, not under this crate's
|
||||
directory:
|
||||
`radicle-search` is a member of the Cargo workspace rooted at the repository
|
||||
root (it lives under `crates/`), so build it from there. Cargo places the binary
|
||||
in the workspace-wide `target/`, not under this crate's directory:
|
||||
|
||||
```sh
|
||||
cargo build --release -p radicle-search
|
||||
./target/release/radicle-search
|
||||
```
|
||||
|
||||
The daemon picks up the Radicle profile from `RAD_HOME` and the node
|
||||
control socket from `RAD_SOCKET` (or their defaults). On first launch it
|
||||
bootstraps the index in a few seconds, then listens for node events.
|
||||
The daemon picks up the Radicle profile from `RAD_HOME` and the node control
|
||||
socket from `RAD_SOCKET` (or their defaults). On first launch it bootstraps the
|
||||
index in a few seconds, then listens for node events.
|
||||
|
||||
### 3. Point httpd at the index
|
||||
|
||||
@@ -99,35 +99,35 @@ Set `RADICLE_SEARCH_URL` (plus optional friends) before launching httpd:
|
||||
RADICLE_SEARCH_URL=http://127.0.0.1:7700 radicle-httpd
|
||||
```
|
||||
|
||||
On boot httpd logs `search backend enabled: url=… index=repos`. With the
|
||||
env var absent, httpd works exactly as before.
|
||||
On boot httpd logs `search backend enabled: url=… index=repos`. With the env var
|
||||
absent, httpd works exactly as before.
|
||||
|
||||
## Configuration
|
||||
|
||||
All via environment variables:
|
||||
|
||||
| Variable | Default | Purpose |
|
||||
|---|---|---|
|
||||
| `RADICLE_SEARCH_MEILI_URL` | `http://localhost:7700` | Meilisearch instance to connect to. |
|
||||
| `RADICLE_SEARCH_MEILI_KEY` | _(none)_ | Meilisearch master key (production mode). |
|
||||
| `RADICLE_SEARCH_INDEX_NAME` | `repos` | Index name this daemon maintains. |
|
||||
| `RADICLE_SEARCH_RESCAN_SECS` | `3600` | Interval between safety-net full rescans. |
|
||||
| `RADICLE_SEARCH_RECONNECT_BACKOFF_SECS` | `5` | Delay before reconnecting after an event-stream disconnect. |
|
||||
| `RADICLE_SEARCH_BATCH_SECS` | `30` | Interval at which repos touched by node events are re-indexed. |
|
||||
| `RAD_HOME` | `~/.radicle` | Standard Radicle profile path. |
|
||||
| `RAD_SOCKET` | `$RAD_HOME/node/control.sock` | Standard node control socket. |
|
||||
| Variable | Default | Purpose |
|
||||
| --------------------------------------- | ----------------------------- | -------------------------------------------------------------- |
|
||||
| `RADICLE_SEARCH_MEILI_URL` | `http://localhost:7700` | Meilisearch instance to connect to. |
|
||||
| `RADICLE_SEARCH_MEILI_KEY` | _(none)_ | Meilisearch master key (production mode). |
|
||||
| `RADICLE_SEARCH_INDEX_NAME` | `repos` | Index name this daemon maintains. |
|
||||
| `RADICLE_SEARCH_RESCAN_SECS` | `3600` | Interval between safety-net full rescans. |
|
||||
| `RADICLE_SEARCH_RECONNECT_BACKOFF_SECS` | `5` | Delay before reconnecting after an event-stream disconnect. |
|
||||
| `RADICLE_SEARCH_BATCH_SECS` | `30` | Interval at which repos touched by node events are re-indexed. |
|
||||
| `RAD_HOME` | `~/.radicle` | Standard Radicle profile path. |
|
||||
| `RAD_SOCKET` | `$RAD_HOME/node/control.sock` | Standard node control socket. |
|
||||
|
||||
httpd reads a parallel set to decide, at runtime, whether to use the index:
|
||||
|
||||
| Variable | Default | Purpose |
|
||||
|---|---|---|
|
||||
| `RADICLE_SEARCH_URL` | _(none)_ | Meilisearch instance httpd queries. **Unset disables search** — httpd serves listings and search from its storage walk. |
|
||||
| `RADICLE_SEARCH_KEY` | _(none)_ | Meilisearch API key. |
|
||||
| `RADICLE_SEARCH_INDEX_NAME` | `repos` | Index name to query. |
|
||||
| `RADICLE_SEARCH_TIMEOUT_MS` | `500` | Per-query timeout in milliseconds (must be a non-zero integer). |
|
||||
| Variable | Default | Purpose |
|
||||
| --------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------- |
|
||||
| `RADICLE_SEARCH_URL` | _(none)_ | Meilisearch instance httpd queries. **Unset disables search** — httpd serves listings and search from its storage walk. |
|
||||
| `RADICLE_SEARCH_KEY` | _(none)_ | Meilisearch API key. |
|
||||
| `RADICLE_SEARCH_INDEX_NAME` | `repos` | Index name to query. |
|
||||
| `RADICLE_SEARCH_TIMEOUT_MS` | `500` | Per-query timeout in milliseconds (must be a non-zero integer). |
|
||||
|
||||
Use the same URL/key/index values in both processes. A single
|
||||
`radicle-httpd` binary handles both modes — no build-time feature flag is
|
||||
involved. When `RADICLE_SEARCH_URL` is unset, or when a query to the
|
||||
backend fails or times out, httpd transparently falls back to the storage
|
||||
walk, so the API behaves identically either way.
|
||||
Use the same URL/key/index values in both processes. A single `radicle-httpd`
|
||||
binary handles both modes — no build-time feature flag is involved. When
|
||||
`RADICLE_SEARCH_URL` is unset, or when a query to the backend fails or times
|
||||
out, httpd transparently falls back to the storage walk, so the API behaves
|
||||
identically either way.
|
||||
|
||||
@@ -39,15 +39,18 @@ sudo apt install radicle
|
||||
|
||||
### Pacman (Arch Linux)
|
||||
|
||||
Install [`radicle`](https://archlinux.org/packages/extra/x86_64/radicle/) via pacman.
|
||||
Install [`radicle`](https://archlinux.org/packages/extra/x86_64/radicle/) via
|
||||
pacman.
|
||||
|
||||
### Nix
|
||||
|
||||
Install `radicle-node` from [Nixpkgs](https://search.nixos.org/packages?query=radicle-node).
|
||||
Install `radicle-node` from
|
||||
[Nixpkgs](https://search.nixos.org/packages?query=radicle-node).
|
||||
|
||||
## Reproducible binaries
|
||||
|
||||
Radicle publishes reproducible builds for Linux and macOS. Each release includes binaries, SHA256 checksums, and SSH signatures.
|
||||
Radicle publishes reproducible builds for Linux and macOS. Each release includes
|
||||
binaries, SHA256 checksums, and SSH signatures.
|
||||
|
||||
### Radicle
|
||||
|
||||
@@ -59,12 +62,12 @@ curl -O -L https://files.radicle.dev/releases/latest/radicle-$TARGET.tar.xz
|
||||
|
||||
Replace `$TARGET` with one of:
|
||||
|
||||
| Platform | Target |
|
||||
|----------|--------|
|
||||
| Linux x86_64 | `x86_64-unknown-linux-musl` |
|
||||
| Linux ARM64 | `aarch64-unknown-linux-musl` |
|
||||
| macOS x86_64 | `x86_64-apple-darwin` |
|
||||
| macOS ARM64 | `aarch64-apple-darwin` |
|
||||
| Platform | Target |
|
||||
| ------------ | ---------------------------- |
|
||||
| Linux x86_64 | `x86_64-unknown-linux-musl` |
|
||||
| Linux ARM64 | `aarch64-unknown-linux-musl` |
|
||||
| macOS x86_64 | `x86_64-apple-darwin` |
|
||||
| macOS ARM64 | `aarch64-apple-darwin` |
|
||||
|
||||
### Radicle HTTP daemon
|
||||
|
||||
@@ -82,11 +85,13 @@ Extract the archive to `~/.radicle/`:
|
||||
tar -xf radicle-$TARGET.tar.xz -C ~/.radicle/
|
||||
```
|
||||
|
||||
This places binaries in `~/.radicle/bin` and man pages in `~/.radicle/man`. Make sure `~/.radicle/bin` is in your `PATH`.
|
||||
This places binaries in `~/.radicle/bin` and man pages in `~/.radicle/man`. Make
|
||||
sure `~/.radicle/bin` is in your `PATH`.
|
||||
|
||||
## Verification
|
||||
|
||||
Each archive is accompanied by a `.sig` (SSH signature) and `.sha256` (checksum) file.
|
||||
Each archive is accompanied by a `.sig` (SSH signature) and `.sha256` (checksum)
|
||||
file.
|
||||
|
||||
### Signature verification
|
||||
|
||||
@@ -98,13 +103,13 @@ ssh-keygen -Y check-novalidate -n file -s ARCHIVE.tar.xz.sig < ARCHIVE.tar.xz
|
||||
|
||||
The following team members sign releases:
|
||||
|
||||
| Name | Public key |
|
||||
|------|-----------|
|
||||
| Name | Public key |
|
||||
| --------------------- | ---------------------------------------------------------------------------------- |
|
||||
| cloudhead@radicle.xyz | `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL460KIEccS4881p7PPpiiQBsxF+H5tgC6De6crw9rbU` |
|
||||
| erik@radicle.xyz | `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBrJyJTwj/xG7F7qY0HDFXbb8A+xNNH8eILQ8hlvKW7/` |
|
||||
| fintan@radicle.xyz | `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEFsaRqAJ1r6bBFwlcWzJKN7DdjItQDumCNc0wqw6Dvk` |
|
||||
| lorenz@radicle.xyz | `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFhK7CqgIIbSthoNn8ea32krOnMzC807Z+PpBkR2YOVj` |
|
||||
| rudolfs@osins.org | `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPueml1FxzjvwbD7vRZfwoaoyuxLy0L+WLBwSNiVoJe5` |
|
||||
| erik@radicle.xyz | `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBrJyJTwj/xG7F7qY0HDFXbb8A+xNNH8eILQ8hlvKW7/` |
|
||||
| fintan@radicle.xyz | `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEFsaRqAJ1r6bBFwlcWzJKN7DdjItQDumCNc0wqw6Dvk` |
|
||||
| lorenz@radicle.xyz | `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFhK7CqgIIbSthoNn8ea32krOnMzC807Z+PpBkR2YOVj` |
|
||||
| rudolfs@osins.org | `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPueml1FxzjvwbD7vRZfwoaoyuxLy0L+WLBwSNiVoJe5` |
|
||||
|
||||
### Checksum verification
|
||||
|
||||
|
||||
@@ -15,52 +15,83 @@ title: Glossary
|
||||
|
||||
<h1 class="txt-bold-32">Glossary. <span class="txt-color-tertiary">Definitions of Radicle-specific terms.</span></h1>
|
||||
|
||||
**Bootstrap node** — A well-known seed node that new nodes connect to on first startup to discover the rest of the network. Radicle ships pre-configured with `seed.radicle.garden` and `seed.radicle.xyz`.
|
||||
**Bootstrap node** — A well-known seed node that new nodes connect to on first
|
||||
startup to discover the rest of the network. Radicle ships pre-configured with
|
||||
`seed.radicle.garden` and `seed.radicle.xyz`.
|
||||
|
||||
**Canonical JSON** — A standardized JSON encoding with sorted keys and no unnecessary whitespace. Used for identity documents so that hashing produces deterministic results.
|
||||
**Canonical JSON** — A standardized JSON encoding with sorted keys and no
|
||||
unnecessary whitespace. Used for identity documents so that hashing produces
|
||||
deterministic results.
|
||||
|
||||
**Canonical reference** — A Git reference whose authoritative state is determined by delegate signatures meeting the threshold requirement.
|
||||
**Canonical reference** — A Git reference whose authoritative state is
|
||||
determined by delegate signatures meeting the threshold requirement.
|
||||
|
||||
**COB (Collaborative Object)** — A CRDT-based data structure stored as Git objects. Used to implement issues, patches, and other social features.
|
||||
**COB (Collaborative Object)** — A CRDT-based data structure stored as Git
|
||||
objects. Used to implement issues, patches, and other social features.
|
||||
|
||||
**`config.json`** — The node configuration file, typically at `~/.radicle/config.json`. Controls seeding policy, external addresses, bootstrap peers, and scope.
|
||||
**`config.json`** — The node configuration file, typically at
|
||||
`~/.radicle/config.json`. Controls seeding policy, external addresses, bootstrap
|
||||
peers, and scope.
|
||||
|
||||
**CRDT (Conflict-Free Replicated Data Type)** — A data structure designed so that concurrent modifications by different participants always merge deterministically without conflicts. The foundation of COBs.
|
||||
**CRDT (Conflict-Free Replicated Data Type)** — A data structure designed so
|
||||
that concurrent modifications by different participants always merge
|
||||
deterministically without conflicts. The foundation of COBs.
|
||||
|
||||
**Delegate** — A person (identified by their DID) authorized to make changes to a repository’s identity document and canonical branches.
|
||||
**Delegate** — A person (identified by their DID) authorized to make changes to
|
||||
a repository’s identity document and canonical branches.
|
||||
|
||||
**DID (Decentralized Identifier)** — A W3C standard identifier encoding a public key. In Radicle, DIDs use the `did:key` method with Ed25519 keys. Format: `did:key:z6Mk...`.
|
||||
**DID (Decentralized Identifier)** — A W3C standard identifier encoding a public
|
||||
key. In Radicle, DIDs use the `did:key` method with Ed25519 keys. Format:
|
||||
`did:key:z6Mk...`.
|
||||
|
||||
**Gossip protocol** — The communication mechanism by which Radicle nodes discover peers and learn about repository updates.
|
||||
**Gossip protocol** — The communication mechanism by which Radicle nodes
|
||||
discover peers and learn about repository updates.
|
||||
|
||||
**Identity document** — A JSON document at `refs/rad/id` that defines a repository’s metadata, delegates, and threshold.
|
||||
**Identity document** — A JSON document at `refs/rad/id` that defines a
|
||||
repository’s metadata, delegates, and threshold.
|
||||
|
||||
**Magic ref** — A special Git reference (like `refs/patches`) that Radicle intercepts during push to trigger specific actions.
|
||||
**Magic ref** — A special Git reference (like `refs/patches`) that Radicle
|
||||
intercepts during push to trigger specific actions.
|
||||
|
||||
**Namespace** — Git’s mechanism for partitioning references. Radicle uses namespaces to store each peer’s data under their Node ID.
|
||||
**Namespace** — Git’s mechanism for partitioning references. Radicle uses
|
||||
namespaces to store each peer’s data under their Node ID.
|
||||
|
||||
**Node** — A participant in the Radicle network, running `radicle-node`. Identified by a public key (Node ID).
|
||||
**Node** — A participant in the Radicle network, running `radicle-node`.
|
||||
Identified by a public key (Node ID).
|
||||
|
||||
**Node ID (NID)** — The public key that identifies a node on the network. Retrieve yours with `rad self --nid`.
|
||||
**Node ID (NID)** — The public key that identifies a node on the network.
|
||||
Retrieve yours with `rad self --nid`.
|
||||
|
||||
**Patch** — A proposed code change, stored as a COB. Radicle’s equivalent of a pull request.
|
||||
**Patch** — A proposed code change, stored as a COB. Radicle’s equivalent of a
|
||||
pull request.
|
||||
|
||||
**`rad` remote** — The Git remote configured in Radicle working copies. Handled by `git-remote-rad`.
|
||||
**`rad` remote** — The Git remote configured in Radicle working copies. Handled
|
||||
by `git-remote-rad`.
|
||||
|
||||
**Radicle Explorer** — The web interface for browsing Radicle repositories, powered by `radicle-httpd`. Currently read-only.
|
||||
**Radicle Explorer** — The web interface for browsing Radicle repositories,
|
||||
powered by `radicle-httpd`. Currently read-only.
|
||||
|
||||
**Reference announcement** — A gossip message that informs peers a repository has been updated. Triggers Git fetches by interested nodes.
|
||||
**Reference announcement** — A gossip message that informs peers a repository
|
||||
has been updated. Triggers Git fetches by interested nodes.
|
||||
|
||||
**RID (Repository Identity)** — A globally unique, self-certifying identifier for a Radicle repository. Prefixed with `rad:`.
|
||||
**RID (Repository Identity)** — A globally unique, self-certifying identifier
|
||||
for a Radicle repository. Prefixed with `rad:`.
|
||||
|
||||
**Scope** — Controls which peers’ data your node synchronizes. Options are `followed` (only explicit follows) or `all`.
|
||||
**Scope** — Controls which peers’ data your node synchronizes. Options are
|
||||
`followed` (only explicit follows) or `all`.
|
||||
|
||||
**Seed / Seed node** — An always-on server node that provides high availability for repositories. Listens on TCP port 8776 by default.
|
||||
**Seed / Seed node** — An always-on server node that provides high availability
|
||||
for repositories. Listens on TCP port 8776 by default.
|
||||
|
||||
**Seeding** — Serving a repository to other nodes on the network. Distinct from tracking (storing locally for your own use).
|
||||
**Seeding** — Serving a repository to other nodes on the network. Distinct from
|
||||
tracking (storing locally for your own use).
|
||||
|
||||
**Seeding policy** — Configuration that determines which repositories a node will replicate. `allow` means replicate everything; `block` means only replicate explicitly allowed repos.
|
||||
**Seeding policy** — Configuration that determines which repositories a node
|
||||
will replicate. `allow` means replicate everything; `block` means only replicate
|
||||
explicitly allowed repos.
|
||||
|
||||
**Threshold** — The number of delegates required to agree on a change for it to be considered canonical. Defined in the identity document.
|
||||
**Threshold** — The number of delegates required to agree on a change for it to
|
||||
be considered canonical. Defined in the identity document.
|
||||
|
||||
**Tracking** — Telling your node to store a local copy of a repository and fetch updates. Distinct from seeding (also serving it to others).
|
||||
**Tracking** — Telling your node to store a local copy of a repository and fetch
|
||||
updates. Distinct from seeding (also serving it to others).
|
||||
|
||||
@@ -122,7 +122,9 @@ test("math", async ({ page }) => {
|
||||
waitUntil: "networkidle",
|
||||
});
|
||||
await expect(page.getByText("The Cauchy-Schwarz Inequality")).toBeVisible();
|
||||
await expect(page.locator(".katex-display .katex-html").first()).toBeVisible();
|
||||
await expect(
|
||||
page.locator(".katex-display .katex-html").first(),
|
||||
).toBeVisible();
|
||||
await expect(page).toHaveScreenshot({ fullPage: true });
|
||||
});
|
||||
|
||||
|
||||
+12
-11
@@ -1,14 +1,14 @@
|
||||
# Open Graph
|
||||
|
||||
Worker on `open-graph.radicle.network` that serves OG meta tags and
|
||||
preview card images for social media embeds.
|
||||
Worker on `open-graph.radicle.network` that serves OG meta tags and preview card
|
||||
images for social media embeds.
|
||||
|
||||
## How it works
|
||||
|
||||
`radicle.network` is a plain static SPA. A Cloudflare Redirect Rule
|
||||
302s social media crawlers to `open-graph.radicle.network`, which
|
||||
returns HTML with OG tags. The `og:image` points to `/cards/...` on
|
||||
the same domain, where the worker renders PNG cards via Satori + resvg-wasm.
|
||||
`radicle.network` is a plain static SPA. A Cloudflare Redirect Rule 302s social
|
||||
media crawlers to `open-graph.radicle.network`, which returns HTML with OG tags.
|
||||
The `og:image` points to `/cards/...` on the same domain, where the worker
|
||||
renders PNG cards via Satori + resvg-wasm.
|
||||
|
||||
Browsers and search crawlers hit the SPA directly — no worker cost.
|
||||
|
||||
@@ -18,8 +18,8 @@ Browsers and search crawlers hit the SPA directly — no worker cost.
|
||||
- `/cards/*` — PNG card images (cached 2 hours)
|
||||
|
||||
Card routes mirror app routes: `/cards/nodes/:host/:rid`,
|
||||
`/cards/nodes/:host/:rid/issues/:id`, etc. When API fetches fail,
|
||||
cards degrade: specific item -> repo -> node -> home.
|
||||
`/cards/nodes/:host/:rid/issues/:id`, etc. When API fetches fail, cards degrade:
|
||||
specific item -> repo -> node -> home.
|
||||
|
||||
## Cloudflare Redirect Rule
|
||||
|
||||
@@ -42,14 +42,15 @@ cards degrade: specific item -> repo -> node -> home.
|
||||
)
|
||||
```
|
||||
|
||||
Dynamic 302 to `concat("https://open-graph.radicle.network", http.request.uri.path)`
|
||||
Dynamic 302 to
|
||||
`concat("https://open-graph.radicle.network", http.request.uri.path)`
|
||||
|
||||
## Rate Limiting
|
||||
|
||||
**Security > WAF > Rate limiting rules** on the `radicle.network` zone:
|
||||
|
||||
Verified bots are rate limited to 50 requests per 10 seconds across
|
||||
all of `radicle.network`, with a 1 minute block.
|
||||
Verified bots are rate limited to 50 requests per 10 seconds across all of
|
||||
`radicle.network`, with a 1 minute block.
|
||||
|
||||
## Deploy
|
||||
|
||||
|
||||
Reference in New Issue
Block a user