Radicle is a peer-to-peer, local-first code collaboration stack built on Git.
The Radicle team would like to announce the release of Radicle 1.9.0, code name Hawthorn. The Hawthorn tree, or Mayflower, signifies the coming of summer, and has significance for many cultures. In particular, the Hawthorn tree represents the door to the “other side” and is the home of the fairies in Irish culture. It is forbidden to cut down the Hawthorn tree, unless you want to be cursed by the fairies. So, this release represents being on the other side of the fixed security vulnerability in 1.8.0, and readying ourselves to ensure stronger foundations for the future.
This release contains 165 commits by 9 contributors, with a big thanks to:
- Daniel Norman
- Josh Soref
- Richard Levitte
- stefan
- Wiktor Kwapisiewicz
Installation
curl -sSLf https://radicle.dev/install | sh -s -- --no-modify-path --version=1.9.0
In this Release
Domain Name Migration
Following a domain move of the project, the names of the bootstrap nodes have changed to: {iris,rosa}.radicle.{xyz → network}.
If you are still using the old names in the Radicle configuration, this will be detected and you will see warnings printed.
Similarly, if you are using systemd credentials, then you should migrate from xyz.radicle.node.* to dev.radicle.node.*.
The COB type names and payload IDs remain unchanged for backwards compatibility.
Revision Ranges in rad patch show
Each revision in the output of rad patch show now shows the base and head of the revision in the format: <base>..<head>.
The shortened form is used, but the full commit OID is used when --verbose is passed.
This makes comparing two revisions much easier in combination with git range-diff.
For example, here is a patch in heartwood:
╭───────────────────────────────────────────────────────────────────────────╮
│ Title .radicle/ambient: Add pre-plan action for rustup │
│ Patch 3bb6f611190fc40207cdee0d22c421b02a6bc717 │
│ Author fintohaps (you) │
│ Head d9f9d090bde88ba0b6596614579641a15acff871 │
│ Base 9158df5067429282cbec60292316c13b3d965c5a │
│ Commits ahead 1, behind 3 │
│ Status open │
│ │
│ To ensure the correct toolchain is used when building and testing the │
│ project, a pre-plan action is added for `rustup`. │
│ It uses the same `channel` as defined in the `rust-toolchain.toml`. │
│ A note is left about this duplication, and the possibility of it being │
│ supported in the future. │
├───────────────────────────────────────────────────────────────────────────┤
│ d9f9d09 .radicle/ambient: Add pre-plan action for rustup │
├───────────────────────────────────────────────────────────────────────────┤
│ ● Revision 3bb6f61 @ 9158df5..d9f9d09 by fintohaps (you) 5 days ago │
│ ↑ Revision 183d186 @ 9158df5..040ab10 by lars z6MkgEM…1b2w2FV 2 hours ago │
╰───────────────────────────────────────────────────────────────────────────╯
As long as the commits are fetched from fintohaps and lars, then you can run:
$ git range-diff 9158df5..d9f9d09 9158df5..040ab10
1: d9f9d090b = 1: d9f9d090b .radicle/ambient: Add pre-plan action for rustup
-: --------- > 2: 040ab1045 work around problems with Ambient Rust toolchain downloading
Showing that a new commit was added, and no other changes were made.
Nodes Advertise Radicle Version
Nodes will now advertise the version of Radicle they are running in the node announcement as part of the “user agent”, which is shared among the network.
For example, the value that will be shared by Radicle 1.9.0 will be /radicle:1.9.0/.
This value is also customizable by node operators via the configuration value node.userAgent. Refer to rad config schema for more information on the possible values.
Operators that choose to set a custom value are asked to keep the substring /radicle:{YOUR_VERSION}/ which allows for better telemetry regarding version distribution on the network.
To opt-out of sending any meaningful user agent, set node.userAgent = null.
Introducing I2P Support
In addition to connections via SOCKS proxy and Tor for *.onion hostnames, I2P hostnames are now supported.
These names are of the form *.i2p{,.alt}.
To enable making connections via I2P, configure node.i2p, for example:
{
"node": {
"i2p": {
"mode": "proxy",
"address": "127.0.0.1:4447"
}
}
}
Symbolic Canonical References
It is now possible to define symbolic canonical references for a repository.
The payload xyz.radicle.crefs was extended to accept an object with key “symbolic” next to “rules”.
Consider the following example:
{
"payload": {
"xyz.radicle.crefs": {
"rules": {
"refs/heads/qa": {
"allow": [
"did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk"
],
"threshold": 1
},
"refs/tags/*": {
"allow": "delegates",
"threshold": 1
},
},
"symbolic": {
"refs/heads/staging": "refs/heads/qa"
}
}
}
}
Delegates are allowed to create tags, and one particular user is allowed to control the branch named “qa”. The team working on this repository used to call the “qa” branch “staging”, so they decided to keep a symbolic reference from “staging” to “qa” around for a while.
For further information about symbolic references also refer to the documentation of git symbolic-ref.
Deprecating rad config Subcommands
The commands to read and modify particular values in Radicle configuration via the CLI were marked as obsolete, i.e.,
rad config getrad config pushrad config removerad config setrad config unset
In the future, please modify Radicle configuration with your favorite text editor (e.g. via rad config edit), or specialized tools like jq.
Fixed Bugs
Gracefully Handle Malformed Addresses
Skip node address entries that cannot be parsed from an SQLite row into a valid address entry. This improves the node service, when it checks available peers. Previously, if it found a row it could not parse, then it would fail the whole process. Now, it will continue, providing valid entries to connect to.
To ensure that invalid IPv6 addresses no longer exist in your SQLite database, invalid addresses are removed.
Entries deleted include ones that have an address of the form []:port, or that have an invalid address within the [].
This removal happens automatically through a database migration, that runs at node startup.
Handling of * in Canonical References
Correctly handle the canonical reference rules that have a glob star suffix, e.g., refs/heads/main*, refs/heads/main-*, etc.
Previously, these would be expanded into sub-component searches.
For example, in the previous examples, the search would be expanded to refs/heads/main**/* and refs/heads/main-**/*.
Now, the rule will match by prefix, e.g. refs/heads/main-* will match refs/heads/main-a, refs/heads/main-b, refs/heads/main-deadbeef, etc.
Changelog
100040253node: upgrade cyphernet to fix a panic in socks5-client when using artix stefan.r.boca@gmail.com9158df506flake: Add NixOS tests to checks lorenz.leutgeb@radicle.dev767b80e7fflake: Sort Inputs Lexicographically lorenz.leutgeb@radicle.devc5043617bflake: Fix nixpkgs inputs lorenz.leutgeb@radicle.devcaee776c3log: New crate for logger implementations adrian.duke@gmail.comf22811e01simulation/README: Note for running on NixOS fintan.halpenny@gmail.com277f2615csimulation: Ensure OVMF is available adrian.duke@gmail.com9dda890fbflake.nix: Add simulation requirements to devShell fintan.halpenny@gmail.comac6759b74simulation: Switch externalAddress config parsing to jq adrian.duke@gmail.comd64889200simulation: Extract external address configuration bash commands adrian.duke@gmail.comf41bea1d6simulation: Vendor Timoni dependencies as part of start-network adrian.duke@gmail.comae4a70e3bsimulation: Update README adrian.duke@gmail.comd197ab613simulation: Add justfile and network.cue topology definition adrian.duke@gmail.com8622a466csimulation: Ignore cue.mod/pkg and cue.mod/gen for Timoni adrian.duke@gmail.com620a1ec69simulation: Introduce particle CUE module for radicle-node adrian.duke@gmail.combe5a1742fflake.lock: Update nixpkgs-stable fintan.halpenny@gmail.com0d7bc8d1dbuild: Update apline version to 3.22 fintan.halpenny@gmail.com420af3b71workspace/rust: 1.90 → 1.95 lorenz.leutgeb@radicle.dev9ea040ccdrust/msrv: 1.85.0 → 1.88.0 lorenz.leutgeb@radicle.dev0a0e70b1dnode/systemd: Fix reading credentials lorenz.leutgeb@radicle.dev6b460c442logger: Respect config file log level daniel@norman.life917714679radicle/web: Fix schema ofConfig::descriptionlorenz.leutgeb@radicle.devee9a9de36radicle/web: Relax deserialization ofConfiglorenz.leutgeb@radicle.dev53db99414schemars: Release 0.8.0 fintan.halpenny@gmail.comad068309cfetch: Release 0.20.0 fintan.halpenny@gmail.comab3621d5dremote-helper: Release 0.17.0 fintan.halpenny@gmail.comf5c39dd60cob: Release 0.20.0 fintan.halpenny@gmail.combaf533b37cli: Release 0.21.0 fintan.halpenny@gmail.com342b4d963node: Release 0.20.0 fintan.halpenny@gmail.com622f3827bprotocol: Release 0.8.0 fintan.halpenny@gmail.com2707f6b4bradicle: Release 0.24.0 fintan.halpenny@gmail.com3486c028eterm: Release 0.18.0 fintan.halpenny@gmail.com5991bdfa9systemd: Release 0.13.0 fintan.halpenny@gmail.com287141780oid: Release 0.2.0 fintan.halpenny@gmail.com4ca2098cbcore: Release 0.3.0 fintan.halpenny@gmail.com64a419d79crypto: Release 0.17.0 fintan.halpenny@gmail.com3f81e83d3radicle/crefs: Support Symbolic References lorenz.leutgeb@radicle.xyz080790d84radicle/git/canonical: Add explicit test case for fast_glob pattern match syntax adrian.duke@gmail.com80d30d3b5e2e: Fix false-positive in canonical ref update test adrian.duke@gmail.comed340f572e2e: Add partial glob match cref test adrian.duke@gmail.come87af868dnode/test:NodeHandle::commit_toshould namespace fintan.halpenny@gmail.com8724ebe78radicle/git/canonical: Introduce property tests for glob matching behaviour adrian.duke@gmail.comfb40bdc0aradicle/git/canonical: Fix glob rewrite rule for trailing asterisk adrian.duke@gmail.com455138f4aradicle/canonical/rules: Reorganise test suite fintan.halpenny@gmail.com998f527bdnode/db: delete unparseable ipv6 rows daniel@norman.lifea45a1078anode: Skip unreadable address rows inentries()daniel@norman.life5dae2a8b5treewide: Spelling <2119212+jsoref@users.noreply.github.com>a10170501term: RenameRow::Divid{i,}er<2119212+jsoref@users.noreply.github.com>08dd1dfdanode/test: Fix Spelling <2119212+jsoref@users.noreply.github.com>8391599f6oid: Fix spelling <2119212+jsoref@users.noreply.github.com>b482845e7sigrefs/git/properties: Restore property tests fintan.halpenny@gmail.com92347a307justfile: Add Rust tests to pre-push fintan.halpenny@gmail.comb4707e550cli: Amend jj tests fintan.halpenny@gmail.com378365aa4term: Denyprint_stdoutlorenz.leutgeb@radicle.xyzcc70d7dadradicle/cob: Do not returnBrokenPipefrom external COB invocation lorenz.leutgeb@radicle.xyz553a3ebd0cli/cob: Remove check ofBrokenPipelorenz.leutgeb@radicle.xyz56625a42fterm: Rename print_inline to print fintan.halpenny@gmail.com2262b8d9bterm: Rename print to println fintan.halpenny@gmail.come7d519cf6term: Rename println to println_prefixed fintan.halpenny@gmail.com1a31a9f54cli: Handle broken pipe (SIGPIPE) gracefully fintan.halpenny@gmail.come1f16bee2term: Catch EPIPE and swallow fintan.halpenny@gmail.com8f4b90db7cli/test: Add broken pipe (SIGPIPE) tests fintan.halpenny@gmail.com7b07e57b9treewide/test: Useimpl Arbitrary for Oidlorenz.leutgeb@radicle.xyz88a7252e3oid: Fiximpl Arbitrary for Oidlorenz.leutgeb@radicle.xyzdeabe6d2coid: Nicer panic message lorenz.leutgeb@radicle.xyz60f42bff5protocol: Minimize scope ofradicle::git::rawlorenz.leutgeb@radicle.xyz8dba3ca9dprotocol: Decoderadicle_oid::Oidwithoutgit2lorenz.leutgeb@radicle.xyz3d1b37fcboid: MakeOid::SHA1_LENpublic lorenz.leutgeb@radicle.xyzf46624b81oid: SHA1_DIGEST_LEN → Oid::LEN_SHA1 lorenz.leutgeb@radicle.xyz4c605c067radicle: Avoid comparison withZERO_SHA1lorenz.leutgeb@radicle.xyzecca50a5ftreewide: Avoidgit2::Oid::zerolorenz.leutgeb@radicle.xyzf65175397oid:const ZERO_SHA1instead offn sha1_zerolorenz.leutgeb@radicle.xyzaa177b040treewide: radicle.{xyz → dev,network} lorenz.leutgeb@radicle.devcb57e6560node: Rename systemd Credentials lorenz.leutgeb@radicle.dev06ff36ebccli: Update warning for new bootstrap node names lorenz.leutgeb@radicle.dev22287fd94radicle: Change names of bootstrap nodes lorenz.leutgeb@radicle.dev3bc8abdc2radicle/node/config: UseIndexSetlorenz.leutgeb@radicle.dev099722dd0radicle: Propagateradicle-oid/qcheckfintan.halpenny@gmail.com5d8988b1aCONTRIBUTING/HACKING: Add note on direnv adrian.duke@gmail.com8af0b623f.envrc: Replace .envrc with .envrc.sample richard@levitte.orgbdd991a5fe2e: Fix race condition in test_non_fastforward_identity_doc adrian.duke@gmail.com802e4726ee2e: Replace the hardcoded 1-second sleep intest_connection_crossingwith polling loop adrian.duke@gmail.combfb54bf4be2e: Fix flakiness intest_connection_crossingtest adrian.duke@gmail.combbb127960cli/config: Obsolete{get,set,push,remove,unset}lorenz.leutgeb@radicle.xyzf83eb5771ci: Update GitHub actionactions/cachelorenz.leutgeb@radicle.xyz224c03dafnode: Expandtarget_oscondition for keep-alive lorenz.leutgeb@radicle.xyz4a81673d0node: Fix conditions for socket activation lorenz.leutgeb@radicle.xyz354805aebcli/test: Fix failures related to remote HEAD richard@levitte.org6ce2d00beflake: SetRUST_BACKTRACEin development shell lorenz.leutgeb@radicle.xyz2d20e249fcli/init: DeduplicateScopeParserlorenz.leutgeb@radicle.xyzf8ec40a33just: Make it possible to give your own cargo command richard@levitte.org4f647b2a1Spell “Radicle” with a captial R lorenz.leutgeb@radicle.xyzbb97414a2cli: Deduplicate RID Argument Handling lorenz.leutgeb@radicle.xyzf2e96c96ccli: Rename allRepoIdargs torepolorenz.leutgeb@radicle.xyz07c624499just: Check for Git and Jujutsu-VCS conflict markers fintan.halpenny@gmail.comf00a1624dcodespell: Add .direnv to skip list fintan.halpenny@gmail.com8a38fa8c7typos: Rule for … -> … fintan.halpenny@gmail.comfe353ea7ecodespell: Rule for … -> … fintan.halpenny@gmail.com179a08086just: Introduce commit-msg hook for typos adrian.duke@gmail.comf6bf13422just: Fix doublestar expansion in check-scripts adrian.duke@gmail.com083c9d1abjust: Replace inline scripts with script file calls adrian.duke@gmail.com421a43376just: Drop underline from output styline adrian.duke@gmail.com6744384acjust: Extract inline bash scripts out to files adrian.duke@gmail.comdf31702b8flake: Addjustto development shell lorenz.leutgeb@radicle.xyzfc1241477just: RenameHOOK_NAMEto justHOOKlorenz.leutgeb@radicle.xyz112c901deflake: Add codespell fintan.halpenny@gmail.com69ccabacdjust: Use bash to perform install-hook confirmation fintan.halpenny@gmail.com1f4de60bajust: Add minimum version to CONTRIBUTING and HACKING adrian.duke@gmail.com11e80d309just: Check for file before removing in install-hooks fintan.halpenny@gmail.coma74befd2ajust: Expand shellcheck glob to all shell scripts fintan.halpenny@gmail.com983e5e19djust: Use full argument names for codespell fintan.halpenny@gmail.com3e9df1c8ejust: Remove existing hooks during install-hooks adrian.duke@gmail.comffe5b9ed0just: Better doc comment for check-keywords adrian.duke@gmail.comb0af317eahacking: Update docs with ‘just’ commands adrian.duke@gmail.com6e2b71035contributing: Update docs with ‘just’ commands adrian.duke@gmail.com1df1acabfgit-hook-template: minor output formatting adrian.duke@gmail.com4e0f739c2just: Add post-checkout hook adrian.duke@gmail.com09cd3eeb8just: Add check-hooks to confirm presence and integrity adrian.duke@gmail.comeb8467cb6just: Introduce output formatting adrian.duke@gmail.combdb2a1fc7just: Introduce pre-commit and pre-push installer adrian.duke@gmail.com576bc6d6ajust: Add groupings and parallel where possible adrian.duke@gmail.com3082f9976just: Add pre-commit hook adrian.duke@gmail.com9310b1effjust: Add more pre-push tasks adrian.duke@gmail.com9210f0871just: Introduce justfile with pre-push hook cmds adrian.duke@gmail.com430868ffbcodespell: Add ‘ser’ toignore-words-listadrian.duke@gmail.com9c6bcd277cli: Fix typo “writeable” → “writable” adrian.duke@gmail.comac3eba09aI2P Support lorenz.leutgeb@radicle.xyz9b9b5ca99cargo: Updatecyphernetfrom 0.5.2 to 0.5.3 lorenz.leutgeb@radicle.xyz91b2fd898clippy: Denyunwrap_usedlorenz.leutgeb@radicle.xyz4d57ba496rust: Disallow lintdead_codelorenz.leutgeb@radicle.xyzc23a257f3clippy: Configure lintunwrap_usedlorenz.leutgeb@radicle.xyzdbec748c4clippy: Disallow unused lints lorenz.leutgeb@radicle.xyz63f960742clippy: Disallow lintiter_nth_zerolorenz.leutgeb@radicle.xyzf87d25439clippy: Disallow lintidentity_oplorenz.leutgeb@radicle.xyz33a8c09f7clippy: Disallow lintmatch_like_matches_macrolorenz.leutgeb@radicle.xyzca732015fclippy: Disallow lintscollapsible_*lorenz.leutgeb@radicle.xyz44244dc00clippy: Disallow linttype_complexitylorenz.leutgeb@radicle.xyzffc81154eclippy: Disallow lintenum_variant_nameslorenz.leutgeb@radicle.xyzae55d935bcargo/workspace/lints: Shorten notation lorenz.leutgeb@radicle.xyz547a75376simulation: Add README with overview and plan adrian.duke@gmail.com94f65a71dcargo: Remove unused dependencies lorenz.leutgeb@radicle.xyzadfd89f60cli-test: RespectCARGO_TARGET_DIRrichard@levitte.org80c1bba76radicle: PreventRAD_SOCKETfrom polluting tests lorenz.leutgeb@radicle.xyza2de55cbbradicle/crefs: UseGetPayloadto load lorenz.leutgeb@radicle.xyz516736791radicle: Introducetrait GetPayloadlorenz.leutgeb@radicle.xyzaa2856703radicle/crefs: RefactorGetCanonicalRefslorenz.leutgeb@radicle.xyzef101d9abradicle/crefs/protect: Module for protected refs lorenz.leutgeb@radicle.xyze822623dcradicle/crefs/rules: Exact patterns for branches lorenz.leutgeb@radicle.xyzbfb285805radicle/storage: SplitWriteRepository::set_headlorenz.leutgeb@radicle.xyz0eba6caf9radicle: More convenience methods to get default branch lorenz.leutgeb@radicle.xyz22b2871f6radicle: Add Version to User Agent lorenz.leutgeb@radicle.xyz48551cde9crypto: Usessh-agent-libfor SSH Agent wiktor@metacode.biz0080813c9term: Update inquire to 0.9.4 fintan.halpenny@gmail.com5b6ae0ac4Update radicle-surf to 0.27.1 fintan.halpenny@gmail.com546001253protocol: Use pastey fork fintan.halpenny@gmail.com96f573b76cargo: Update dependencies withcargo updatelorenz.leutgeb@radicle.xyz91590a328cli/patch: Show Commit Ranges of Revisions richard@levitte.orgb8f8cfb31cli/terminal: Formatting Functions for Ranges richard@levitte.orgb54fc820eradicle/tor: Fixes lorenz.leutgeb@radicle.xyzf223afd9dradicle: Refactor COB Storage Access lorenz.leutgeb@radicle.xyz10a82958cnode: Explicit default forAddressConfiglorenz.leutgeb@radicle.xyzfb1808395radicle/serde_ext:fn null_to_defaultlorenz.leutgeb@radicle.xyz1e132685bcargo: Add feature for Tor support lorenz.leutgeb@radicle.xyz8bac24d6arust/edition/fmt: 2021 → 2024 lorenz.leutgeb@radicle.xyz0494227e7rust/edition: 2021 → 2024 lorenz.leutgeb@radicle.xyz
Checksums
42c90f273cf20c4ee1614dc7601c7595b900bf796ef97ba408dc262d48b7e514 radicle-1.9.0-x86_64-apple-darwin.tar.xz
bf5b7d6437eb1a378502d2e7ffbb192381f82a4d093018021585e1fd2e639530 radicle-1.9.0-aarch64-unknown-linux-musl.tar.xz
7adee42d3c3db6e9ba234040b1d9e37f4c2ea152ba7251e80b61a1afef3362a1 radicle-1.9.0-x86_64-unknown-linux-musl.tar.xz
768ef26013df96ea3506e6cf917726550e2d4bb94be3361dd2d7d6522be2ccf6 radicle-1.9.0-aarch64-apple-darwin.tar.xz