<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.3.4">Jekyll</generator><link href="https://radicle.xyz/feed.xml" rel="self" type="application/atom+xml" /><link href="https://radicle.xyz/" rel="alternate" type="text/html" /><updated>2025-07-25T07:22:52+01:00</updated><id>https://radicle.xyz/feed.xml</id><title type="html">Radicle: the sovereign forge</title><entry><title type="html">Using Radicle CI for Development</title><link href="https://radicle.xyz/2025/07/23/using-radicle-ci-for-development.html" rel="alternate" type="text/html" title="Using Radicle CI for Development" /><published>2025-07-23T00:00:00+01:00</published><updated>2025-07-23T00:00:00+01:00</updated><id>https://radicle.xyz/2025/07/23/using-radicle-ci-for-development</id><content type="html" xml:base="https://radicle.xyz/2025/07/23/using-radicle-ci-for-development.html"><![CDATA[<p>In this blog post I show how I use Radicle and its CI support for my
own software development. I show how I start a project, add it to
Radicle, add CI support for it, and manage patches and issues.</p>

<p>I have been working full time on Radicle CI for a couple of years now.
All my personal Git repositories are hosted on Radicle. Radicle CI is
the only CI I now use.</p>

<p>There are instructions to install the software I mention here at the
end.</p>

<p>These days, I’m not a typical software developer. I usually work in
Emacs and the command line instead of an IDE. In this blog post I’ll
concentrate on the parts of my development process that relate to
Radicle, and not my other tooling.</p>

<h1 id="overview-of-radicle-ci">Overview of Radicle CI</h1>

<p>The Radicle node process opens a Unix domain socket to which it sends
events describing changes in the node. One of these events represents
changes to a repository in the node’s storage.</p>

<p><img src="/assets/images/blog/components.svg" class="screenshot" style="background-color: #f5f5ff;" /></p>

<p>Support for CI in Radicle is built around the repository change event.
The Radicle CI broker (<code class="language-plaintext highlighter-rouge">cib</code>), listens for the events and matches them
against its configuration to decide when to run CI. The node operator
gets to decide for what repositories they run CI.</p>

<p>The CI broker does not itself run CI. It invokes a separate program,
the “adapter”, which is given the event that triggered CI. The adapter either
executes the run itself, or uses an external CI system to execute it.
This allows Radicle to support a variety of CI systems, by writing a
simple adapter for each.</p>

<p>I have written a CI engine for myself,
<a href="https://ambient.liw.fi/">Ambient</a>, and the adapter for that
(<code class="language-plaintext highlighter-rouge">radicle-ci-ambient</code>), and that is what I use.</p>

<p>There are adapters for running CI locally on the host or in a
container, GitHub actions, Woodpecker, and several others. See <a href="https://app.radicle.xyz/nodes/radicle.liw.fi/rad:zwTxygwuz5LDGBq255RA2CbNGrz8/tree/README.md"><code class="language-plaintext highlighter-rouge">CI
broker
README.md</code></a>
and <a href="https://explorer.radicle.gr/nodes/seed.radicle.gr/rad:z4Uh671FzoooaHjLvmtW9BtGMF9qm">integration
documentation</a>
for a more complete list. The adapter interface is intentionally easy
to implement: it needs to read one line of JSON and write up to two
lines of JSON.</p>

<h1 id="the-sample-project">The sample project</h1>

<p>This blog post is about Radicle, so I’m going to use a “hello world”
program as an example. This avoids getting mired into the details of
implementing something useful.</p>

<p>First I create a Git repository with a Rust project. I choose Rust,
because I like Rust, but the programming language is irrelevant here.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cargo init liw-hello
    Creating binary (application) package
... some text removed
$ cd liw-hello
$ git add .
$ git commit -m "chore: cargo init"
[main (root-commit) 5037847] chore: cargo init
 3 files changed, 10 insertions(+)
 create mode 100644 .gitignore
 create mode 100644 Cargo.toml
 create mode 100644 src/main.rs
</code></pre></div></div>

<p>Then I edit the <code class="language-plaintext highlighter-rouge">src/main.rs</code> file to have some useful content,
including unit tests:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>fn main() {
    let greeting = Greeting::default()
        .greeting("hello")
        .whom("world");
    println!("{}", greeting.greet());
}

struct Greeting {
    greeting: String,
    whom: String,
}

impl Default for Greeting {
    fn default() -&gt; Self {
        Self {
            greeting: "howdy".into(),
            whom: "partner".into(),
        }
    }
}

impl Greeting {
    fn greeting(mut self, s: &amp;str) -&gt; Self {
        self.greeting = s.into();
        self
    }

    fn whom(mut self, s: &amp;str) -&gt; Self {
        self.whom = s.into();
        self
    }

    fn greet(&amp;self) -&gt; String {
        format!("{} {}", self.greeting, self.whom)
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn default() {
        let g = Greeting::default();
        assert!(!g.greeting.is_empty());
        assert!(!g.whom.is_empty());
    }

    #[test]
    fn sets_greeting() {
        let g = Greeting::default().greeting("hi");
        assert_eq!(g.greet(), "hi partner");
    }

    #[test]
    fn sets_whom() {
        let g = Greeting::default().whom("there");
        assert_eq!(g.greet(), "howdy there");
    }
}
</code></pre></div></div>

<p>To commit that, I actually use Emacs with Magit for this, but I also often use
the command line, which I show here.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git commit -am "feat: implement greeting"
</code></pre></div></div>

<p>Once I have a Git repository with at least one commit, I can create a
Radicle repository for that. I do that on the command line. The <code class="language-plaintext highlighter-rouge">rad
init</code> command asks the user some questions. The answers could be
provided via option, which is useful for testing, but not something I
usually do when using the program.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ rad init

Initializing radicle 👾 repository in /home/liw/radicle/liw-hello..

✓ Name liw-hello
✓ Description Sample program for blog post about Radicle and its CI
✓ Default branch main
✓ Visibility public
✓ Repository liw-hello created.

Your Repository ID (RID) is rad:z3dhWQMH8J6nX3Qo97o5oSFMTfgyr.
You can show it any time by running `rad .` from this directory.

◤ Uploaded to z6MksCgjxU4VZt6qgtZntdikhtXFbsfvKRLPzpKtfCY4rAHR, 0 peer(s) remaining..
✓ Repository successfully synced to z6MksCgjxU4VZt6qgtZntdikhtXFbsfvKRLPzpKtfCY4rAHR
✓ Repository successfully synced to 1 node(s).

Your repository has been synced to the network and is now discoverable by peers.
Unfortunately, you were unable to replicate your repository to your preferred seeds.
To push changes, run `git push`.
</code></pre></div></div>

<p>There you go. I now have a Radicle repository to play with. As of
publishing this blog post, the repository is alive on the Radicle
network, if you want to <a href="https://app.radicle.xyz/nodes/radicle.liw.fi/rad:z3dhWQMH8J6nX3Qo97o5oSFMTfgyr">look at
it</a>
or clone it.</p>

<h1 id="ci-configuration-in-the-repository">CI configuration in the repository</h1>

<p>To use Radicle CI with Ambient, I need to create
<code class="language-plaintext highlighter-rouge">.radicle/ambient.yaml</code>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>plan:
  - action: cargo_clippy
  - action: cargo_test
</code></pre></div></div>

<p>This tells Ambient to run <code class="language-plaintext highlighter-rouge">cargo clippy</code> and <code class="language-plaintext highlighter-rouge">cargo test</code>, albeit with
additional command line arguments.</p>

<p>This is specific to Ambient, and the Ambient adapter for Radicle CI,
but similar files are needed for every CI system. The Radicle CI
broker does not try hide this variance: it’s important that you, as
the developer using a specific CI system, get full access to it, even
when you use it through Radicle CI. If the CI broker added a layer
above that it would only cause confusion and irritation.</p>

<h1 id="running-ci-locally">Running CI locally</h1>

<p>I find the most frustrating part of using CI to be to wait for a CI
run to finish on a server and then try to deduce from the run log what
went wrong. I’ve alleviated this by writing an extension to <code class="language-plaintext highlighter-rouge">rad</code> to
run CI locally:
<a href="https://app.radicle.xyz/nodes/radicle.liw.fi/rad%3Az6QuhJTtgFCZGyQZhRMZmZKJ3SVG"><code class="language-plaintext highlighter-rouge">rad-ci</code></a>.
It can produce a huge amount of output, so I’ve abbreviated that
below.</p>

<p><code class="language-plaintext highlighter-rouge">rad</code> supports extensions like <code class="language-plaintext highlighter-rouge">git</code> does: if you run <code class="language-plaintext highlighter-rouge">rad foo</code> and
<code class="language-plaintext highlighter-rouge">foo</code> isn’t built into <code class="language-plaintext highlighter-rouge">rad</code>, then <code class="language-plaintext highlighter-rouge">rad</code> will try to run <code class="language-plaintext highlighter-rouge">rad-foo</code>
instead. <code class="language-plaintext highlighter-rouge">rad-ci</code> can thus be invoked as <code class="language-plaintext highlighter-rouge">rad ci</code>, which I use in the
example below.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ rad ci
...
    RUN: Action CargoClippy
    SPAWN: argv=["cargo", "clippy", "--offline", "--locked", "--workspace", "--all-targets", "--no-deps", "--", "--deny", "warnings"]
           cwd=/workspace/src (exists? true)
           extra_env=[("CARGO_TARGET_DIR", "/workspace/cache"), ("CARGO_HOME", "/workspace/deps"), ("PATH", "/root/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin")]
        Checking liw-hello v0.1.0 (/workspace/src)
        Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.15s
    RUN: Action finished OK
    RUN: Action CargoTest
    SPAWN: argv=["cargo", "test", "--offline", "--locked", "--workspace"]
           cwd=/workspace/src (exists? true)
           extra_env=[("CARGO_TARGET_DIR", "/workspace/cache"), ("CARGO_HOME", "/workspace/deps"), ("PATH", "/root/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin")]
       Compiling liw-hello v0.1.0 (/workspace/src)
        Finished `test` profile [unoptimized + debuginfo] target(s) in 0.18s
         Running unittests src/main.rs (/workspace/cache/debug/deps/liw_hello-9c44d33bbe6cdc80)

    running 3 tests
    test test::default ... ok
    test test::sets_greeting ... ok
    test test::sets_whom ... ok

    test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

    RUN: Action finished OK
    RUN: Action TarCreate {
        archive: "/dev/vde",
        directory: "/workspace/cache",
    }
    RUN: Action finished OK
    RUN: Action TarCreate {
        archive: "/dev/vdd",
        directory: "/workspace/artifacts",
    }
    RUN: Action finished OK
    ambient-execute-plan ends
    EXIT CODE: 0
    [2025-07-04T05:48:23Z INFO  ambient] ambient ends successfully

Everything went fine.
</code></pre></div></div>

<p>(I’ve used the voluminous output to help debug <code class="language-plaintext highlighter-rouge">rad-ci</code>, but now that
it is stable, I should reduce the volume by default. A cobbler’s
children may have no shoes but a programmer’s tool has unnecessary
debug output.)</p>

<p>I find this ability to emulate what happens in CI on a server to be
very useful. To start with, I can use the resources I have locally, on
my laptop. I don’t need to compete with the shared server with other
people. I don’t have to wait for the CI server to have time for me. I
also don’t need to commit changes, which is another little source of
friction removed from the edit-ci-debug cycle.</p>

<p>For Ambient I intend to add support when it’s run locally (as <code class="language-plaintext highlighter-rouge">rad-ci</code>
does), and there’s a failure, the developer can log into the
environment and have hands-on access. This will make debugging a
failure under CI much easier than pushing changes to add more output
to the run log to help figure out what the problem is. But that isn’t
implemented yet: I only have 86400 seconds per day, most days.</p>

<h1 id="ci-configuration-on-my-ci-node">CI configuration on my CI node</h1>

<p>I love being able to run CI locally, but it is not sufficient. One
important aspect of a shared CI is that everyone uses the same
environment, with the same versions of everything. A server can also
deliver or deploy changes, as needed.</p>

<p>I’ve configured a second node, <a href="https://ci0.liw.fi/">ci0</a>, where I run
the CI broker and Ambient for all the public projects I have or
participate in. The actual server is a small desktop PC I have, which
is quiet and uses fairly little power, especially when idle. The HTML
report pages get published on a public server, for the amusement of
others.</p>

<p>My CI broker configuration is such that I don’t need to change it for
every new project. I only need to make sure the repository is on the
CI node, and the repository has a <code class="language-plaintext highlighter-rouge">.radicle/ambient.yaml</code> file.</p>

<p>To seed, I run this on the CI node:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rad seed rad:z3dhWQMH8J6nX3Qo97o5oSFMTfgyr
</code></pre></div></div>

<p>That’s the repository ID for my sample project. I run <code class="language-plaintext highlighter-rouge">rad .</code> in the
working directory to find out what it is. Because finding out the ID
is so easy, I never bother to make note of it when creating a repository.</p>

<h1 id="reporting-an-issue">Reporting an issue</h1>

<p>The <code class="language-plaintext highlighter-rouge">rad</code> tool can open issues from the command line, but for issue
management I’ve moved to using <a href="https://radicle.xyz/desktop">the desktop
application</a>. In the screenshot below I
open an issue about the default greeting.</p>

<p><img src="/assets/images/blog/radicle-desktop-new-issue-scaled.png" class="screenshot" /></p>

<p>In the above picture I show how I open a new issue for the sample
repository, saying the greeting is not the usual “hello world”
greeting.</p>

<h1 id="making-a-change">Making a change</h1>

<p>To make a change to the project, I make a branch, commit some changes,
then create a Radicle patch.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ git switch -c change
Switched to a new branch 'change'
$ git commit -am "feat: change greeting"
[change d19c898] feat: change greeting
 1 file changed, 2 insertions(+), 2 deletions(-)
$ git push rad HEAD:refs/patches
✓ Patch fd552417cc9a66c6aac1b6c8c717996bea741bfd opened
✓ Synced with 11 seed(s)

 * [new reference]   HEAD -&gt; refs/patches
</code></pre></div></div>

<p>The last command above pushes the branch to Radicle, via the special
<code class="language-plaintext highlighter-rouge">rad</code> remote, and instructs the <code class="language-plaintext highlighter-rouge">rad</code> Git remote helper to create a
Radicle patch instead of a branch. The <code class="language-plaintext highlighter-rouge">refs/patches</code> name is special
and magic. The <code class="language-plaintext highlighter-rouge">git-remote-rad</code> helper program understands it as a
request to create a new patch.</p>

<p>This makes a change in the local node, which by default then
automatically syncs it with other nodes it’s connected to, if they
have the same repository. My laptop node is connected to the CI node,
so that happens immediately.</p>

<p>As soon as the new patch lands in the CI node, the CI broker triggers
a new CI run, which fails. I can go to the <a href="https://ci0.liw.fi/z3dhWQMH8J6nX3Qo97o5oSFMTfgyr.html">web page updated by the CI
broker</a> and see
what the problem is. The patch diff is:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>diff --git a/src/main.rs b/src/main.rs
index a79818f..216bab7 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -11,8 +11,8 @@ struct Greeting {
 impl Default for Greeting {
     fn default() -&gt; Self {
         Self {
-            greeting: "howdy".into(),
-            whom: "partner".into(),
+            greeting: "hello".into(),
+            whom: "world".into(),
         }
     }
 }
</code></pre></div></div>

<p>The problem is that tests assume the original default:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>---- test::sets_greeting stdout ----

thread 'test::sets_greeting' panicked at src/main.rs:50:9:
assertion `left == right` failed
  left: "hi world"
 right: "hi partner"
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

---- test::sets_whom stdout ----

thread 'test::sets_whom' panicked at src/main.rs:56:9:
assertion `left == right` failed
  left: "hello there"
 right: "howdy there"


failures:
    test::sets_greeting
    test::sets_whom

test result: FAILED. 1 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
</code></pre></div></div>

<p>I change the tests, run the tests locally, run <code class="language-plaintext highlighter-rouge">rad ci</code> locally, and
commit the fix..</p>

<p>I then push the fix to the patch. The push default for this branch was
set to the Radicle patch, which makes pushing easier.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ git push
✓ Patch fd55241 updated to revision 8d1f8c69dc0f8028d8b1bb9e336240febaf2d1f4
To compare against your previous revision 3180ddd, run:

   git range-diff c3f02b43830578c93edd83a23ee2902899fdb159 17cda244d2e78bdeffd0647b20f315726bebf605 2a82eb0326179b60664ffeeac3ee062a5adfdcd6

✓ Synced with 13 seed(s)

  https://app.radicle.xyz/nodes/ci0/rad:z3dhWQMH8J6nX3Qo97o5oSFMTfgyr/patches/fd552417cc9a66c6aac1b6c8c717996bea741bfd

To rad://z3dhWQMH8J6nX3Qo97o5oSFMTfgyr/z6MkgEMYod7Hxfy9qCvDv5hYHkZ4ciWmLFgfvm3Wn1b2w2FV
   17cda24..2a82eb0  change -&gt; patches/fd552417cc9a66c6aac1b6c8c717996bea741bfd
</code></pre></div></div>

<p>I wait for CI to run. It is a SUCCESS!</p>

<p>I still need to merge the fix to the <code class="language-plaintext highlighter-rouge">main</code> branch. This will also
automatically mark the branch as merged for Radicle.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ rad patch
╭───────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ ●  ID       Title                                    Author         Reviews  Head     +    -   Updat… │
├───────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ ●  fd55241  ci: add configuration Radicle + Ambient  liw     (you)  -        2a82eb0  +14  -4  1 min… │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────╯
$ git switch main
Switched to branch 'main'
$ git merge change
Updating 54d2c9c..2a82eb0
Fast-forward
 Cargo.lock  | 7 +++++++
 src/main.rs | 8 ++++----
 2 files changed, 11 insertions(+), 4 deletions(-)
 create mode 100644 Cargo.lock
$ git push
✓ Patch fd552417cc9a66c6aac1b6c8c717996bea741bfd merged
✓ Canonical head updated to 2a82eb0326179b60664ffeeac3ee062a5adfdcd6
✓ Synced with 13 seed(s)

  https://app.radicle.xyz/nodes/ci0/rad:z3dhWQMH8J6nX3Qo97o5oSFMTfgyr/tree/2a82eb0326179b60664ffeeac3ee062a5adfdcd6

To rad://z3dhWQMH8J6nX3Qo97o5oSFMTfgyr/z6MkgEMYod7Hxfy9qCvDv5hYHkZ4ciWmLFgfvm3Wn1b2w2FV
   c3f02b4..2a82eb0  main -&gt; main
$ rad patch
Nothing to show.
$ delete-merged
Deleted branch change (was 2a82eb0).
</code></pre></div></div>

<p>(The last command is a little helper script that deletes any local
branches that have been merged into the default branch. I don’t like
to have a lot of merged branches around to confuse me.)</p>

<p>I could have avoided this round trip via the server by running <code class="language-plaintext highlighter-rouge">rad
ci</code>, or at least <code class="language-plaintext highlighter-rouge">cargo test</code>, before creating the patch, but I was
confident that I can’t make a mistake in an example this simple. This
is why CI is needed: to keep in control the hubris of someone who has
been programming for decades.</p>

<h1 id="installing">Installing</h1>

<p>To install Radicle itself, the <a href="https://radicle.xyz/#get-started">official
instructions</a> will get you <code class="language-plaintext highlighter-rouge">rad</code> and
<code class="language-plaintext highlighter-rouge">radicle-node</code>. The <a href="https://radicle.xyz/desktop">Radicle desktop
application</a> has it’s own installation
instructions.</p>

<p>There are instructions for installing <a href="https://radicle-ci.liw.fi/radicle-ci-broker/userguide.html#installing-radicle-ci-with-ambient-on-debian">Radicle CI (for
Debian)</a>,
but not other systems, since I only use Debian. I would very much
appreciate help with expanding that documentation.</p>

<p>It’s probably easiest to install
<a href="https://app.radicle.xyz/nodes/radicle.liw.fi/rad:z6QuhJTtgFCZGyQZhRMZmZKJ3SVG"><code class="language-plaintext highlighter-rouge">rad-ci</code></a>
from source code or with <code class="language-plaintext highlighter-rouge">cargo install</code>, but I have a <code class="language-plaintext highlighter-rouge">deb</code> package
for those using Debian or derivatives in my <a href="http://apt.liw.fi/">APT
repository</a>.</p>

<h1 id="conclusion">Conclusion</h1>

<p>I’ve used CI systems since 2010, starting with Jenkins, just after it
got renamed from Hudson. I’ve written about four CI engines myself,
depending on how you count rewrites. With Radicle and Ambient I am
finally getting to a development experience where CI is not actively
irritating, even if is not yet fun.</p>

<p>A CI system that’s a joy to use, that sounds like a fantasy. What
would it even be like? What would make using a CI system joyful to
you?</p>]]></content><author><name>lars</name></author><summary type="html"><![CDATA[In this blog post I show how I use Radicle and its CI support for my own software development. I show how I start a project, add it to Radicle, add CI support for it, and manage patches and issues.]]></summary></entry><entry><title type="html">Radicle 1.2.1</title><link href="https://radicle.xyz/2025/07/17/radicle-1.2.1.html" rel="alternate" type="text/html" title="Radicle 1.2.1" /><published>2025-07-17T00:00:00+01:00</published><updated>2025-07-17T00:00:00+01:00</updated><id>https://radicle.xyz/2025/07/17/radicle-1.2.1</id><content type="html" xml:base="https://radicle.xyz/2025/07/17/radicle-1.2.1.html"><![CDATA[<p>The Radicle team is delighted to announce the release of Radicle 1.2.1 (29043134a). This release contains 50 commits by 11 contributors. It’s amazing to see that we continue to have contributors in the double digits – thank you for your time and effort ✨</p>

<h2 id="installation">Installation</h2>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl -sSf https://radicle.xyz/install | sh -s -- --no-modify-path --version=1.2.1
</code></pre></div></div>

<h2 id="migration-of-node-dns-names-action-required">Migration of Node DNS Names (Action Required)</h2>

<p>The DNS names for <code class="language-plaintext highlighter-rouge">seed.radicle.garden</code> and <code class="language-plaintext highlighter-rouge">ash.radicle.garden</code> are being slowly migrated to <code class="language-plaintext highlighter-rouge">iris.radicle.xyz</code> and <code class="language-plaintext highlighter-rouge">rosa.radicle.xyz</code>, respectively. This in an effort to unify these nodes under their <code class="language-plaintext highlighter-rouge">radicle.xyz</code> domain, leaving room for other things to live under <code class="language-plaintext highlighter-rouge">radicle.garden</code>.</p>

<p>You will notice that if you still use the old DNS names, then you will get a warning during <code class="language-plaintext highlighter-rouge">rad node status</code> or <code class="language-plaintext highlighter-rouge">rad debug</code>. The old names will continue to work, but we encourage you to change these entries to avoid any future errors.</p>

<h2 id="rad-node-connect-nid"><code class="language-plaintext highlighter-rouge">rad node connect &lt;nid&gt;</code></h2>

<p>Did you hate specifying the node’s address when wanting to connect? For example:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rad node connect z6Mkmqogy2qEM2ummccUthFEaaHvyYmYBYh3dbe9W4ebScxo@rosa.radicle.xyz:8776
</code></pre></div></div>

<p>Well, with <code class="language-plaintext highlighter-rouge">1.2.1</code> you can now simply use the Node ID, i.e. <code class="language-plaintext highlighter-rouge">z6Mkmqogy2qEM2ummccUthFEaaHvyYmYBYh3dbe9W4ebScxo</code> in the above, and it will attempt to look up the known address for that node and connect to it. One less thing to try and copy and paste 😌</p>

<h2 id="patch-review-improvements">Patch Review Improvements</h2>

<p>The summaries of reviews on patches were lacking a little pizzazz. They have received some love to allow them have an edit history, as well as contain embeds.</p>

<p><strong>Note</strong>: This change is backwards-compatible, however, there is no guarantee of forwards-compatibility. The evaluation of patches on previous versions may fail when they come across the improved edit action.</p>

<h2 id="improved-templates-for-comments-on-issues">Improved Templates for Comments on Issues</h2>

<p>When replying to or editing a comment in an issue, the comment text will now be prefilled with more helpful information, such as the the thread of comments you are replying to, including their author and ID. This should make it easier to contribute to a meaningful discussion.</p>

<h2 id="json-schemas">JSON Schemas</h2>

<p>We have published a developer tooling crate <a href="https://crates.io/crates/radicle-schemars">radicle-schemars</a> for emitting the JSON schemas of the <code class="language-plaintext highlighter-rouge">config.json</code> and the node’s command and command result types. For the former, you can generate it using <code class="language-plaintext highlighter-rouge">rad config schema</code>. For the latter, a CLI can be installed using:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cargo install radicle-schemars
</code></pre></div></div>

<p>You can use it to generate all three:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>radicle-schemars radicle::node::Command       # generate schema for commands
radicle-schemars radicle::node::CommandResult # generate schema for command results
radicle-schemars radicle::profile::Config      # generate schema for config
</code></pre></div></div>

<p>The idea for this crate and binary is to allow developers interacting with Radicle to generate types in their own languages – as opposed to a user facing tool.</p>

<h2 id="changelog">Changelog</h2>

<p>For a full list of changes, see below:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">29043134a</code> <strong>radicle: hotfix release 0.16.1</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">4e08eef8d</code> <strong>radicle: add missing <code class="language-plaintext highlighter-rouge">review_react</code> methods</strong> <em><a href="mailto:me@sebastinez.dev">me@sebastinez.dev</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">3a4700357</code> <strong>radicle: add ReviewEdit getter methods</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">b77809ae9</code> <strong>chore: prepare crates release</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">fe6a11d0d</code> <strong>radicle: fix schemars macro on FetchPackSizeLimit</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">4e429e440</code> <strong>radicle: Fix doctests</strong> <em><a href="mailto:erik@zirkular.io">erik@zirkular.io</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">34939253f</code> <strong>radicle: improve reviews</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">c30298fb8</code> <strong>radicle: implement std::error::Error for AnnouncerError</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">e965d9a2c</code> <strong>node: clean up <code class="language-plaintext highlighter-rouge">UploadError</code></strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">db3b3b054</code> <strong>flake: Delete Apps</strong> <em><a href="mailto:lorenz.leutgeb@radicle.xyz">lorenz.leutgeb@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">5a840983a</code> <strong>node, cli: Refactor test environment</strong> <em><a href="mailto:lorenz@leutgeb.xyz">lorenz@leutgeb.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">9e010068e</code> <strong>docs: Add issue instructions</strong> <em><a href="mailto:yorgos.work@proton.me">yorgos.work@proton.me</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">38ff2652b</code> <strong>radicle: remove unnecessary constraints</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">895ca5d02</code> <strong>cli: rad node connect using only NodeId</strong> <em><a href="mailto:johannes.kuehlewindt@gmail.com">johannes.kuehlewindt@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">76e00a34e</code> <strong>cli: change link direction symbols</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">84427a56b</code> <strong>radicle-term: Use crossterm instead of termion</strong> <em><a href="mailto:lorenz.leutgeb@radicle.xyz">lorenz.leutgeb@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">ee8ffcc79</code> <strong>radicle-term: Inline <code class="language-plaintext highlighter-rouge">termion::get_tty</code> for Unix</strong> <em><a href="mailto:lorenz.leutgeb@radicle.xyz">lorenz.leutgeb@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">ec47566cb</code> <strong>radicle-term: Remove custom pager</strong> <em><a href="mailto:lorenz.leutgeb@radicle.xyz">lorenz.leutgeb@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">570bfc3bb</code> <strong>debian: add missing env variables to debian build</strong> <em><a href="mailto:me@sebastinez.dev">me@sebastinez.dev</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">deb823f3b</code> <strong>flake: Fix path to crates</strong> <em><a href="mailto:lorenz.leutgeb@radicle.xyz">lorenz.leutgeb@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">e39653afc</code> <strong>build: Rewrite tagging script</strong> <em><a href="mailto:lorenz@leutgeb.xyz">lorenz@leutgeb.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">6f34124d4</code> <strong>radicle: improve config errors</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">6686f86c6</code> <strong>radicle: fix small typo</strong> <em><a href="mailto:me@sebastinez.dev">me@sebastinez.dev</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">d8d00666d</code> <strong>chore: remove radicle-tools</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">42285e71c</code> <strong>chore: remove radicle-crdt</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">78ba263d0</code> <strong>radicle-cli/issue: Improve comment templating</strong> <em><a href="mailto:lorenz.leutgeb@radicle.xyz">lorenz.leutgeb@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">af35e6f4d</code> <strong>radicle-cli: Warn when using old names of nodes</strong> <em><a href="mailto:lorenz.leutgeb@radicle.xyz">lorenz.leutgeb@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">727e4e72c</code> <strong>radicle-cli/debug: Use <code class="language-plaintext highlighter-rouge">BTreeMap</code> for consistent ordering</strong> <em><a href="mailto:lorenz.leutgeb@radicle.xyz">lorenz.leutgeb@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">1df8cf102</code> <strong>radicle/bootstrap: Add rosa.radicle.xyz</strong> <em><a href="mailto:lorenz.leutgeb@radicle.xyz">lorenz.leutgeb@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">a354686bb</code> <strong>chore: Remove <code class="language-plaintext highlighter-rouge">seed.radicle.xyz</code></strong> <em><a href="mailto:lorenz.leutgeb@radicle.xyz">lorenz.leutgeb@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">e30e66e00</code> <strong>radicle: add .external_template(false) to all other libgit2 calls</strong> <em><a href="mailto:jakob.kirsch@web.de">jakob.kirsch@web.de</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">ab62dce68</code> <strong>radicle: refactor Canonical</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">b2bcd561c</code> <strong>radicle: store threshold in Canonical</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">b614167bd</code> <strong>meta: relax radicle-git dependencies</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">6e9517a18</code> <strong>fix Debian package building after crates have moved into a sub-dir</strong> <em><a href="mailto:liw@liw.fi">liw@liw.fi</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">5bc2dc677</code> <strong>repo: Move workspace crates into <code class="language-plaintext highlighter-rouge">crates</code> subdirectory</strong> <em><a href="mailto:lorenz.leutgeb@radicle.xyz">lorenz.leutgeb@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">6259a7032</code> <strong>cargo: Use <code class="language-plaintext highlighter-rouge">workspace.package</code> table</strong> <em><a href="mailto:lorenz.leutgeb@radicle.xyz">lorenz.leutgeb@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">eea6a9bc7</code> <strong>cargo: Clean up dependencies</strong> <em><a href="mailto:lorenz.leutgeb@radicle.xyz">lorenz.leutgeb@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">d50df68b7</code> <strong>chore: Remove dependency <code class="language-plaintext highlighter-rouge">once_cell</code></strong> <em><a href="mailto:lorenz.leutgeb@radicle.xyz">lorenz.leutgeb@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">3bc0db68f</code> <strong>doc: Add <code class="language-plaintext highlighter-rouge">CHANGELOG.md</code></strong> <em><a href="mailto:lorenz.leutgeb@radicle.xyz">lorenz.leutgeb@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">0fd8c8be4</code> <strong>github: Add README.md</strong> <em><a href="mailto:lorenz.leutgeb@radicle.xyz">lorenz.leutgeb@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">bac719da2</code> <strong>bootstrap: Migrate radicle.garden → radicle.xyz</strong> <em><a href="mailto:lorenz.leutgeb@radicle.xyz">lorenz.leutgeb@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">9d4aa59a1</code> <strong>radicle: add .external_template(false) to libgit2 call</strong> <em><a href="mailto:jakob.kirsch@web.de">jakob.kirsch@web.de</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">a8ab718b9</code> <strong>chore(debian/changelog): update package version to match upstream</strong> <em><a href="mailto:me@sebastinez.dev">me@sebastinez.dev</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">7380e2118</code> <strong>chore(debian/control): add sebastinez to Uploaders</strong> <em><a href="mailto:me@sebastinez.dev">me@sebastinez.dev</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">eceb7f29c</code> <strong>cob: Simplify the ChangeGraph implementation</strong> <em><a href="mailto:leon.zach@posteo.de">leon.zach@posteo.de</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">4cd0782f2</code> <strong>radicle-schemars: Add crate for utility binary</strong> <em><a href="mailto:lorenz.leutgeb@radicle.xyz">lorenz.leutgeb@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">fcd1acd1d</code> <strong>radicle/schemars: Annotate Commands and results</strong> <em><a href="mailto:lorenz.leutgeb@radicle.xyz">lorenz.leutgeb@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">05368e84f</code> <strong>cargo: Make schemars a workspace dependency</strong> <em><a href="mailto:lorenz.leutgeb@radicle.xyz">lorenz.leutgeb@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">9dae540c8</code> <strong>systemd: Provide user service for radicle-node</strong> <em><a href="mailto:tippfehlr@tippfehlr.dev">tippfehlr@tippfehlr.dev</a></em>
    <h2 id="checksums">Checksums</h2>
  </li>
</ul>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>08ba01a0c60599a97ef7ed117585c3d9ff2ffe3820e8adb63f45e0e4fb5ac3f3  radicle-1.2.1-aarch64-unknown-linux-musl.tar.xz
e3df804ef2d94e2b3d4b1ba9e6077f7c1a4c61881f1be6d1bd33179293d25c5a  radicle-1.2.1-x86_64-unknown-linux-musl.tar.xz
dcd246d6917a2d95cc8763b060ecf060236d4d37f1ea28bbf0d55fb952b8c2d7  radicle-1.2.1-x86_64-apple-darwin.tar.xz
45c46e1bd88d20a3ef14bde6d331bed229f2c8b2ff3a2e84dbd7274ef6b8a296  radicle-1.2.1-aarch64-apple-darwin.tar.xz
</code></pre></div></div>]]></content><author><name></name></author><summary type="html"><![CDATA[The Radicle team is delighted to announce the release of Radicle 1.2.1 (29043134a). This release contains 50 commits by 11 contributors. It’s amazing to see that we continue to have contributors in the double digits – thank you for your time and effort ✨]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://radicle.xyz/radicle-1.png" /><media:content medium="image" url="https://radicle.xyz/radicle-1.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Radicle Desktop 🖥️</title><link href="https://radicle.xyz/2025/06/13/radicle-desktop.html" rel="alternate" type="text/html" title="Radicle Desktop 🖥️" /><published>2025-06-13T00:00:00+01:00</published><updated>2025-06-13T00:00:00+01:00</updated><id>https://radicle.xyz/2025/06/13/radicle-desktop</id><content type="html" xml:base="https://radicle.xyz/2025/06/13/radicle-desktop.html"><![CDATA[<p>Today, we’re excited to officially introduce Radicle Desktop - a simple, intuitive desktop app that makes contributing to the Radicle network easier than ever.</p>

<p><img src="/assets/images/blog/radicle-desktop-repo-home.png" alt="Radicle Desktop" /></p>

<p>Since Radicle reached version 1.0 in September last year, we’ve been focused on improving the overall user experience. We believe the Radicle network becomes more valuable the more people participate - and Radicle Desktop is a step toward making that participation more accessible, without making any compromises.</p>

<h2 id="try-it-out-">Try it out! 🪄</h2>

<p>Head over to <a href="https://radicle.xyz/desktop">radicle.xyz/desktop</a> to find the install instructions including packaged versions for major distributions.</p>

<h2 id="what-is-radicle-desktop">What is Radicle Desktop?</h2>

<p><img src="/assets/images/blog/radicle-desktop-pr.png" alt="Radicle Desktop" /></p>

<p>Radicle Desktop is a graphical interface built to simplify some of the more complex parts of the Radicle experience, such as issue management and patch reviews. It offers a familiar experience to other forges, giving you an overview of all the repositories on your node, and allowing you to manage issues and collaborate on patches seamlessly.</p>

<h2 id="what-radicle-desktop-currently-is-not">What Radicle Desktop (currently) is not</h2>

<p>Radicle Desktop is not trying to replace your terminal, IDE, or code editor - you already have your preferred tools for code browsing. It won’t replace our existing <a href="https://app.radicle.xyz">app.radicle.xyz</a> and <a href="https://search.radicle.xyz">search.radicle.xyz</a> for finding and exploring projects. It also doesn’t run a node for you. Instead, it communicates with your existing Radicle node, supporting your current workflow and encourages gradual adoption.</p>

<h2 id="why-were-excited-">Why we’re excited 🎊</h2>

<p>Radicle Desktop marks the latest addition to the growing Radicle ecosystem. A lot of work has gone into this release, and we’re happily using Radicle Desktop ourselves for some time now. We also want to extend a big thank you to everyone who tried the earlier versions - the feedback has been immensely valuable. Even some of the CLI fans admit that certain workflows are better in the app.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[Today, we’re excited to officially introduce Radicle Desktop - a simple, intuitive desktop app that makes contributing to the Radicle network easier than ever.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://radicle.xyz/radicle-1.png" /><media:content medium="image" url="https://radicle.xyz/radicle-1.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Radicle 1.2</title><link href="https://radicle.xyz/2025/06/02/radicle-1.2.html" rel="alternate" type="text/html" title="Radicle 1.2" /><published>2025-06-02T00:00:00+01:00</published><updated>2025-06-02T00:00:00+01:00</updated><id>https://radicle.xyz/2025/06/02/radicle-1.2</id><content type="html" xml:base="https://radicle.xyz/2025/06/02/radicle-1.2.html"><![CDATA[<p>The Radicle team is delighted to announce the release of Radicle 1.2. This
release contains 106 commits by 16 contributors 📈.</p>

<p>To upgrade or install, head to the <a href="/download">download</a> section, or run the
following command from your terminal:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl -sSf https://radicle.xyz/install | sh -s -- --version=1.2.0
</code></pre></div></div>

<p><strong>Huge</strong> thanks to all the contributors, many of which are contributors from outside of the team. We appreciate the community that is being built here 🌱</p>

<p>Thank you to:</p>
<ul>
  <li>🌱 Derick Eddington</li>
  <li>🌱 Ivan Stanković</li>
  <li>🌱 Lars Wirzenius</li>
  <li>🌱 Leah Neukirchen</li>
  <li>🌱 Richard Levitte</li>
  <li>🌱 Sebastian Martinez</li>
  <li>🌱 Sekhat Temporus</li>
  <li>🌱 Yorgos Saslis</li>
  <li>🌱 tippfehlr</li>
</ul>

<h2 id="improved-repository-timings">Improved Repository Timings</h2>

<p>There has been a huge improvement in initialising larger repositories. This was, unfortunately, due to <code class="language-plaintext highlighter-rouge">libgit2</code> being a lot slower than <code class="language-plaintext highlighter-rouge">git</code> when performing file protocol push and fetches (thanks for <a href="https://github.com/libgit2/libgit2/issues/2836">creating an issue</a> 10 years ago Linus).</p>

<h2 id="better-rad-sync-output">Better <code class="language-plaintext highlighter-rouge">rad sync</code> Output</h2>

<p>There has been a concerted effort to improve the fetching and announcing output when using <code class="language-plaintext highlighter-rouge">rad sync</code>. This also helped us improve <code class="language-plaintext highlighter-rouge">rad clone</code> which should not include many error messages, while also succeeding.</p>

<h2 id="breaking-changes">Breaking Changes</h2>

<p>No breaking changes, as far as we are aware. Please report any issues via Radicle or message us on <a href="radicle.zulipchat.com">Zulip</a>.</p>

<h2 id="general-improvements">General Improvements</h2>

<h3 id="cli">CLI</h3>

<ul>
  <li>Output JSON lines for <code class="language-plaintext highlighter-rouge">rad cob</code></li>
  <li>Allow showing multiple COBs at once</li>
  <li>Improvements to help documentation</li>
  <li>The full set of actions for patches are now available via <code class="language-plaintext highlighter-rouge">rad patch</code></li>
  <li>Better error context when <code class="language-plaintext highlighter-rouge">ssh-agent</code> connection fails</li>
  <li>The remote helper will print <code class="language-plaintext highlighter-rouge">git range-diff</code>s when creating new patch revisions</li>
  <li><code class="language-plaintext highlighter-rouge">rad seed</code> and <code class="language-plaintext highlighter-rouge">rad unseed</code> can now take multiple RIDs</li>
  <li><code class="language-plaintext highlighter-rouge">rad cob [create | update]</code> have been added</li>
  <li><code class="language-plaintext highlighter-rouge">rad config schema</code> for emitting a JSONSchema of the configuration</li>
  <li>Better syntax highlighting</li>
  <li><code class="language-plaintext highlighter-rouge">rad cob show</code> handles broken pipes</li>
  <li>Avoiding obtaining a signer when it is not necessary</li>
  <li>Print node addresses when syncing</li>
</ul>

<h3 id="library">Library</h3>

<ul>
  <li>Patch revisions can now be labelled and resolve comments</li>
  <li>Issues can be listed by status</li>
  <li>Extend the set of emojis that are supported</li>
  <li>Provide an API to do a reverse lookup from aliases to NIDs</li>
  <li>Use <code class="language-plaintext highlighter-rouge">signals_receipts</code> crate for improved signal handling</li>
  <li>Integrate more up-to-date Gitoxide crates</li>
  <li>Ensuring an MSRV of 1.81</li>
</ul>

<h2 id="changelog">Changelog</h2>

<p>Here is the full Radicle 1.2 changelog.</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">6f25d73d</code> <strong>build: remove quotes from rust-version</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">e9cf91e1</code> <strong>cob: bump major version</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">e6ef767f</code> <strong>radicle: remove job cob</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">f4c8ff7a</code> <strong>chore: prepare crates release</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">caf9e241</code> <strong>cli: fix outputs</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">ae1165fa</code> <strong>build: do not assume <code class="language-plaintext highlighter-rouge">rad</code> remote</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">edcfcae7</code> <strong>build: fix ssh symlinking</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">40e9b7ba</code> <strong>build: update cargo-zigbuild version to 0.20</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">7dcfe457</code> <strong>build: Dockerfile uses Rust version from <code class="language-plaintext highlighter-rouge">rust-toolchain.toml</code></strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">924b9328</code> <strong>cli: change announcement message</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">d1ba665e</code> <strong>radicle: introduce sync::announce tests</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">aa7dcd92</code> <strong>radicle: use a struct to help announce success counts</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">5a0c14cf</code> <strong>radicle: ensure preferred seeds are announced to</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">c57d43f2</code> <strong>radicle: schemars test should be behind feature flag</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">5b4cbc2c</code> <strong>radicle: introduce announcer</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">fa9c6cd1</code> <strong>radicle: move PrivateNetwork to <code class="language-plaintext highlighter-rouge">node::sync</code></strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">cc96b9ed</code> <strong>cli: improve rad clone</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">059c8045</code> <strong>radicle: fix build when schemars feature is not enabled</strong> <em><a href="mailto:aclopte@gmail.com">aclopte@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">1a67ac18</code> <strong>cli: reword sync replicas help</strong> <em><a href="mailto:lorenz.leutgeb@radicle.xyz">lorenz.leutgeb@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">eec4dd45</code> <strong>radicle: improve sync fetching</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">c205322c</code> <strong>node: fix e2e reader limit test</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">b608a788</code> <strong>cli: <code class="language-plaintext highlighter-rouge">rad config schema</code> emits JSON Schema</strong> <em><a href="mailto:n4ch7@r1v3nd311">n4ch7@r1v3nd311</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">5a2f26ea</code> <strong>cli/node/status: Redesign</strong> <em><a href="mailto:lorenz.leutgeb@radicle.xyz">lorenz.leutgeb@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">ee12f76c</code> <strong>cli/tests: Fix nextest running via Nix</strong> <em><a href="mailto:lorenz.leutgeb@radicle.xyz">lorenz.leutgeb@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">9988b63b</code> <strong>cob: abstract namespace identifier</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">1f4fcc5e</code> <strong>radicle: move to <code class="language-plaintext highlighter-rouge">signature</code> crate</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">41f9048d</code> <strong>nix: Add flake check that builds at MSRV</strong> <em><a href="mailto:lorenz@leutgeb.xyz">lorenz@leutgeb.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">105b65c2</code> <strong>workspace: set rust-version (MSRV)</strong> <em><a href="mailto:liw@liw.fi">liw@liw.fi</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">9f2c4e39</code> <strong>chore: use watch_file in .envrc</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">5a0a334d</code> <strong>build(debian/rules): install into a location where Debian expects</strong> <em><a href="mailto:liw@liw.fi">liw@liw.fi</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">e0d18b86</code> <strong>systemd: Add example configuration for DNS-SD</strong> <em><a href="mailto:lorenz@leutgeb.xyz">lorenz@leutgeb.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">98cf054b</code> <strong>git: Add .direnv to .gitignore</strong> <em><a href="mailto:lorenz@leutgeb.xyz">lorenz@leutgeb.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">f5fa84fa</code> <strong>test: set name and email for repository fixture</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">59a10214</code> <strong>hook: Make <code class="language-plaintext highlighter-rouge">cargo check</code> and <code class="language-plaintext highlighter-rouge">cargo clippy</code> only execute pre-push</strong> <em><a href="mailto:lorenz@leutgeb.xyz">lorenz@leutgeb.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">5553a147</code> <strong>cli/tests: Relax expectations in <code class="language-plaintext highlighter-rouge">rad-clone-partial-fail.md</code></strong> <em><a href="mailto:lorenz@leutgeb.xyz">lorenz@leutgeb.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">f30760d6</code> <strong>cob: Add CobAction::produces_identifier and validation</strong> <em><a href="mailto:lorenz@leutgeb.xyz">lorenz@leutgeb.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">e4d23fe5</code> <strong>cli: Introduce <code class="language-plaintext highlighter-rouge">cob [create|update]</code></strong> <em><a href="mailto:lorenz@leutgeb.xyz">lorenz@leutgeb.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">547614a5</code> <strong>cli-test: Add current working directory to PATH</strong> <em><a href="mailto:lorenz@leutgeb.xyz">lorenz@leutgeb.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">30182233</code> <strong>cli: Allow multiple RIDs for <code class="language-plaintext highlighter-rouge">rad unseed</code></strong> <em><a href="mailto:sekhat@temporus.me">sekhat@temporus.me</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">6bbe919c</code> <strong>cli: allow multiple RIDs for <code class="language-plaintext highlighter-rouge">rad seed</code></strong> <em><a href="mailto:sekhat@temporus.me">sekhat@temporus.me</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">a90aabb1</code> <strong>node: rate limiter for channel reads</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">f13afe49</code> <strong>remote-helper: Print <code class="language-plaintext highlighter-rouge">git range-diff</code> invocation</strong> <em><a href="mailto:lorenz@leutgeb.xyz">lorenz@leutgeb.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">6dcd5627</code> <strong>node: upload-pack inter-thread communication</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">ce8ac663</code> <strong>radicle: use <code class="language-plaintext highlighter-rouge">git fetch</code> over libigt2 in checkout</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">a9fa31e5</code> <strong>docs: add links to to README.md to home page and Zulip</strong> <em><a href="mailto:liw@liw.fi">liw@liw.fi</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">cbca3af2</code> <strong>chore: shellcheck fixes</strong> <em><a href="mailto:lorenz@leutgeb.xyz">lorenz@leutgeb.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">ce07e92a</code> <strong>Add Git pre-commit hooks via Nix</strong> <em><a href="mailto:lorenz@leutgeb.xyz">lorenz@leutgeb.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">77386b0f</code> <strong>build: Upload Git archive of heartwood</strong> <em><a href="mailto:lorenz@leutgeb.xyz">lorenz@leutgeb.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">10daedf9</code> **cli: Add ‘rad node inventory –nid <nid>'** *&lt;richard@levitte.org&gt;*</nid></li>
  <li><code class="language-plaintext highlighter-rouge">8fd04483</code> <strong>radicle: use <code class="language-plaintext highlighter-rouge">git push</code> to avoid <code class="language-plaintext highlighter-rouge">libgit2</code> push</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">433483e0</code> <strong>Add Lorenz Leutgeb to <code class="language-plaintext highlighter-rouge">.gitsigners</code></strong> <em><a href="mailto:lorenz@leutgeb.xyz">lorenz@leutgeb.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">dc1ff882</code> <strong>cli/sync: Also print node addresses</strong> <em><a href="mailto:lorenz@leutgeb.xyz">lorenz@leutgeb.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">72913b8c</code> <strong>fetch: integrate the latest <code class="language-plaintext highlighter-rouge">gix-protocol</code> into <code class="language-plaintext highlighter-rouge">radicle-fetch</code></strong> <em><a href="mailto:sebastian.thiel@icloud.com">sebastian.thiel@icloud.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">96637aca</code> <strong>chore: update rust-toolchain</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">47c785b9</code> <strong>signals: Use <code class="language-plaintext highlighter-rouge">signals_receipts</code> crate instead</strong> <em><a href="mailto:kcired@pm.me">kcired@pm.me</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">c05434eb</code> <strong>cli: add emoji picker to <code class="language-plaintext highlighter-rouge">rad issue react</code></strong> <em><a href="mailto:tippfehlr@gmail.com">tippfehlr@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">2af090ea</code> <strong>cli: fallible comment selector</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">7eb07e1b</code> <strong>chore(debian/changelog): update package version to match upstream</strong> <em><a href="mailto:liw@liw.fi">liw@liw.fi</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">13ba2ef0</code> <strong>fix(debian/rules): cargo install offline</strong> <em><a href="mailto:liw@liw.fi">liw@liw.fi</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">ebc8d037</code> <strong>ci(.radicle/ambient.yaml): CI plan for Radicle CI Ambient adapter</strong> <em><a href="mailto:liw@liw.fi">liw@liw.fi</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">9abedf44</code> <strong>cli: Don’t use ‘signer’ where not necessary</strong> <em><a href="mailto:richard@levitte.org">richard@levitte.org</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">538648c5</code> <strong>cli: document disallow and edit options in manpages</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">a5665412</code> <strong>Cargo.lock: update crossbeam-channel to 0.5.15</strong> <em><a href="mailto:istankovic@posteo.net">istankovic@posteo.net</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">9ef9c5d5</code> <strong>radicle: add Op::load method</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">c847a16e</code> <strong>radicle: return iterator types for db policies</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">7de82b50</code> <strong>radicle: use <code class="language-plaintext highlighter-rouge">Alias</code> in <code class="language-plaintext highlighter-rouge">follow</code></strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">6940ac42</code> <strong>radicle: reverse lookup for AliasStore</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">3dba4fbc</code> <strong>cli: cargo fmt</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">dd5f7396</code> <strong>radicle: generic Transaction::initial</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">170915ff</code> <strong>nix: Nix flake maintenance</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">c2863c08</code> <strong>radicle: extend emoji support</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">a9a4aac3</code> <strong>docs, cli: Mention feedback, also via e-mail</strong> <em><a href="mailto:lorenz@leutgeb.xyz">lorenz@leutgeb.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">a7230682</code> <strong>cli: provide error context for ssh-agent connect</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">ffc86f8a</code> <strong>build: ensure zigbuild install doesn’t break reproducible build</strong> <em><a href="mailto:yorgos.work@proton.me">yorgos.work@proton.me</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">3b5fac17</code> <strong>crypto: RefCell instead of Mutex in Agent</strong> <em><a href="mailto:lorenz@leutgeb.xyz">lorenz@leutgeb.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">62d000f7</code> <strong>radicle: fix <code class="language-plaintext highlighter-rouge">parse_ref_*</code> documentation</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">ee0d19f2</code> <strong>man: make a note on draft patches</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">4cced3dd</code> <strong>cli: add remaining patch actions</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">7d28d1e6</code> <strong>ci: don’t build docs for depedencies</strong> <em><a href="mailto:liw@liw.fi">liw@liw.fi</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">dfe89fb3</code> <strong>ci: only deny warnings, not all clippy lints</strong> <em><a href="mailto:liw@liw.fi">liw@liw.fi</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">a1cd0e2f</code> <strong>cli: Add <code class="language-plaintext highlighter-rouge">--title</code> and <code class="language-plaintext highlighter-rouge">--description</code> edit option</strong> <em><a href="mailto:yorgos.work@proton.me">yorgos.work@proton.me</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">f0390e00</code> <strong>cli: print success to console on <code class="language-plaintext highlighter-rouge">rad issue state</code></strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">ffbdabe4</code> <strong>cli: add comment edit for rad issue</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">98598746</code> <strong>radicle: add <code class="language-plaintext highlighter-rouge">list_by_status</code> method to <code class="language-plaintext highlighter-rouge">cob::issue::Issues</code></strong> <em><a href="mailto:me@sebastinez.dev">me@sebastinez.dev</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">7c902b69</code> <strong>radicle: Add <code class="language-plaintext highlighter-rouge">resolves</code> and <code class="language-plaintext highlighter-rouge">labels</code> method to <code class="language-plaintext highlighter-rouge">cob::patch::Revision</code></strong> <em><a href="mailto:me@sebastinez.dev">me@sebastinez.dev</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">65982434</code> <strong>radicle: document <code class="language-plaintext highlighter-rouge">parse_ref</code> and <code class="language-plaintext highlighter-rouge">parse_ref_namespaced</code></strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">41c33901</code> <strong>radicle: use rlim_t when working with limits</strong> <em><a href="mailto:leah@vuxu.org">leah@vuxu.org</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">c8062bc4</code> <strong>docs: note that node logs may also be in the system journal</strong> <em><a href="mailto:liw@liw.fi">liw@liw.fi</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">4c82bb4c</code> <strong>radicle: add some documentation for node::events::Event</strong> <em><a href="mailto:liw@liw.fi">liw@liw.fi</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">2929146c</code> <strong>radicle: clarify RefsAt description</strong> <em><a href="mailto:liw@liw.fi">liw@liw.fi</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">b6cf6fea</code> <strong>cli: Fix <code class="language-plaintext highlighter-rouge">rad ls</code> help message</strong> <em><a href="mailto:me@sebastinez.dev">me@sebastinez.dev</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">87cb7bf5</code> <strong>build: Update zig installation method</strong> <em><a href="mailto:yorgos.work@proton.me">yorgos.work@proton.me</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">87f6956e</code> <strong>build: Fixes to release script</strong> <em><a href="mailto:cloudhead@radicle.xyz">cloudhead@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">d274b28a</code> <strong>scripts: Small fix to contributor count</strong> <em><a href="mailto:cloudhead@radicle.xyz">cloudhead@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">d9c76893</code> <strong>cli: bump version to 0.12.1</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">19bbdbca</code> <strong>cli: fix syntax highlighting</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">7ed72ec9</code> <strong>cli: Fix some clippy lints</strong> <em><a href="mailto:cloudhead@radicle.xyz">cloudhead@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">61865b5b</code> <strong>cob: fix documentation</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">8e2fe644</code> <strong>scripts: Improve changelog script</strong> <em><a href="mailto:cloudhead@radicle.xyz">cloudhead@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">5fe3d5a7</code> <strong>cli: Handle broken pipe in <code class="language-plaintext highlighter-rouge">cob show</code></strong> <em><a href="mailto:cloudhead@radicle.xyz">cloudhead@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">7616dcb7</code> <strong>cli/cob: Output JSON Lines</strong> <em><a href="mailto:lorenz@leutgeb.xyz">lorenz@leutgeb.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">8865b559</code> <strong>cli/cob: Allow showing multiple COBs at once</strong> <em><a href="mailto:lorenz@leutgeb.xyz">lorenz@leutgeb.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">289e59bb</code> <strong>term: Bump version to 0.12.0</strong> <em><a href="mailto:cloudhead@radicle.xyz">cloudhead@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">b4f18f43</code> <strong>cli: Bump to 0.12.0</strong> <em><a href="mailto:lorenz@leutgeb.xyz">lorenz@leutgeb.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">1fa1cafe</code> <strong>cli: Update tree-sitter</strong> <em><a href="mailto:lorenz@leutgeb.xyz">lorenz@leutgeb.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">fd892d00</code> <strong>Update <code class="language-plaintext highlighter-rouge">radicle</code> to 0.14</strong> <em><a href="mailto:cloudhead@radicle.xyz">cloudhead@radicle.xyz</a></em></li>
</ul>

<h2 id="checksums">Checksums</h2>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>179cc84f9bca81cc6bec0a2b70d0a5fdd569db128973d755025022f81eeb07de  radicle-1.2.0-x86_64-unknown-linux-musl.tar.xz
63768853edd038bdb7dbf540c0ab9a6963cd6bf1bcf3e048d0eb0969544f5ffa  radicle-1.2.0-aarch64-unknown-linux-musl.tar.xz
3fdb2f97d9bab419c9f066f73b5f175284197ef3d1116e7d91428c1c672f1739  radicle-1.2.0-aarch64-apple-darwin.tar.xz
c2d45feebc9d7c71158e6c2430a3f39e3cd631323e496d3a9ce0625ce115ff0b  radicle-1.2.0-x86_64-apple-darwin.tar.xz
</code></pre></div></div>]]></content><author><name></name></author><summary type="html"><![CDATA[The Radicle team is delighted to announce the release of Radicle 1.2. This release contains 106 commits by 16 contributors 📈.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://radicle.xyz/radicle-1.png" /><media:content medium="image" url="https://radicle.xyz/radicle-1.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">How we used Radicle with GitHub Actions</title><link href="https://radicle.xyz/2025/05/30/radicle-with-github-actions.html" rel="alternate" type="text/html" title="How we used Radicle with GitHub Actions" /><published>2025-05-30T00:00:00+01:00</published><updated>2025-05-30T00:00:00+01:00</updated><id>https://radicle.xyz/2025/05/30/radicle-with-github-actions</id><content type="html" xml:base="https://radicle.xyz/2025/05/30/radicle-with-github-actions.html"><![CDATA[<p>A chat with <a href="https://app.radicle.xyz/nodes/seed.radicle.garden/users/did:key:z6MkrubmdTJKR42YZd7yDYysyx4JRez1wmvxjpmhzhTMKxsr">burrito</a> aka <a href="https://metafluff.com">Dietrich Ayala</a> today sparked the idea to write down how we started dogfooding Radicle before we had our native Radicle CI going. He also encouraged me to just set a deadline for writing blog posts in general, so this had to be written and published by the end of today.</p>

<p>We wanted to dogfood Radicle as soon as possible, but there was one caveat: we didn’t have a solution for CI at the time. So what we did was just reuse our existing GitHub actions and push both to Radicle and GitHub. The code review would happen in Radicle, and GitHub would run our tests. For easy visual indication, we used workflow status badges generated for each branch pushed to GitHub.</p>

<p>The screenshot below shows how this looks in the Desktop app.
<img src="/assets/images/blog/radicle-with-github-actions-screenshot.png" class="screenshot" /></p>

<p>The workflow was as simple as:</p>

<ol>
  <li>Create a branch and commit your changes</li>
  <li>Push the changes to GitHub with <code class="language-plaintext highlighter-rouge">git push github rudolfs/breadcrumb-tweak:rudolfs/breadcrumb-tweak</code></li>
  <li>Copy the build badge links to your clipboard, see script below</li>
  <li>Open a patch on Radicle via <code class="language-plaintext highlighter-rouge">git push rad HEAD:refs/patches</code>, paste the build badges into the patch body and submit it</li>
</ol>

<p>When we addressed changes from code review and submitted a new revision, we pushed it to both Radicle and GitHub to trigger another build, the badges updated automatically.</p>

<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>git push github rudolfs/breadcrumb-tweak:rudolfs/breadcrumb-tweak
<span class="nv">$ </span>git push rad
</code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">rad</code> remote is set up for you automatically when you initialize a project with <code class="language-plaintext highlighter-rouge">rad init</code>. The GitHub remote can be set up manually via <code class="language-plaintext highlighter-rouge">git remote add github git@github.com:radicle-dev/radicle-interface.git</code> pointing to a copy of the project which lives on your GitHub account.</p>

<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>git remote <span class="nt">-v</span>

github	git@github.com:radicle-dev/radicle-interface.git <span class="o">(</span>fetch<span class="o">)</span>
github	git@github.com:radicle-dev/radicle-interface.git <span class="o">(</span>push<span class="o">)</span>
rad	rad://z4V1sjrXqjvFdnCUbxPFqd5p4DtH5 <span class="o">(</span>fetch<span class="o">)</span>
rad	rad://z4V1sjrXqjvFdnCUbxPFqd5p4DtH5/z6MkwPUeUS2fJMfc2HZN1RQTQcTTuhw4HhPySB8JeUg2mVvx <span class="o">(</span>push<span class="o">)</span>
</code></pre></div></div>

<p>Bash script that automatically copies the build badge links to the clipboard.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>
<span class="nb">set</span> <span class="nt">-euo</span> pipefail
<span class="nv">branchName</span><span class="o">=</span><span class="si">$(</span>git branch <span class="nt">--show-current</span><span class="si">)</span>
<span class="nv">previewBranchName</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">branchName</span><span class="p">//\//-</span><span class="k">}</span><span class="s2">"</span>
<span class="nv">workflowBranchName</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">branchName</span><span class="p">//\//%2F</span><span class="k">}</span><span class="s2">"</span>
<span class="c"># Use a here document to include the text and pipe it to sed</span>
<span class="nb">sed</span> <span class="nt">-e</span> <span class="s2">"s|&lt;branchName&gt;|</span><span class="nv">$branchName</span><span class="s2">|g"</span> <span class="se">\</span>
  <span class="nt">-e</span> <span class="s2">"s|&lt;workflowBranchName&gt;|</span><span class="nv">$workflowBranchName</span><span class="s2">|g"</span> <span class="se">\</span>
  <span class="nt">-e</span> <span class="s2">"s|&lt;previewBranchName&gt;|</span><span class="nv">$previewBranchName</span><span class="s2">|g"</span> <span class="o">&lt;&lt;</span><span class="sh">'</span><span class="no">EOF</span><span class="sh">' | pbcopy
![check](https://github.com/radicle-dev/radicle-interface/actions/workflows/check.yml/badge.svg?branch=&lt;branchName&gt;) ![check-visual](https://github.com/radicle-dev/radicle-interface/actions/workflows/check-visual.yml/badge.svg?branch=&lt;branchName&gt;) ![check-unit-test](https://github.com/radicle-dev/radicle-interface/actions/workflows/check-unit-test.yml/badge.svg?branch=&lt;branchName&gt;) ![check-http-client-unit-test](https://github.com/radicle-dev/radicle-interface/actions/workflows/check-http-client-unit-test.yml/badge.svg?branch=&lt;branchName&gt;) ![check-radicle-httpd](https://github.com/radicle-dev/radicle-interface/actions/workflows/check-radicle-httpd.yml/badge.svg?branch=&lt;branchName&gt;) ![check-e2e](https://github.com/radicle-dev/radicle-interface/actions/workflows/check-e2e.yml/badge.svg?branch=&lt;branchName&gt;) ![check-build](https://github.com/radicle-dev/radicle-interface/actions/workflows/check-build.yml/badge.svg?branch=&lt;branchName&gt;) ![check-http](https://github.com/radicle-dev/radicle-interface/actions/workflows/check-radicle-httpd.yml/badge.svg?branch=&lt;branchName&gt;)
👉 [Preview](https://radicle-interface-git-&lt;previewBranchName&gt;-radicle.vercel.app)
👉 [Workflow runs](https://github.com/radicle-dev/radicle-interface/actions?query=branch%3A&lt;workflowBranchName&gt;)
👉 [Branch on GitHub](https://github.com/radicle-dev/radicle-interface/tree/&lt;branchName&gt;)
</span><span class="no">EOF
</span></code></pre></div></div>

<p>This is how we used to run tests and builds. Now, we’re dogfooding <a href="https://app.radicle.xyz/nodes/ash.radicle.garden/rad:zwTxygwuz5LDGBq255RA2CbNGrz8">our own CI solution</a> together with <a href="https://app.radicle.xyz/nodes/seed.radicle.garden/rad:z39Cf1XzrvCLRZZJRUZnx9D1fj5ws">Woodpecker</a>. If you want to learn more about CI in Radicle, check out the conversations on <a href="https://radicle.zulipchat.com/#narrow/channel/452370-radicle-ci">Zulip</a>.</p>]]></content><author><name>rudolfs</name></author><summary type="html"><![CDATA[A chat with burrito aka Dietrich Ayala today sparked the idea to write down how we started dogfooding Radicle before we had our native Radicle CI going. He also encouraged me to just set a deadline for writing blog posts in general, so this had to be written and published by the end of today.]]></summary></entry><entry><title type="html">Radicle 1.1</title><link href="https://radicle.xyz/2024/12/05/radicle-1.1.html" rel="alternate" type="text/html" title="Radicle 1.1" /><published>2024-12-05T00:00:00+00:00</published><updated>2024-12-05T00:00:00+00:00</updated><id>https://radicle.xyz/2024/12/05/radicle-1.1</id><content type="html" xml:base="https://radicle.xyz/2024/12/05/radicle-1.1.html"><![CDATA[<p>The Radicle team is delighted to announce the release of Radicle 1.1. This
release contains 47 commits by 8 contributors.</p>

<p>To upgrade or install, head to the <a href="/download">download</a> section, or run the
following command from your terminal:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl -sSf https://radicle.xyz/install | sh -s -- --version=1.1.0
</code></pre></div></div>

<h2 id="database-migration">Database migration</h2>

<p>This release includes a migration of the COB database to version 2. The
migration is run automatically when you start your node. If you’d like to run
it manually, use:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rad cob migrate
</code></pre></div></div>

<h2 id="radicle-http-daemon">Radicle HTTP Daemon</h2>

<p>Seeders should upgrade their <code class="language-plaintext highlighter-rouge">radicle-httpd</code> installation to 0.18.0. Head
over to <a href="/download">download</a> to grab that.</p>

<h2 id="whats-in-the-box-">What’s in the box 📦</h2>

<p>The Radicle 1.1 release includes quality of life improvements, bug fixes,
and a couple of new CLI commands.</p>

<h3 id="cli">CLI</h3>

<ul>
  <li>A new <code class="language-plaintext highlighter-rouge">rad cob migrate</code> command was added to migrate the collaborative objects
database.</li>
  <li>A new <code class="language-plaintext highlighter-rouge">--edit</code> flag was added to the <code class="language-plaintext highlighter-rouge">rad id update</code> command, to make changes
to an identity document from your editor.</li>
  <li>A new <code class="language-plaintext highlighter-rouge">--storage</code> flag was added to <code class="language-plaintext highlighter-rouge">rad patch cache</code> and <code class="language-plaintext highlighter-rouge">rad issue cache</code>
that operates on the entire storage, instead of a specific repository.</li>
  <li>When fetching a repository with <code class="language-plaintext highlighter-rouge">--seed</code> specified on the CLI, we now try to
connect to the seed it if not already connected.</li>
  <li>A new set of sub-commands were added to <code class="language-plaintext highlighter-rouge">rad config</code>, for directly modifying
the local Radicle configuration. See <code class="language-plaintext highlighter-rouge">rad config --help</code> for details.</li>
  <li>Repositories are now initialized with a new refspec for the <code class="language-plaintext highlighter-rouge">rad</code> remote, that
ensures that tags are properly namespaced under their remote.</li>
  <li>A new <code class="language-plaintext highlighter-rouge">--remote &lt;name&gt;</code> flag was added to <code class="language-plaintext highlighter-rouge">rad patch checkout</code> and <code class="language-plaintext highlighter-rouge">rad patch
set</code> to set the remote for those commands. Defaults to <code class="language-plaintext highlighter-rouge">rad</code>.</li>
  <li>The <code class="language-plaintext highlighter-rouge">RAD_PASSPHRASE</code> variable is now correctly treated as no passphrase when
empty.</li>
</ul>

<h3 id="git-remote-helper">Git Remote Helper</h3>

<ul>
  <li>The <code class="language-plaintext highlighter-rouge">GIT_DIR</code> environment variable is no longer required for listing refs via
the remote helper. This means the commands can be run outside of a working
copy.</li>
  <li>Fixed a bug where the wrong commit was used in the Patch COB when merging
multiple patches with a single <code class="language-plaintext highlighter-rouge">git push</code>, resulting in some merged patches
showing as unmerged.</li>
</ul>

<h3 id="collaborative-objects-cobs">Collaborative Objects (COBs)</h3>

<ul>
  <li>Fixed compatibility with certain old patches that contained empty reviews.</li>
  <li>Added a new <code class="language-plaintext highlighter-rouge">review.edit</code> action to the <code class="language-plaintext highlighter-rouge">xyz.radicle.patch</code> COB, for editing
reviews.</li>
</ul>

<h3 id="node">Node</h3>

<ul>
  <li>When fetching a repository, the fetch would fail if the canonical branch could
not be established. This is no longer the case, allowing the user to handle the problem
locally.</li>
  <li>When fetching a repository, we no longer fail a fetch from a peer that is
missing a reference to the default branch.</li>
  <li>Private RIDs that could sometimes leak over the gossip protocol no longer do.
Note that this only affected the identifiers, not any repository data.</li>
</ul>

<h3 id="protocol">Protocol</h3>

<ul>
  <li>A new <code class="language-plaintext highlighter-rouge">rad/root</code> reference is added to the list of signed references
(<code class="language-plaintext highlighter-rouge">rad/sigrefs</code>). This prevents a possible reference grafting attack.</li>
</ul>

<h2 id="changelog">Changelog</h2>

<p>Here is the full Radicle 1.1 changelog.</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">70f0cc35</code> <strong>cob: Fix <code class="language-plaintext highlighter-rouge">serde</code> instances for <code class="language-plaintext highlighter-rouge">ObjectId</code></strong> <em><a href="mailto:cloudhead@radicle.xyz">cloudhead@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">f58af8fe</code> <strong>cli: Use <code class="language-plaintext highlighter-rouge">term::Table::header</code> where possible</strong> <em><a href="mailto:lorenz@leutgeb.xyz">lorenz@leutgeb.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">bcba8f5a</code> <strong>scripts: Add <code class="language-plaintext highlighter-rouge">--from-version</code> to changelog script</strong> <em><a href="mailto:cloudhead@radicle.xyz">cloudhead@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">47b20098</code> <strong>cli: Fix <code class="language-plaintext highlighter-rouge">rad cob migrate</code> test</strong> <em><a href="mailto:cloudhead@radicle.xyz">cloudhead@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">0ecdc764</code> <strong>cli: Improve <code class="language-plaintext highlighter-rouge">rad node logs</code> error message</strong> <em><a href="mailto:arnaud.bailly@iohk.io">arnaud.bailly@iohk.io</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">3ad84420</code> <strong>cli: Implement <code class="language-plaintext highlighter-rouge">rad cob migrate</code></strong> <em><a href="mailto:cloudhead@radicle.xyz">cloudhead@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">2d13591e</code> <strong>radicle: Fix flaky test <code class="language-plaintext highlighter-rouge">counts_by_repo</code></strong> <em><a href="mailto:cloudhead@radicle.xyz">cloudhead@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">a7e96131</code> <strong>radicle: add notification count grouped by repo</strong> <em><a href="mailto:me@sebastinez.dev">me@sebastinez.dev</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">259adf7d</code> <strong>cob: mutable stable time for testing</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">cab56c11</code> <strong>helper: Use the correct head when merging a patch</strong> <em><a href="mailto:cloudhead@radicle.xyz">cloudhead@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">91914d93</code> <strong>radicle: improve quorum copy</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">e412168b</code> <strong>node: do not fail on <code class="language-plaintext highlighter-rouge">set_head</code></strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">159d3fce</code> <strong>dag: test contains</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">6c8ee433</code> <strong>radicle: Implement migration callback mechanism</strong> <em><a href="mailto:cloudhead@radicle.xyz">cloudhead@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">08833985</code> <strong>radicle: introduce identity document version</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">ccc0297b</code> <strong>cli: test deletion via <code class="language-plaintext highlighter-rouge">git push -d</code></strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">43e08a8e</code> <strong>cli: rad id update –edit</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">c6d97579</code> <strong>cli: verification of project for json errors only</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">f9c35231</code> <strong>e2e: improve flake in missing_delegate_default_branch</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">0d402647</code> <strong>term: allow Editor to be reusable</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">23f8cf0d</code> <strong>cli: Option for caching COBs for all repositories</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">df44cee9</code> <strong>cob: Add an experimental “job” COB</strong> <em><a href="mailto:liw@liw.fi">liw@liw.fi</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">eb095c10</code> <strong>fetch: allow missing default branch</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">f6aa46a2</code> <strong>cli: Try to connect to seeds specified as options</strong> <em><a href="mailto:cloudhead@radicle.xyz">cloudhead@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">11a6ec5d</code> <strong>cob: Add logging to COB evaluation</strong> <em><a href="mailto:cloudhead@radicle.xyz">cloudhead@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">0bb0fe8f</code> <strong>cob: Fix compatibility with certain old patches</strong> <em><a href="mailto:cloudhead@radicle.xyz">cloudhead@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">6dcfbfcd</code> <strong>build: Separate release from upload</strong> <em><a href="mailto:cloudhead@radicle.xyz">cloudhead@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">09f79623</code> <strong>radicle: Compute root OID for older remotes</strong> <em><a href="mailto:cloudhead@radicle.xyz">cloudhead@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">0c9a7419</code> <strong>cli: Add config modification sub-commands</strong> <em><a href="mailto:johannes.kuehlewindt@gmail.com">johannes.kuehlewindt@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">a838c3ea</code> <strong>fmt: Run <code class="language-plaintext highlighter-rouge">cargo fmt</code></strong> <em><a href="mailto:cloudhead@radicle.xyz">cloudhead@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">b4f2614d</code> <strong>cob: chronological ordering of concurrent values</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">de1958fa</code> <strong>radicle: refactor doc</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">f83c1167</code> <strong>radicle: Fix clippy warnings around <code class="language-plaintext highlighter-rouge">unwrap</code></strong> <em><a href="mailto:cloudhead@radicle.xyz">cloudhead@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">989edacd</code> <strong>Include new <code class="language-plaintext highlighter-rouge">rad/root</code> in signed refs</strong> <em><a href="mailto:cloudhead@radicle.xyz">cloudhead@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">24066c26</code> <strong>radicle: Test the signed refs grafting attack</strong> <em><a href="mailto:cloudhead@radicle.xyz">cloudhead@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">46c2637f</code> <strong>radicle: add tags fetch refspec</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">6763bf31</code> <strong>helper: Don’t require <code class="language-plaintext highlighter-rouge">GIT_DIR</code> for listing refs</strong> <em><a href="mailto:cloudhead@radicle.xyz">cloudhead@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">855327d3</code> <strong>cob: Change APIs to take URIs for embeds</strong> <em><a href="mailto:cloudhead@radicle.xyz">cloudhead@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">034eb418</code> <strong>node: Ensure private RIDs don’t leak in gossip</strong> <em><a href="mailto:cloudhead@radicle.xyz">cloudhead@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">3acdb17b</code> <strong>cob: Fix patch review editing</strong> <em><a href="mailto:cloudhead@radicle.xyz">cloudhead@radicle.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">729a6e05</code> <strong>cobs: Fix COB drafts to work correctly</strong> <em><a href="mailto:self@cloudhead.io">self@cloudhead.io</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">e130b4dc</code> <strong>radicle: custom upstream remote for patches</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">00639182</code> <strong>docs: Add a note on running isolated nodes</strong> <em><a href="mailto:liw@liw.fi">liw@liw.fi</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">47842a81</code> <strong>man: Mention <code class="language-plaintext highlighter-rouge">rad patch review</code></strong> <em><a href="mailto:lorenz@leutgeb.xyz">lorenz@leutgeb.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">4b955fff</code> <strong>nix: Fix macOS build</strong> <em><a href="mailto:lorenz@leutgeb.xyz">lorenz@leutgeb.xyz</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">f244d89e</code> <strong>node: check policy before visibility</strong> <em><a href="mailto:fintan.halpenny@gmail.com">fintan.halpenny@gmail.com</a></em></li>
  <li><code class="language-plaintext highlighter-rouge">1d57778f</code> <strong>profile: Treat empty passphrase as no passphrase</strong> <em><a href="mailto:lorenz@leutgeb.xyz">lorenz@leutgeb.xyz</a></em></li>
</ul>

<h2 id="checksums">Checksums</h2>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>7653fbd51fd1fdfc79a3ebd2716c7111437012c2b36d591f7c46347cee55330e  radicle-1.1.0-aarch64-unknown-linux-musl.tar.xz
6cd27335df663e5a2dd1c2182986564e399fd5dbad48fefbd0a78061a6a9839d  radicle-1.1.0-x86_64-apple-darwin.tar.xz
bca3b83e7c50b2e0d3970194af2b49cf57e685615b594841f92ef92eb0acf930  radicle-1.1.0-x86_64-unknown-linux-musl.tar.xz
d7a791bf1d7906773629cf99572ac723d54d66bdf15ac0b247636104a5ff7c4a  radicle-1.1.0-aarch64-apple-darwin.tar.xz
</code></pre></div></div>]]></content><author><name></name></author><summary type="html"><![CDATA[The Radicle team is delighted to announce the release of Radicle 1.1. This release contains 47 commits by 8 contributors.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://radicle.xyz/radicle-1.png" /><media:content medium="image" url="https://radicle.xyz/radicle-1.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Radicle 1.0</title><link href="https://radicle.xyz/2024/09/10/radicle-1.0.html" rel="alternate" type="text/html" title="Radicle 1.0" /><published>2024-09-10T00:00:00+01:00</published><updated>2024-09-10T00:00:00+01:00</updated><id>https://radicle.xyz/2024/09/10/radicle-1.0</id><content type="html" xml:base="https://radicle.xyz/2024/09/10/radicle-1.0.html"><![CDATA[<p>On March 26th, we <a href="https://x.com/radicle/status/1772659708978991605?s=20">announced</a> the first release candidate for Radicle 1.0.
Today, after five months of feedback and 17 release candidates, we are ready to
launch Radicle <code class="language-plaintext highlighter-rouge">1.0</code>.</p>

<p>If you’ve been waiting for the right moment to try Radicle or to reintroduce
yourself to the stack, now is a great time to dive in: our <a href="/">website</a>
and <a href="/guides">guides</a> should have all the information you need to get started.
You can also browse the latest <a href="https://app.radicle.xyz/nodes/seed.radicle.xyz/rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5">code</a>, hosted on Radicle.</p>

<p>If you’ve been tagging along, thank you, it’s been a bumpy ride and we couldn’t
have done it without you!</p>

<h2 id="try-it-out">Try it out!</h2>

<p>You can grab the latest release with the following command:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl -sSf https://radicle.xyz/install | sh
</code></pre></div></div>

<p>Or head over to the <a href="/download">download</a> section to download and verify the
binaries yourself.</p>

<h2 id="whats-in-the-box-">What’s in the box 📦</h2>

<p>Radicle 1.0 represents the culmination of <a href="/history">years</a> of experimentation
and hard work from our team and community, where we set out to ensure that free
and open source software ecosystems can flourish without having to rely on the
whims of Big Tech. We designed Radicle with a first-principles approach, as a
natural extension to Git, expanding it to work in a collaborative, local-first,
peer-to-peer setting.</p>

<p>This milestone includes:</p>

<ul>
  <li>An extensible, homegrown, peer-to-peer gossip and sync <a href="/guides/protocol">protocol</a>
built on the Git protocol.</li>
  <li>Social interactions such as issues, patches and code review, using our
extensible <a href="/guides/protocol#collaborative-objects">Collaborative Objects</a> system which keeps all artifacts
in the repository.</li>
  <li>A secure authentication and authorization protocol using public key
cryptography, which allows all published content to be verified locally,
without centralized authority.</li>
  <li>An intuitive CLI that should be familiar to users of Git, as well as a web
frontend for browsing Radicle repositories and seed nodes.</li>
  <li>Privacy at the protocol level, with truly private repositories and built-in
<a href="/guides/user/#4-embracing-the-onion">Tor support</a>.</li>
  <li>Reproducible and signed <a href="/download">builds</a> for all Radicle binaries.</li>
</ul>

<p>To us, Radicle 1.0 means that Radicle is <em>ready to use</em>. It stands as a
testament that sovereign code forges are possible today, and in our opinion,
<em>necessary</em>.</p>

<p>We feel comfortable now inviting you to join us, replicate, and
<a href="/guides/user">collaborate</a> within the Radicle network or even <a href="/guides/seeder">run a seed
node</a>.</p>

<p>For an in-depth explanation of how Radicle works, check out our <a href="/guides/protocol">Protocol
Guide</a>.</p>

<h2 id="stability-️">Stability ⛰️</h2>

<p>Radicle 1.0 marks our commitment to stability: from this release onwards, all
changes to the protocol will be designed in backwards compatible way, and any
necessary change on the CLI will include a seamless upgrade path.</p>

<p>We are aware that the release candidate phase was rockier than expected for
some, but we are now in a good place to slow things down and improve stability.</p>

<p>Along with this commitment will come a more dependable and streamlined release
process which starts with this release!</p>

<h2 id="future-plans-">Future plans 🔮</h2>

<p>There are several things in the pipeline that we intend to release when ready:</p>

<ul>
  <li>Native CI/CD capabilities</li>
  <li>The Radicle TUI (Terminal User Interface)</li>
  <li>Advanced code review functionality</li>
  <li>An inbox system for repository notifications</li>
  <li>Multi-device support and user profiles</li>
  <li>Support for other canonical references, such as tags</li>
  <li>Seed node moderation and management tools</li>
  <li>The Radicle desktop application</li>
</ul>

<h2 id="growing-ecosystem-">Growing ecosystem 🌱</h2>

<p>Outside of the core stack, the ecosystem is growing nicely:  an independent
team working on integrations &amp; tooling for Radicle has developed a <a href="https://app.radicle.at/nodes/seed.radicle.gr/rad:z3Makm6fsQQXmpSFE43DZqwupaEhk">VS
Code</a> and <a href="https://app.radicle.at/nodes/seed.radicle.gr/rad:z3WHS4GSf8hChLjGYfPkJY7vCxsBK">JetBrains</a> plugin. The Radicle network now also
comprises several deployments of the Radicle <a href="https://app.radicle.xyz/nodes/seed.radicle.xyz/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5">frontend</a>, and there are more
than 40 seed nodes operating on the network, freely replicating user content.</p>

<h2 id="invitation-to-forge-the-future-">Invitation to forge the future 🤝</h2>

<p>Once you <a href="/guides/user#installation">install</a> Radicle and set up your identity, you’ll have access
to all public repositories on any public node, making it easier to explore and
contribute to the ecosystem. Compared to traditional self-hosted forges, which
often result in fragmented collaboration environments, Radicle represents an
evolutionary step for Git-based collaboration, with a single cryptographic
identity that works across nodes.</p>

<p>Lastly, in the spirit of free and open source software, we believe that power
lies in community. As we embark on further iterating the protocol and stack, we
also invite you to shape the future of Radicle with us. Your ideas and insights
are invaluable to our mission of creating a sovereign forge.</p>

<p>Together, we can make significant progress towards reclaiming the internet.</p>

<p><em>Free your code!</em></p>

<p>👾👾👾</p>]]></content><author><name></name></author><summary type="html"><![CDATA[On March 26th, we announced the first release candidate for Radicle 1.0. Today, after five months of feedback and 17 release candidates, we are ready to launch Radicle 1.0.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://radicle.xyz/radicle-1.png" /><media:content medium="image" url="https://radicle.xyz/radicle-1.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>