rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5 heartwood45820843c6d147802b49a780dda800dcafb52a69
{
"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": "Created",
"patch": {
"id": "9e45558dda40cf7e46739fef11b366d2060ecb1d",
"author": {
"id": "did:key:z6MkkPvBfjP4bQmco5Dm7UGsX2ruDBieEHi8n9DVJWX5sTEz",
"alias": "lorenz"
},
"title": "cli/id: Use clap",
"state": {
"status": "open",
"conflicts": []
},
"before": "384c506489dd6a4cbf8c80b0370b2b2a8de7835b",
"after": "45820843c6d147802b49a780dda800dcafb52a69",
"commits": [
"45820843c6d147802b49a780dda800dcafb52a69",
"53c39f7a783054515e2bc4646273a6391df4c0e6",
"c102e32e087a1f08abb10c469888eade471e0abc",
"aabb470075a1b8128829a1de5f2e527a7a614716",
"db4946dfe22ba583659575e5418edee32b0da19d",
"a2700eaeb5dc90ecd6dae97d9e5d63ffaff9c534",
"bcd23d68ba9d44f4d9e67d33a2bf02e4c47245dd",
"6226ecd1440f59f74eceba46d2f92d78a81cf1a8",
"6e30b6976abcd9a34e80d797541fcd891f23f538",
"6030280853c4c6ddbab12a17de75a7c18538f6c6"
],
"target": "384c506489dd6a4cbf8c80b0370b2b2a8de7835b",
"labels": [],
"assignees": [],
"revisions": [
{
"id": "9e45558dda40cf7e46739fef11b366d2060ecb1d",
"author": {
"id": "did:key:z6MkkPvBfjP4bQmco5Dm7UGsX2ruDBieEHi8n9DVJWX5sTEz",
"alias": "lorenz"
},
"description": "This implementation works around the fact that `clap` does currently\nnot support value parsers for a series of values, so representing\n`--payload` as a `Vec<Payload>` does not work.\n\nInstead, we parse eveything into a `Vec<String>` and do the validation\non the application side.\n\nUsing value parsers for a series of values will probably be supported in\n`clap` v5, though.",
"base": "3e98589a767d9a17a3da90e52ae4abb198fa9ada",
"oid": "1fcee08a8fd3b3c863bddb8c98cdf1bcbb2cf2cc",
"timestamp": 1760432036
},
{
"id": "5743b4009825c6beafb70cb6fd9ddee79843057c",
"author": {
"id": "did:key:z6MkkPvBfjP4bQmco5Dm7UGsX2ruDBieEHi8n9DVJWX5sTEz",
"alias": "lorenz"
},
"description": "- Rebase",
"base": "efe10f95be9fde1cda84f0631ec8f6546ac7228d",
"oid": "f27f69e9a00f4dc33f9c74327d2d3dfe62a14322",
"timestamp": 1760432200
},
{
"id": "4afef0bc538bbf407e8e8863535bcbaf1bc10807",
"author": {
"id": "did:key:z6MkkPvBfjP4bQmco5Dm7UGsX2ruDBieEHi8n9DVJWX5sTEz",
"alias": "lorenz"
},
"description": "REVIEW",
"base": "efe10f95be9fde1cda84f0631ec8f6546ac7228d",
"oid": "53244fd61500879b0f81d7a3496f494e595fbd81",
"timestamp": 1760440294
},
{
"id": "8391c927f0376b3043c677d3e78ddd28fb6cc405",
"author": {
"id": "did:key:z6MkkPvBfjP4bQmco5Dm7UGsX2ruDBieEHi8n9DVJWX5sTEz",
"alias": "lorenz"
},
"description": "Changes:\n\n- Return `impl Iterator` from payload parsing function\n- Assert value number in payload parsing function\n- Add unit tests",
"base": "dfd35480be82828713ccc3c9206b1273ddac35d0",
"oid": "d3f8eced41cd81b833a8a101f8004113002aba58",
"timestamp": 1760443529
},
{
"id": "c2b443e152167326672d9952f01c26ff08a70896",
"author": {
"id": "did:key:z6MkkPvBfjP4bQmco5Dm7UGsX2ruDBieEHi8n9DVJWX5sTEz",
"alias": "lorenz"
},
"description": "REVIEW",
"base": "dfd35480be82828713ccc3c9206b1273ddac35d0",
"oid": "1ea1182827099e205c9e060135ce4770584e7628",
"timestamp": 1760444570
},
{
"id": "2f9c64211a2179b13b253e0e93ef749c2b388abb",
"author": {
"id": "did:key:z6MkkPvBfjP4bQmco5Dm7UGsX2ruDBieEHi8n9DVJWX5sTEz",
"alias": "lorenz"
},
"description": "- Squash review commits",
"base": "dfd35480be82828713ccc3c9206b1273ddac35d0",
"oid": "8a3a222b18f315fe7a9fad7cfd7fc11e9ca00886",
"timestamp": 1760458749
},
{
"id": "8904aec75c2095b785209754949ad4a6cdeed146",
"author": {
"id": "did:key:z6MkkPvBfjP4bQmco5Dm7UGsX2ruDBieEHi8n9DVJWX5sTEz",
"alias": "lorenz"
},
"description": "- Rebase",
"base": "384c506489dd6a4cbf8c80b0370b2b2a8de7835b",
"oid": "6030280853c4c6ddbab12a17de75a7c18538f6c6",
"timestamp": 1760458770
},
{
"id": "9549a776bd4e3f7a744b3020774cb5eb564a5c61",
"author": {
"id": "did:key:z6MkkPvBfjP4bQmco5Dm7UGsX2ruDBieEHi8n9DVJWX5sTEz",
"alias": "lorenz"
},
"description": "Review",
"base": "384c506489dd6a4cbf8c80b0370b2b2a8de7835b",
"oid": "45820843c6d147802b49a780dda800dcafb52a69",
"timestamp": 1760469079
}
]
}
}
{
"response": "triggered",
"run_id": {
"id": "f76a3ffe-d9e2-4dcc-9c7a-3c496f9d65ca"
},
"info_url": "https://cci.rad.levitte.org//f76a3ffe-d9e2-4dcc-9c7a-3c496f9d65ca.html"
}
Started at: 2025-10-14 21:15:47.813960+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/f76a3ffe-d9e2-4dcc-9c7a-3c496f9d65ca/w/
╭────────────────────────────────────╮
│ heartwood │
│ Radicle Heartwood Protocol & Stack │
│ 125 issues · 18 patches │
╰────────────────────────────────────╯
Run `cd ./.` to go to the repository directory.
Exit code: 0
$ rad patch checkout 9e45558dda40cf7e46739fef11b366d2060ecb1d
✓ Switched to branch patch/9e45558 at revision 8904aec
✓ Branch patch/9e45558 setup to track rad/patches/9e45558dda40cf7e46739fef11b366d2060ecb1d
Exit code: 0
$ git config advice.detachedHead false
Exit code: 0
$ git checkout 45820843c6d147802b49a780dda800dcafb52a69
HEAD is now at 45820843 REVIEW: With `PayloadUpsert` in `radicle`, we can avoid introducing another ad-hoc struct, and using `itertools`.
Exit code: 0
$ git show 45820843c6d147802b49a780dda800dcafb52a69
commit 45820843c6d147802b49a780dda800dcafb52a69
Merge: 53c39f7a a2700eae
Author: Lorenz Leutgeb <lorenz.leutgeb@radicle.xyz>
Date: Tue Oct 14 20:49:48 2025 +0200
REVIEW: With `PayloadUpsert` in `radicle`, we can
avoid introducing another ad-hoc struct, and using `itertools`.
diff --cc crates/radicle-cli/src/commands/id.rs
index e8d0b105,93f3cf12..34bcad08
--- a/crates/radicle-cli/src/commands/id.rs
+++ b/crates/radicle-cli/src/commands/id.rs
@@@ -161,13 -407,7 +159,11 @@@ pub fn run(args: Args, ctx: impl term::
}
};
- update::payload(proposal, payload)?
+ // TODO(erikli): whenever `clap` starts supporting custom value parsers
+ // for a series of values, we can parse into `Payload` implicitly.
- let payloads = args::PayloadUpsert::parse_many(&payload)
- .map_ok(|p| (p.id, p.key, p.value))
- .collect::<Result<Vec<_>, _>>()?;
++ let payloads = args::parse_many_upserts(&payload).collect::<Result<Vec<_>, _>>()?;
+
+ update::payload(proposal, payloads)?
};
// If `--edit` is specified, the document can also be edited via a text edit.
diff --cc crates/radicle-cli/src/commands/id/args.rs
index 1e75a29e,00000000..513ffcb7
mode 100644,000000..100644
--- a/crates/radicle-cli/src/commands/id/args.rs
+++ b/crates/radicle-cli/src/commands/id/args.rs
@@@ -1,335 -1,0 +1,327 @@@
+use std::io;
+use std::str::FromStr;
+
+use clap::{Parser, Subcommand};
+
+use serde_json as json;
+
+use thiserror::Error;
+
+use radicle::cob::{Title, TypeNameParse};
+use radicle::identity::doc::update::EditVisibility;
++use radicle::identity::doc::update::PayloadUpsert;
+use radicle::identity::doc::PayloadId;
+use radicle::prelude::{Did, RepoId};
+
+use crate::git::Rev;
+
+use crate::terminal::Interactive;
+
+pub(crate) const ABOUT: &str = "Manage repository identities";
+const LONG_ABOUT: &str = r#"
+The `id` command is used to manage and propose changes to the
+identity of a Radicle repository.
+
+See the rad-id(1) man page for more information.
+"#;
+
+#[derive(Debug, Error)]
+pub enum PayloadUpsertParseError {
+ #[error("could not parse payload id: {0}")]
+ IdParse(#[from] TypeNameParse),
+ #[error("could not parse json value: {0}")]
+ Value(#[from] json::Error),
+}
+
- #[derive(Clone, Debug)]
- pub struct PayloadUpsert {
- pub(super) id: PayloadId,
- pub(super) key: String,
- pub(super) value: json::Value,
- }
-
- impl PayloadUpsert {
- /// Parses a slice of all payload upserts as aggregated by `clap`
- /// (see [`Command::Update::payload`]).
- /// E.g. `["com.example.one", "name", "1", "com.example.two", "name2", "2"]`
- /// will result in iterator over two [`PayloadUpsert`]s.
- ///
- /// # Panics
- ///
- /// If the length of `values` is not divisible by 3.
- /// (To catch errors in the definition of the parser derived from
- /// [`Command::Update`] or `clap` itself, and unexpected changes to
- /// `clap`s behaviour in the future.)
- pub(super) fn parse_many(
- values: &[String],
- ) -> impl Iterator<Item = Result<Self, PayloadUpsertParseError>> + use<'_> {
- // `clap` ensures we have 3 values per option occurrence,
- // so we can chunk the aggregated slice exactly.
- let chunks = values.chunks_exact(3);
-
- assert!(chunks.remainder().is_empty());
-
- chunks.map(|chunk| {
- // Slice accesses will not panic, guaranteed by `chunks_exact(3)`.
- Ok(PayloadUpsert {
- id: PayloadId::from_str(&chunk[0])?,
- key: chunk[1].to_owned(),
- value: json::from_str(&chunk[2].to_owned())?,
- })
++/// Parses a slice of all payload upserts as aggregated by `clap`
++/// (see [`Command::Update::payload`]).
++/// E.g. `["com.example.one", "name", "1", "com.example.two", "name2", "2"]`
++/// will result in iterator over two [`PayloadUpsert`]s.
++///
++/// # Panics
++///
++/// If the length of `values` is not divisible by 3.
++/// (To catch errors in the definition of the parser derived from
++/// [`Command::Update`] or `clap` itself, and unexpected changes to
++/// `clap`s behaviour in the future.)
++pub(super) fn parse_many_upserts(
++ values: &[String],
++) -> impl Iterator<Item = Result<PayloadUpsert, PayloadUpsertParseError>> + use<'_> {
++ // `clap` ensures we have 3 values per option occurrence,
++ // so we can chunk the aggregated slice exactly.
++ let chunks = values.chunks_exact(3);
++
++ assert!(chunks.remainder().is_empty());
++
++ chunks.map(|chunk| {
++ // Slice accesses will not panic, guaranteed by `chunks_exact(3)`.
++ Ok(PayloadUpsert {
++ id: PayloadId::from_str(&chunk[0])?,
++ key: chunk[1].to_owned(),
++ value: json::from_str(&chunk[2].to_owned())?,
+ })
- }
++ })
+}
+
+#[derive(Clone, Debug)]
+struct EditVisibilityParser;
+
+impl clap::builder::TypedValueParser for EditVisibilityParser {
+ type Value = EditVisibility;
+
+ fn parse_ref(
+ &self,
+ cmd: &clap::Command,
+ arg: Option<&clap::Arg>,
+ value: &std::ffi::OsStr,
+ ) -> Result<Self::Value, clap::Error> {
+ <EditVisibility as std::str::FromStr>::from_str.parse_ref(cmd, arg, value)
+ }
+
+ fn possible_values(
+ &self,
+ ) -> Option<Box<dyn Iterator<Item = clap::builder::PossibleValue> + '_>> {
+ use clap::builder::PossibleValue;
+ Some(Box::new(
+ [PossibleValue::new("private"), PossibleValue::new("public")].into_iter(),
+ ))
+ }
+}
+
+#[derive(Debug, Parser)]
+#[command(about = ABOUT, long_about = LONG_ABOUT, disable_version_flag = true)]
+pub struct Args {
+ #[command(subcommand)]
+ pub(super) command: Option<Command>,
+
+ /// Specify the repository to operate on. Defaults to the current repository
+ ///
+ /// [example values: rad:z3Tr6bC7ctEg2EHmLvknUr29mEDLH, z3Tr6bC7ctEg2EHmLvknUr29mEDLH]
+ #[arg(long)]
+ #[arg(value_name = "RID", global = true)]
+ pub(super) repo: Option<RepoId>,
+
+ /// Do not ask for confirmation
+ #[arg(long)]
+ #[arg(global = true)]
+ no_confirm: bool,
+
+ /// Suppress output
+ #[arg(long, short)]
+ #[arg(global = true)]
+ pub(super) quiet: bool,
+}
+
+impl Args {
+ pub(super) fn interactive(&self) -> Interactive {
+ if self.no_confirm {
+ Interactive::No
+ } else {
+ Interactive::new(io::stdout())
+ }
+ }
+}
+
+#[derive(Subcommand, Debug)]
+pub(super) enum Command {
+ /// Accept a proposed revision to the identity document
+ #[clap(alias("a"))]
+ Accept {
+ /// Proposed revision to accept
+ #[arg(value_name = "REVISION-ID")]
+ revision: Rev,
+ },
+
+ /// Reject a proposed revision to the identity document
+ #[clap(alias("r"))]
+ Reject {
+ /// Proposed revision to reject
+ #[arg(value_name = "REVISION-ID")]
+ revision: Rev,
+ },
+
+ /// Edit an existing revision to the identity document
+ #[clap(alias("e"))]
+ Edit {
+ /// Proposed revision to edit
+ #[arg(value_name = "REVISION-ID")]
+ revision: Rev,
+
+ /// Title of the edit
+ #[arg(long)]
+ title: Option<Title>,
+
+ /// Description of the edit
+ #[arg(long)]
+ description: Option<String>,
+ },
+
+ /// Propose a new revision to the identity document
+ #[clap(alias("u"))]
+ Update {
+ /// Set the title for the new proposal
+ #[arg(long)]
+ title: Option<Title>,
+
+ /// Set the description for the new proposal
+ #[arg(long)]
+ description: Option<String>,
+
+ /// Update the identity by adding a new delegate, identified by their DID
+ #[arg(long, short)]
+ #[arg(value_name = "DID")]
+ #[arg(action = clap::ArgAction::Append)]
+ delegate: Vec<Did>,
+
+ /// Update the identity by removing a delegate, identified by their DID
+ #[arg(long, short)]
+ #[arg(value_name = "DID")]
+ #[arg(action = clap::ArgAction::Append)]
+ rescind: Vec<Did>,
+
+ /// Update the identity by setting the number of delegates required to accept a revision
+ #[arg(long)]
+ threshold: Option<usize>,
+
+ /// Update the identity by setting the repository's visibility to private or public
+ #[arg(long)]
+ #[arg(value_parser = EditVisibilityParser)]
+ visibility: Option<EditVisibility>,
+
+ /// Update the identity by giving a specific DID access to a private repository
+ #[arg(long)]
+ #[arg(value_name = "DID")]
+ #[arg(action = clap::ArgAction::Append)]
+ allow: Vec<Did>,
+
+ /// Update the identity by removing a specific DID's access from a private repository
+ #[arg(long)]
+ #[arg(value_name = "DID")]
+ #[arg(action = clap::ArgAction::Append)]
+ disallow: Vec<Did>,
+
+ /// Update the identity by setting metadata in one of the identity payloads
+ ///
+ /// [example values: xyz.radicle.project name '"radicle-example"']
+ // TODO(erikili:) Value parsers do not operate on series of values, yet. This will
+ // change with clap v5, so we can hopefully use `Vec<Payload>`.
+ // - https://github.com/clap-rs/clap/discussions/5930#discussioncomment-12315889
+ // - https://docs.rs/clap/latest/clap/_derive/index.html#arg-types
+ #[arg(long)]
+ #[arg(value_names = ["TYPE", "KEY", "VALUE"], num_args = 3)]
+ payload: Vec<String>,
+
+ /// Opens your $EDITOR to edit the JSON contents directly
+ #[arg(long)]
+ edit: bool,
+ },
+
+ /// Lists all proposed revisions to the identity document
+ #[clap(alias("l"))]
+ List,
+
+ /// Show a specific identity proposal
+ #[clap(alias("s"))]
+ Show {
+ /// Proposed revision to show
+ #[arg(value_name = "REVISION-ID")]
+ revision: Rev,
+ },
+
+ /// Redact a revision
+ #[clap(alias("d"))]
+ Redact {
+ /// Proposed revision to redact
+ #[arg(value_name = "REVISION-ID")]
+ revision: Rev,
+ },
+}
+
+#[cfg(test)]
+mod test {
- use super::{Args, PayloadUpsert};
++ use super::{parse_many_upserts, Args};
+ use clap::error::ErrorKind;
+ use clap::Parser;
+
+ #[test]
+ fn should_parse_single_payload() {
+ let args = Args::try_parse_from(["id", "update", "--payload", "key", "name", "value"]);
+ assert!(args.is_ok())
+ }
+
+ #[test]
+ fn should_not_parse_single_payload() {
+ let err = Args::try_parse_from(["id", "update", "--payload", "key", "name"]).unwrap_err();
+ assert_eq!(err.kind(), ErrorKind::WrongNumberOfValues);
+ }
+
+ #[test]
+ fn should_parse_multiple_payloads() {
+ let args = Args::try_parse_from([
+ "id",
+ "update",
+ "--payload",
+ "key_1",
+ "name_1",
+ "value_1",
+ "--payload",
+ "key_2",
+ "name_2",
+ "value_2",
+ ]);
+ assert!(args.is_ok())
+ }
+
+ #[test]
+ fn should_not_parse_single_payloads() {
+ let err = Args::try_parse_from([
+ "id",
+ "update",
+ "--payload",
+ "key_1",
+ "name_1",
+ "value_1",
+ "--payload",
+ "key_2",
+ "name_2",
+ ])
+ .unwrap_err();
+ assert_eq!(err.kind(), ErrorKind::WrongNumberOfValues);
+ }
+
+ #[test]
+ fn should_not_clobber_payload_args() {
+ let err = Args::try_parse_from([
+ "id",
+ "update",
+ "--payload",
+ "key_1",
+ "name_1",
+ "--payload", // ensure `--payload is not treated as an argument`
+ "key_2",
+ "name_2",
+ "value_2",
+ ])
+ .unwrap_err();
+ assert_eq!(err.kind(), ErrorKind::WrongNumberOfValues);
+ }
+
+ #[test]
+ fn should_parse_into_payload() {
- let payload: Result<Vec<_>, _> = PayloadUpsert::parse_many(&[
++ let payload: Result<Vec<_>, _> = parse_many_upserts(&[
+ "xyz.radicle.project".to_string(),
+ "name".to_string(),
+ "{}".to_string(),
+ ])
+ .collect();
+ assert!(payload.is_ok())
+ }
+
+ #[test]
+ #[should_panic(expected = "assertion failed: chunks.remainder().is_empty()")]
+ fn should_not_parse_into_payload() {
+ let _: Result<Vec<_>, _> =
- PayloadUpsert::parse_many(&["xyz.radicle.project".to_string(), "name".to_string()])
++ parse_many_upserts(&["xyz.radicle.project".to_string(), "name".to_string()])
+ .collect();
+ }
+}
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 f76a3ffe-d9e2-4dcc-9c7a-3c496f9d65ca -v /opt/radcis/ci.rad.levitte.org/cci/state/f76a3ffe-d9e2-4dcc-9c7a-3c496f9d65ca/s:/f76a3ffe-d9e2-4dcc-9c7a-3c496f9d65ca/s:ro -v /opt/radcis/ci.rad.levitte.org/cci/state/f76a3ffe-d9e2-4dcc-9c7a-3c496f9d65ca/w:/f76a3ffe-d9e2-4dcc-9c7a-3c496f9d65ca/w -w /f76a3ffe-d9e2-4dcc-9c7a-3c496f9d65ca/w -v /opt/radcis/ci.rad.levitte.org/.radicle:/${id}/.radicle:ro -e RAD_HOME=/${id}/.radicle rust:bookworm bash /f76a3ffe-d9e2-4dcc-9c7a-3c496f9d65ca/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 /f76a3ffe-d9e2-4dcc-9c7a-3c496f9d65ca/w/crates/radicle-cli/src/commands/id/args.rs:37:
/// (see [`Command::Update::payload`]).
/// E.g. `["com.example.one", "name", "1", "com.example.two", "name2", "2"]`
/// will result in iterator over two [`PayloadUpsert`]s.
-///
+///
/// # Panics
-///
+///
/// If the length of `values` is not divisible by 3.
/// (To catch errors in the definition of the parser derived from
/// [`Command::Update`] or `clap` itself, and unexpected changes to
Diff in /f76a3ffe-d9e2-4dcc-9c7a-3c496f9d65ca/w/crates/radicle-cli/src/commands/id/args.rs:321:
#[should_panic(expected = "assertion failed: chunks.remainder().is_empty()")]
fn should_not_parse_into_payload() {
let _: Result<Vec<_>, _> =
- parse_many_upserts(&["xyz.radicle.project".to_string(), "name".to_string()])
- .collect();
+ parse_many_upserts(&["xyz.radicle.project".to_string(), "name".to_string()]).collect();
}
}
Exit code: 1
{
"response": "finished",
"result": "failure"
}