This prepares the crate versions for a new release. The version bumps were
determined by the `cargo-semver-checks` tool.
However, there were some issues with the `radicle-fetch` crate – where when
attempting to check it, it was unable to compile due to the previous version
expecting the kind of `Doc` with a generic parameter. I believe this is due to
the version for `radicle` being specified as simply `0`. This prompted changing
the version specifications to use `major.minor` for all the internal crates.
This, for example, would mean that `radicle-fetch` that relies on `0.15` can use
`>=0.15.0,<0.16.0` – allowing any patch versions but must require a minor
version bump.
Similar to the `Fetcher` sans-IO approach, an `Announcer` sans-IO approach is
introduced. The previous `Handler::announce` was already quite close to using a
sans-IO approach, but using internally held state. This change makes the
business logic more reusable – and testable.
Similarly to the `Fetcher`, the `Announcer` is configured and then driven by
telling it when nodes have been synchronized with. It will continuously check if
it has reached its target, yielding to the caller to decide whether to keep
going. In contrast, it also provides a way to mark the process as timed out,
since announcing relies on waiting for events to come back in a timely manner.
Commit b608a788 (cli: `rad config schema` emits JSON Schema, 2025-04-28)
added a feature flag that enables the "schemars" optional dependency.
Crate radicle-node doesn't use this feature.
Crate radicle fails to compile when the feature is disabled.
This is reproducible with "flake check".
Fix it.
Note that a "cargo build" of the entire workspace doesn't fail, because the
feature is enabled due to "unification", since "radicle-cli" does use this
feature. From https://doc.rust-lang.org/cargo/reference/resolver.html#features:
> When building multiple packages in a workspace (such as with --workspace
> or multiple -p flags), the features [of the dependencies] of all of those
> packages are unified. If you have a circumstance where you want to avoid
> that unification for different workspace members, you will need to build
> them via separate cargo invocations.
This patch changes separates the business logic of fetching from the process of
fetching itself. It does this through a sans-IO approach, where a `Fetcher`
provides the necessary state to help drive a fetch forward, without performing
any of the IO itself.
What the `Fetcher` cares about is:
- What nodes are going to be attempted to be fetched from
- In what order should they be attempted
- When should the fetching process be considered finished
The `Fetcher` is then used in `radicle-cli` to drive forward the `sync::fetch`
function, allowing it to only care about the IO.
Leverage `schemars` to generate a JSON Schema from our structs for
configurations and those occurring within them.
The output of `rad config schema` can be used by editors to provide a
smoother editing experience for the configuration file. Discovery
attributes (both keys and values) is greatly improved with the schema
helping in the background.
Refer to:
- https://json-schema.org
- https://code.visualstudio.com/docs/languages/json#_json-schemas-and-settings
- https://schemastore.org
This change is to help separate the fact the namespacing by a `NodeId` is a
Radicle specific concern. The identifier can, in theory, be any kind of path
component, as long it is valid in Git.
The motivation for the change is to help separate the idea of a device's
`NodeId` vs an agent being an author – for future agent repository work.
The motivation of this change is to move away from tying signing to be
specifically for ed25519. The reason being that the protocol will want move
towards two different kinds of signing – the node signing artifacts, and an
author signing artifacts.
This change captures the former, node signing, by introducing a `Device` type
that is the `NodeId` – a PublicKey underneath the hood – and a signing
mechanism. This allows the replacement of the `Signer` trait being used – which
always assumed a `PublicKey`. Instead, the `Device` is constructed with
`NodeId`.
In `radicle-cob`, a signer is expected to implement
`signature::Signer<ExtendedSignature>`, and everywhere in `radicle`,
`radicle-node`, `radicle-cli`, and `radicle-remote-helper` is expected the
signer is expected to implement `signature::Signer<Signature>`.
A `Device` implements both of these but only requires
`signature::Signer<Signature>` to do so – since an `ExtendedSignature` is
essentially `(PublicKey, Signature)`, and the `NodeId` of the `Device` can be
used.
This declares the minimum supported Rust version, independently of the
`rust-toolchain.toml` file, which specifies the Rust version and
toolchain components the crate/workspace should be built with. The
MSRV affects other crates that depend on anything in this workspace,
but the toolchain file does not seem to affect them. This means the
MSRV is useful for those who build or develop dependents.
Signed-off-by: Lars Wirzenius <liw@liw.fi>
In fresh environments, without a global git config, the `user.name` and
`user.email` will not be set for the fixture repository. This causes issues when
tests are run and attempt to call `git2::Signature::now` – it will fail to read
a user name and email for the commit.
To remedy this, the name and email are set for the repository when initialising
it.
This introduces rate limits for the `ChannelReader` to limit DDoS attacks and
attempts to upload repositories that are larger than a node is will to permit.
The limiter sets the total number of bytes it is will to accept in a single
exchange, defaulting to 500MB. This means that initial fetches will prevent
large repositories, but is plenty for new packfile data to be sent in subsequent
fetch exchanges.
The limit can be configured within the node's config file, under the limits.
Similarly to pushing using the `file://` protocol and `libgit2`, fetching will
be slow – so instead use `git fetch` directly to perform the `checkout`.
In issue #[2836] of `libgit2`, the speed of `libgit2`'s `file://` protocol for
git operations is found to be very slow. This is further corrobarated by `rad
init` taking 13 hours to initialise the hardenedbsd [ports] repository.
There are two areas where the `heartwood` project uses `libgit2` to push using
the file protocol. The first is when via the `trasnport::local` smart transport
registration and the second is the final push to storage in the `git-remote-rad`
binary.
When both these `push` operations are changed to use the `git` binary instead,
the [ports] repository can be initialised in less than 10 minutes (nearly 100x
speed up).
This change is clearly required if `heartwood` wishes to support larger
repositories.
[2836]: https://github.com/libgit2/libgit2/issues/2836
[ports]: https://git.hardenedbsd.org/hardenedbsd/ports
Update the rust toolchain version to 1.85.
Note that this is not the latest, however, it is the latest available in nixpgs,
so this version is good enough for now.
Adds an `Op::load` helper method for loading an `Entry`, given its `Oid` and the
`store` it is stored in.
This can be useful for downstream consumers to inspect operations on COBs given
a single `Oid`, without having to load the entire object and/or graph.
It can also be useful when looking at implementing COB stream primitives.
Instead of collecting the results and returning the collection as an
iterator, introduce `FollowPolicies` and `SeedPolicies` types, which
implement `Iterator`.
Note that a call in `service` changed due to the lifetime borrow. It
simply `collect`s into a `Vec` for the time being.
Provide functionality to lookup the `NodeId`s associated with a given
`Alias`.
The use for this functionality is to allow callers to use aliases as
shorthands for `NodeId`s, but still refer to the exact identifier.
The implementation allows for searching using the `LIKE '%<pattern>%'`
queries in sqlite, so searches do not have to be exact matches.
The use of `Transaction` outside of the `radicle` crate requires that a newtype is used, if the upstream code wants to write methods, such as:
```
pub struct Transaction<R>(store::Transaction<MyCob, R>);
impl Transaction<R> {
pub fn add_foo(&mut self, foo: Foo) -> Result<(), store::Error> { /* code */ }
pub fn add_bar(&mut self, bar: Bar) -> Result<(), store::Error> { /* code */ }}
```
This works up until the point that it tries to re-use the
`Transaction::initial` method.
To make this possible, the method needs to know that it can be
converted to the upstream `Transaction` and back to `radicle`
`Transaction`.
Extend the ranges of emojis that are supported, listed
[below](#new-emojis-supported).
To ensure that single `char` emojis are supported, the `emojis` crate
is added as a dev dependency, using it to check that a `Reaction` can
be constructed for the two groups `SmileysAndEmotion` and
`PeopleAndBody`.
### New Emojis Supported
'🩵' 0x1FA75
'🩶' 0x1FA76
'🩷' 0x1FA77
'🫀' 0x1FAC0
'🫁' 0x1FAC1
'🫂' 0x1FAC2
'🫃' 0x1FAC3
'🫄' 0x1FAC4
'🫅' 0x1FAC5
'' 0x1FAC6
'🫠' 0x1FAE0
'🫡' 0x1FAE1
'🫢' 0x1FAE2
'🫣' 0x1FAE3
'🫤' 0x1FAE4
'🫥' 0x1FAE5
'🫦' 0x1FAE6
'🫨' 0x1FAE8
'' 0x1FAE9
'🫰' 0x1FAF0
'🫱' 0x1FAF1
'🫲' 0x1FAF2
'🫳' 0x1FAF3
'🫴' 0x1FAF4
'🫵' 0x1FAF5
'🫶' 0x1FAF6
'🫷' 0x1FAF7
'🫸' 0x1FAF8
The `parse_ref` and `parse_ref_namespaced` documentation used 4 space
indentation for the reference names. Unfortunately, `cargo test` attempts to
interpret this as code.
Use triple-backtick code fencing, with `text` and `no_run`, instead.
To be able to query the `BTreeSet` that shows which comments are
resolved by a specific revision and the `Iterator` of `Label` we require
some methods to obtain them.
Provide better documentation for the two methods.
Solves the issue:
```
rad issue show 4603f55d97a0776f37bae2f9d2ba7d455d8a4c83
```
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
rlimit values have different types on Linux and FreeBSD, as well as
64-bit and 32-bit platforms, so stick to the type rlim_t provided by the
libc crate.
Adds the new `migrate` sub-command to migrate the COB database.
Checks for version when opening the COBs database and suggests the
command on out of date version.
Also adds the 2nd migration to the COBs cache, which updates the patch
JSON schema.
While the total notification count and the notification count by repo
are needed, for most UIs users will want to see the total notification
count grouped by repo.
This new method will provide this without the need of checking all
possible repos to see if they have notifications.
The `radicle-cob` crate provides a feature flag, `stable-commit-ids` to allow
for `Oid`s to remain stable for testing by always using the same author and
timestamp when creating commits.
This can be an issue when it interplays with COB related tests that are relying
on the ordering for the DAG walk. If the `Oid` values change and get re-ordered
then the test will fail. The DAG for COBs are now ordered via the `Oid` and
`Timestamp`.
In this change, a global timestamp is introduced that is initialised
per thread. The value is read, via `read_timestamp`, and can be
advanced using `with_advanced_timestamp` – while performing an action
that creates a new commit.
The `no quorum found` error can be opaque and lead to a lot of confusion. It is
better to give more information for this error so that it leads to easier
debugging, since it can be quite a common warning/error.
Instead of a single error, there are two cases provided: `NoCandidates` and
`Diverging`, to capture the two different variants of errors that can occur.
`Display` implementations are provided for both to provide more information.
This change introduces versioning to the identity document format.
The `Version` type is introduced to capture this. Importantly, it is very
restricted in its construction and API. `Version::new` provides a smart
constructor to ensure that it is only ever constructed within the expected
bounds of `0 < v <= IDENTITY_VERSION`, where `IDENTITY_VERSION` is the constant
for the current version.
Note that serializing of the `Doc::version` is skipped to preserve the `Oid`
outputs of all the tests – which means that the first `version` is always
implicit and is not really expected to exist in the serialized forms of the
identity document.
This is meant to record in Radicle that automated "jobs" have been run
on a repository. The job might be, for example, a CI run that builds
the software and runs its tests. The recording is done in a "job COB",
which can be in three states:
* fresh -- when the job has been triggered, but has not yet started running
* running -- when it's running
* finished -- when it's finished running
The finished state also records whether the job was successful or if
it failed.
A job COB records the git commit that it runs on, and the "run ID" of
the job. The run ID represents an external identifier, such as one
assigned by a remote CI system. The COB can optionally store a URL
related to the job, such as to the build log from CI.
Add the "rad job" subcommand to create and manage job COBs. For
production use, the COBs should be created and updated using
`heartwood` as a library instead of running "rad job", if at all
possible. However, "rad job list" lists the jobs that have been run on
the repository.
The COB type name is xyz.radicle.beta.job, until we've gained
experience with the COB and its implementation and are ready to
declare it stable.
Signed-off-by: Lars Wirzenius <liw@liw.fi>
We were rejecting patches that were once valid, due to a rule that was
added some time ago. Move that rule one level up, in the write path,
instead of in the read path.
Adds `set`, `add`, `remove`, `delete` to `rad config`.
Note that the changes will affect the configuration file, but not the
running instances. For changes to be reflected in the running instances
the node would need to be restarted.