rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5 heartwood130cf1096601fa01f013379c2c3c42cf5362197a
{
"request": "trigger",
"version": 1,
"event_type": "patch",
"repository": {
"id": "rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5",
"name": "heartwood",
"description": "Radicle Heartwood Protocol & Stack",
"private": false,
"default_branch": "master",
"delegates": [
"did:key:z6MksFqXN3Yhqk8pTJdUGLwATkRfQvwZXPqR2qMEhbS9wzpT",
"did:key:z6MktaNvN1KVFMkSRAiN4qK5yvX1zuEEaseeX5sffhzPZRZW",
"did:key:z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM",
"did:key:z6MkgFq6z5fkF2hioLLSNu1zP2qEL1aHXHZzGH1FLFGAnBGz",
"did:key:z6MkkPvBfjP4bQmco5Dm7UGsX2ruDBieEHi8n9DVJWX5sTEz"
]
},
"action": "Updated",
"patch": {
"id": "37aa2b6c81a500fb146aa24a1dd6b3c46acb41f3",
"author": {
"id": "did:key:z6MkkPvBfjP4bQmco5Dm7UGsX2ruDBieEHi8n9DVJWX5sTEz",
"alias": "lorenz"
},
"title": "remote-helper: Update Patch by ID Prefix",
"state": {
"status": "open",
"conflicts": []
},
"before": "ee49e28766ce7c703b95e22d177cce046072f03d",
"after": "130cf1096601fa01f013379c2c3c42cf5362197a",
"commits": [
"130cf1096601fa01f013379c2c3c42cf5362197a",
"2fbdaac76c8a7fc3fbe3fb186b0344b6bec01050"
],
"target": "ee49e28766ce7c703b95e22d177cce046072f03d",
"labels": [],
"assignees": [],
"revisions": [
{
"id": "37aa2b6c81a500fb146aa24a1dd6b3c46acb41f3",
"author": {
"id": "did:key:z6MkkPvBfjP4bQmco5Dm7UGsX2ruDBieEHi8n9DVJWX5sTEz",
"alias": "lorenz"
},
"description": "`rad patch list` does not show full patch IDs by default, and overly\nlong patch IDs are cumbersome to handle.\n\nIf a unique prefix is used, allow updating patches identified by\nthat prefix.\n\nE.g. when there is exactly one patch with an ID that has a prefix of\n\"a\", then pushing to `refs/heads/patches/a` updates that patch.",
"base": "ee49e28766ce7c703b95e22d177cce046072f03d",
"oid": "361bf804b83b604a152f301492f87bee14915265",
"timestamp": 1759341679
},
{
"id": "af8688592d72980d51435f158944da64aa7f3888",
"author": {
"id": "did:key:z6MkkPvBfjP4bQmco5Dm7UGsX2ruDBieEHi8n9DVJWX5sTEz",
"alias": "lorenz"
},
"description": "Use variables directly in `format!` string.",
"base": "ee49e28766ce7c703b95e22d177cce046072f03d",
"oid": "130cf1096601fa01f013379c2c3c42cf5362197a",
"timestamp": 1759342461
}
]
}
}
{
"response": "triggered",
"run_id": {
"id": "e40be114-630d-4764-8f3c-c19c36c3db83"
},
"info_url": "https://cci.rad.levitte.org//e40be114-630d-4764-8f3c-c19c36c3db83.html"
}
Started at: 2025-10-01 20:14:24.986464+02:00
Commands:
$ rad clone rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5 .
✓ Creating checkout in ./...
✓ Remote cloudhead@z6MksFqXN3Yhqk8pTJdUGLwATkRfQvwZXPqR2qMEhbS9wzpT added
✓ Remote-tracking branch cloudhead@z6MksFqXN3Yhqk8pTJdUGLwATkRfQvwZXPqR2qMEhbS9wzpT/master created for z6MksFqXN3Yhqk8pTJdUGLwATkRfQvwZXPqR2qMEhbS9wzpT
✓ Remote cloudhead@z6MktaNvN1KVFMkSRAiN4qK5yvX1zuEEaseeX5sffhzPZRZW added
✓ Remote-tracking branch cloudhead@z6MktaNvN1KVFMkSRAiN4qK5yvX1zuEEaseeX5sffhzPZRZW/master created for z6MktaNvN1KVFMkSRAiN4qK5yvX1zuEEaseeX5sffhzPZRZW
✓ Remote fintohaps@z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM added
✓ Remote-tracking branch fintohaps@z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM/master created for z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM
✓ Remote erikli@z6MkgFq6z5fkF2hioLLSNu1zP2qEL1aHXHZzGH1FLFGAnBGz added
✓ Remote-tracking branch erikli@z6MkgFq6z5fkF2hioLLSNu1zP2qEL1aHXHZzGH1FLFGAnBGz/master created for z6MkgFq6z5fkF2hioLLSNu1zP2qEL1aHXHZzGH1FLFGAnBGz
✓ Remote lorenz@z6MkkPvBfjP4bQmco5Dm7UGsX2ruDBieEHi8n9DVJWX5sTEz added
✓ Remote-tracking branch lorenz@z6MkkPvBfjP4bQmco5Dm7UGsX2ruDBieEHi8n9DVJWX5sTEz/master created for z6MkkPvBfjP4bQmco5Dm7UGsX2ruDBieEHi8n9DVJWX5sTEz
✓ Repository successfully cloned under /opt/radcis/ci.rad.levitte.org/cci/state/e40be114-630d-4764-8f3c-c19c36c3db83/w/
╭────────────────────────────────────╮
│ heartwood │
│ Radicle Heartwood Protocol & Stack │
│ 123 issues · 18 patches │
╰────────────────────────────────────╯
Run `cd ./.` to go to the repository directory.
Exit code: 0
$ rad patch checkout 37aa2b6c81a500fb146aa24a1dd6b3c46acb41f3
✓ Switched to branch patch/37aa2b6 at revision af86885
✓ Branch patch/37aa2b6 setup to track rad/patches/37aa2b6c81a500fb146aa24a1dd6b3c46acb41f3
Exit code: 0
$ git config advice.detachedHead false
Exit code: 0
$ git checkout 130cf1096601fa01f013379c2c3c42cf5362197a
HEAD is now at 130cf109 remote-helper/push: Refactor ownership
Exit code: 0
$ git show 130cf1096601fa01f013379c2c3c42cf5362197a
commit 130cf1096601fa01f013379c2c3c42cf5362197a
Author: Lorenz Leutgeb <lorenz.leutgeb@radicle.xyz>
Date: Wed Oct 1 19:48:54 2025 +0200
remote-helper/push: Refactor ownership
With the exception of keeping a copy of `dst`, ownership of the command
can be passed on. This makes for nicer format strings and slightly less
awkward argument handling and preambles in the functions:
- `patch_open`
- `patch_update`
- `push`
diff --git a/crates/radicle-remote-helper/src/push.rs b/crates/radicle-remote-helper/src/push.rs
index 39435965..1519cd22 100644
--- a/crates/radicle-remote-helper/src/push.rs
+++ b/crates/radicle-remote-helper/src/push.rs
@@ -220,17 +220,17 @@ enum PushAction {
impl PushAction {
fn new(
- dst: &git::RefString,
+ dst: git::RefString,
patches: &cob::patch::Cache<
cob::patch::Patches<'_, storage::git::Repository>,
cob::cache::StoreWriter,
>,
) -> Result<Self, error::PushAction> {
- if dst == &*rad::PATCHES_REFNAME {
+ if dst == *rad::PATCHES_REFNAME {
return Ok(Self::OpenPatch);
}
- let dst = git::Qualified::from_refstr(dst)
+ let dst = git::Qualified::from_refstr(&dst)
.ok_or_else(|| error::PushAction::InvalidRef {
refname: dst.clone(),
})?
@@ -322,8 +322,9 @@ pub fn run(
let Ok(cmd) = Command::parse(&spec, &working) else {
return Err(Error::InvalidCommand(format!("push {spec}")));
};
- let result = match &cmd {
- Command::Delete(dst) => {
+ let dst = cmd.dst().to_string();
+ let result = match cmd {
+ Command::Delete(ref dst) => {
// Delete refs.
let refname = nid.to_namespace().join(dst);
let (canonical_ref, _) = &stored.head()?;
@@ -359,7 +360,7 @@ pub fn run(
patch,
} => patch_update(
src,
- *force,
+ force,
patch_id,
*patch,
&nid,
@@ -381,7 +382,7 @@ pub fn run(
let explorer = push(
src,
&dst,
- *force,
+ force,
&nid,
&working,
stored,
@@ -397,9 +398,9 @@ pub fn run(
// canonical branch.
if let Some(canonical) = rules.canonical(dst.clone(), stored) {
let object = working
- .find_object(**src, None)
+ .find_object(*src, None)
.map(|obj| git::canonical::Object::new(&obj))?
- .ok_or(Error::UnknownObjectType { oid: *src })?;
+ .ok_or(Error::UnknownObjectType { oid: src })?;
let canonical = canonical::Canonical::new(me, object, canonical)?;
match canonical.quorum() {
@@ -416,11 +417,11 @@ pub fn run(
match result {
// Let Git tooling know that this ref has been pushed.
Ok(resource) => {
- println!("ok {}", cmd.dst());
+ println!("ok {dst}");
ok.insert(spec, resource);
}
// Let Git tooling know that there was an error pushing the ref.
- Err(e) => println!("error {} {e}", cmd.dst()),
+ Err(e) => println!("error {dst} {e}"),
}
}
@@ -502,7 +503,7 @@ pub fn run(
/// Open a new patch.
fn patch_open<G>(
- src: &git::Oid,
+ src: git::Oid,
upstream: &Option<git::RefString>,
nid: &NodeId,
working: &git::raw::Repository,
@@ -518,7 +519,7 @@ fn patch_open<G>(
where
G: crypto::signature::Signer<crypto::Signature>,
{
- let head = *src;
+ let head = src;
let dst = git::refs::storage::staging::patch(nid, head);
// Before creating the patch, we must push the associated git objects to storage.
@@ -528,7 +529,7 @@ where
//
// In case the reference is not properly deleted, the next attempt to open a patch should
// not fail, since the reference will already exist with the correct OID.
- push_ref(src, &dst, false, stored.raw(), opts.verbosity)?;
+ push_ref(&src, &dst, false, stored.raw(), opts.verbosity)?;
let (_, target) = stored.canonical_head()?;
let base = if let Some(base) = opts.base {
@@ -660,7 +661,7 @@ where
/// Update an existing patch.
#[allow(clippy::too_many_arguments)]
fn patch_update<G>(
- src: &git::Oid,
+ commit: git::Oid,
force: bool,
patch_id: patch::PatchId,
patch: patch::Patch,
@@ -677,10 +678,9 @@ fn patch_update<G>(
where
G: crypto::signature::Signer<crypto::Signature>,
{
- let commit = *src;
let dst = git::refs::patch(&patch_id).with_namespace(nid.into());
- push_ref(src, &dst, force, stored.raw(), opts.verbosity)?;
+ push_ref(&commit, &dst, force, stored.raw(), opts.verbosity)?;
// Don't update patch if it already has a revision matching this commit.
if patch.revisions().any(|(_, r)| r.head() == commit) {
@@ -735,7 +735,7 @@ where
}
fn push<G>(
- src: &git::Oid,
+ head: git::Oid,
dst: &git::Qualified,
force: bool,
nid: &NodeId,
@@ -751,12 +751,11 @@ fn push<G>(
where
G: crypto::signature::Signer<crypto::Signature>,
{
- let head = *src;
let dst = dst.with_namespace(nid.into());
// It's ok for the destination reference to be unknown, eg. when pushing a new branch.
let old = stored.backend.find_reference(dst.as_str()).ok();
- push_ref(src, &dst, force, stored.raw(), verbosity)?;
+ push_ref(&head, &dst, force, stored.raw(), verbosity)?;
if let Some(old) = old {
let proj = stored.project()?;
Exit code: 0
shell: 'export RUSTDOCFLAGS=''-D warnings'' cargo --version rustc --version cargo fmt --check cargo clippy --all-targets --workspace -- --deny warnings cargo build --all-targets --workspace cargo doc --workspace --no-deps cargo test --workspace --no-fail-fast '
Commands:
$ podman run --name e40be114-630d-4764-8f3c-c19c36c3db83 -v /opt/radcis/ci.rad.levitte.org/cci/state/e40be114-630d-4764-8f3c-c19c36c3db83/s:/e40be114-630d-4764-8f3c-c19c36c3db83/s:ro -v /opt/radcis/ci.rad.levitte.org/cci/state/e40be114-630d-4764-8f3c-c19c36c3db83/w:/e40be114-630d-4764-8f3c-c19c36c3db83/w -w /e40be114-630d-4764-8f3c-c19c36c3db83/w -v /opt/radcis/ci.rad.levitte.org/.radicle:/${id}/.radicle:ro -e RAD_HOME=/${id}/.radicle rust:bookworm bash /e40be114-630d-4764-8f3c-c19c36c3db83/s/script.sh
+ export 'RUSTDOCFLAGS=-D warnings'
+ RUSTDOCFLAGS='-D warnings'
+ cargo --version
info: syncing channel updates for '1.88-x86_64-unknown-linux-gnu'
info: latest update on 2025-06-26, rust version 1.88.0 (6b00bc388 2025-06-23)
info: downloading component 'cargo'
info: downloading component 'clippy'
info: downloading component 'rust-docs'
info: downloading component 'rust-src'
info: downloading component 'rust-std'
info: downloading component 'rustc'
info: downloading component 'rustfmt'
info: installing component 'cargo'
info: installing component 'clippy'
info: installing component 'rust-docs'
info: installing component 'rust-src'
info: installing component 'rust-std'
info: installing component 'rustc'
info: installing component 'rustfmt'
cargo 1.88.0 (873a06493 2025-05-10)
+ rustc --version
rustc 1.88.0 (6b00bc388 2025-06-23)
+ cargo fmt --check
Diff in /e40be114-630d-4764-8f3c-c19c36c3db83/w/crates/radicle-remote-helper/src/push.rs:355:
profile,
opts.clone(),
),
- PushAction::UpdatePatch {
- patch_id,
- patch,
- } => patch_update(
+ PushAction::UpdatePatch { patch_id, patch } => patch_update(
src,
force,
patch_id,
Exit code: 1
{
"response": "finished",
"result": "failure"
}