rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5 heartwood2924f799ceb2750b4de193c60a83b1d4241e5e2a
{
"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:z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM",
"did:key:z6MkkPvBfjP4bQmco5Dm7UGsX2ruDBieEHi8n9DVJWX5sTEz"
]
},
"action": "Created",
"patch": {
"id": "a68925af32002a24eb2f3ca3c83bf7298f3944cc",
"author": {
"id": "did:key:z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM",
"alias": null
},
"title": "Allow unknown fields in Project deserialization",
"state": {
"status": "merged",
"conflicts": []
},
"before": "72db6dd7dd3d0d9ff430e8c700a4cafaa09d873c",
"after": "2924f799ceb2750b4de193c60a83b1d4241e5e2a",
"commits": [
"2924f799ceb2750b4de193c60a83b1d4241e5e2a",
"9153d60338a4fd314bc50f4713fd871320cf3451"
],
"target": "3fc92f83fe089263c470b328414d923227cf0e4a",
"labels": [],
"assignees": [],
"revisions": [
{
"id": "a68925af32002a24eb2f3ca3c83bf7298f3944cc",
"author": {
"id": "did:key:z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM",
"alias": null
},
"description": "",
"base": "6dd52c94fb1472e251110e439fe656aaed74019f",
"oid": "44f037ed395b8a58fbc5520bbda3098a738f99c6",
"timestamp": 1714997713
},
{
"id": "2c10f2d2f1599ddf5dac62805a783ac1a43e73aa",
"author": {
"id": "did:key:z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM",
"alias": null
},
"description": "Changes:\n- Missed adding test file",
"base": "72db6dd7dd3d0d9ff430e8c700a4cafaa09d873c",
"oid": "eac25807de3982cd13b84ee1d65decfb0aa36788",
"timestamp": 1714998078
},
{
"id": "9407980a2c7ebe0a55a1492300128ced3e79e87e",
"author": {
"id": "did:key:z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM",
"alias": null
},
"description": "Changes:\n- `Unknown` variant needs to hold an owned `String`\n- The test needs to call a command that ends up calling the `Identity::project`\n method to test deserialization",
"base": "72db6dd7dd3d0d9ff430e8c700a4cafaa09d873c",
"oid": "2924f799ceb2750b4de193c60a83b1d4241e5e2a",
"timestamp": 1715011324
},
{
"id": "dd6c5073abb23ef9b204863c8804d68e73f298b4",
"author": {
"id": "did:key:z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM",
"alias": null
},
"description": "Rebase.",
"base": "43b0b2b426b244a4176fd545d8ac1a611455660c",
"oid": "e8f2f88bf622ef1e4082eb060cf4cf176d5ac4d6",
"timestamp": 1715070305
}
]
}
}
{
"response": "triggered",
"run_id": {
"id": "cabac6ee-1b98-45df-82b3-65563d2c1dee"
},
"info_url": "https://cci.rad.levitte.org//cabac6ee-1b98-45df-82b3-65563d2c1dee.html"
}
Started at: 2026-09-08 02:01:26.844719+02:00
Commands:
$ rad clone rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5 .
✓ Creating checkout in ./...
✓ Remote cloudhead@z6MksFqXN3Yhqk8pTJdUGLwATkRfQvwZXPqR2qMEhbS9wzpT added
✓ Remote-tracking branch cloudhead@z6MksFqXN3Yhqk8pTJdUGLwATkRfQvwZXPqR2qMEhbS9wzpT/master created for z6MksFqXN3Yhqk8pTJdUGLwATkRfQvwZXPqR2qMEhbS9wzpT
✓ Remote fintohaps@z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM added
✓ Remote-tracking branch fintohaps@z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM/master created for z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM
✓ 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/cabac6ee-1b98-45df-82b3-65563d2c1dee/w/
╭────────────────────────────────────╮
│ heartwood │
│ Radicle Heartwood Protocol & Stack │
│ 189 issues · 38 patches │
╰────────────────────────────────────╯
Run `cd ./.` to go to the repository directory.
Exit code: 0
$ rad patch checkout a68925af32002a24eb2f3ca3c83bf7298f3944cc
✓ Switched to branch patch/a68925a at revision 9407980
✓ Branch patch/a68925a setup to track rad/patches/a68925af32002a24eb2f3ca3c83bf7298f3944cc
Exit code: 0
$ git config advice.detachedHead false
Exit code: 0
$ git checkout 2924f799ceb2750b4de193c60a83b1d4241e5e2a
HEAD is now at 2924f799 cli: add test for adding an unknown field to the identity document
Exit code: 0
$ rad patch show a68925af32002a24eb2f3ca3c83bf7298f3944cc -p
╭────────────────────────────────────────────────────────────────────────────────╮
│ Title Allow unknown fields in Project deserialization │
│ Patch a68925af32002a24eb2f3ca3c83bf7298f3944cc │
│ Author fintohaps z6Mkire…SQZ3voM │
│ Head 2924f799ceb2750b4de193c60a83b1d4241e5e2a │
│ Base 72db6dd7dd3d0d9ff430e8c700a4cafaa09d873c │
│ Target master │
│ Branches patch/a68925a │
│ Commits ahead 2, behind 1383 │
│ Status merged │
├────────────────────────────────────────────────────────────────────────────────┤
│ 2924f79 cli: add test for adding an unknown field to the identity document │
│ 9153d60 radicle: allow for unknown fields in Project deserialization │
├────────────────────────────────────────────────────────────────────────────────┤
│ ● Revision a68925a @ 6dd52c9..44f037e by fintohaps z6Mkire…SQZ3voM 2 years ago │
│ ↑ Revision 2c10f2d @ 72db6dd..eac2580 by fintohaps z6Mkire…SQZ3voM 2 years ago │
│ ↑ Revision 9407980 @ 72db6dd..2924f79 by fintohaps z6Mkire…SQZ3voM 2 years ago │
│ ↑ Revision dd6c507 @ 43b0b2b..e8f2f88 by cloudhead z6MksFq…bS9wzpT 2 years ago │
│ └─ ✓ merged by cloudhead z6MksFq…bS9wzpT │
╰────────────────────────────────────────────────────────────────────────────────╯
commit 2924f799ceb2750b4de193c60a83b1d4241e5e2a
Author: Fintan Halpenny <fintan.halpenny@gmail.com>
Date: Mon May 6 13:13:05 2024 +0100
cli: add test for adding an unknown field to the identity document
Add a test to confirm that the identity can still be deserialized when an
unknown field is added.
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
diff --git a/radicle-cli/examples/rad-id-unknown-field.md b/radicle-cli/examples/rad-id-unknown-field.md
new file mode 100644
index 000000000..68657dedb
--- /dev/null
+++ b/radicle-cli/examples/rad-id-unknown-field.md
@@ -0,0 +1,47 @@
+The payloads in the identity document are extensible and arbitrary fields can be
+added. Here we will add an emoji alias for the heartwood project:
+
+```
+$ rad id update --title "Add emoji alias" --description "Adding alias field" --payload xyz.radicle.project alias '"❤️🪵"'
+✓ Identity revision 05100d3f0a73b9373681677158615a53ba51940e created
+╭────────────────────────────────────────────────────────────────────────╮
+│ Title Add emoji alias │
+│ Revision 05100d3f0a73b9373681677158615a53ba51940e │
+│ Blob a0f421c928dcfc6eca129fc2ea1f50877de7dc20 │
+│ Author did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi │
+│ State accepted │
+│ Quorum yes │
+│ │
+│ Adding alias field │
+├────────────────────────────────────────────────────────────────────────┤
+│ ✓ did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi alice (you) │
+╰────────────────────────────────────────────────────────────────────────╯
+
+@@ -1,13 +1,14 @@
+ {
+ "payload": {
+ "xyz.radicle.project": {
++ "alias": "❤️🪵",
+ "defaultBranch": "master",
+ "description": "Radicle Heartwood Protocol & Stack",
+ "name": "heartwood"
+ }
+ },
+ "delegates": [
+ "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+ ],
+ "threshold": 1
+ }
+```
+
+We can see that the project payload still loads by using `rad ls` which will
+attempt to deserialize the payload:
+
+```
+$ rad ls
+╭───────────────────────────────────────────────────────────────────────────────────────────────────────────╮
+│ Name RID Visibility Head Description │
+├───────────────────────────────────────────────────────────────────────────────────────────────────────────┤
+│ heartwood rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji public f2de534 Radicle Heartwood Protocol & Stack │
+╰───────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+```
diff --git a/radicle-cli/tests/commands.rs b/radicle-cli/tests/commands.rs
index 2121af6c7..e09d5553c 100644
--- a/radicle-cli/tests/commands.rs
+++ b/radicle-cli/tests/commands.rs
@@ -627,6 +627,35 @@ fn rad_id_conflict() {
.unwrap();
}
+#[test]
+fn rad_id_unknown_field() {
+ let mut environment = Environment::new();
+ let alice = environment.node(config::node("alice"));
+ let working = tempfile::tempdir().unwrap();
+ let working = working.path();
+
+ // Setup a test repository.
+ fixtures::repository(working.join("alice"));
+
+ test(
+ "examples/rad-init.md",
+ working.join("alice"),
+ Some(&alice.home),
+ [],
+ )
+ .unwrap();
+
+ let alice = alice.spawn();
+
+ test(
+ "examples/rad-id-unknown-field.md",
+ working.join("alice"),
+ Some(&alice.home),
+ [],
+ )
+ .unwrap();
+}
+
#[test]
fn rad_node_connect() {
let mut environment = Environment::new();
commit 9153d60338a4fd314bc50f4713fd871320cf3451
Author: Fintan Halpenny <fintan.halpenny@gmail.com>
Date: Mon May 6 13:09:52 2024 +0100
radicle: allow for unknown fields in Project deserialization
Allow unknown fields to pass through when deserializing the `Project` payload.
This allows the deserialization to be more resilient when unknown fields are
added, e.g. from the CLI, and improves backwards-compatability when new fields
may be added in the future.
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
diff --git a/radicle/src/identity/project.rs b/radicle/src/identity/project.rs
index 7b243d32e..78ef7a603 100644
--- a/radicle/src/identity/project.rs
+++ b/radicle/src/identity/project.rs
@@ -47,6 +47,9 @@ impl<'de> Deserialize<'de> for Project {
Name,
Description,
DefaultBranch,
+ /// A catch-all variant to allow for unknown fields
+ #[allow(dead_code)]
+ Unknown(String),
}
struct ProjectVisitor;
@@ -86,6 +89,7 @@ impl<'de> Deserialize<'de> for Project {
}
default_branch = Some(map.next_value()?);
}
+ Field::Unknown(_) => continue,
}
}
let name = name.ok_or_else(|| de::Error::missing_field("name"))?;
Exit code: 0
shell: 'cargo --version rustc --version cargo fmt --check cargo clippy --all-targets --workspace -- --deny clippy::all cargo build --all-targets --workspace cargo doc --workspace cargo test --workspace --no-fail-fast '
Commands:
$ podman run --name cabac6ee-1b98-45df-82b3-65563d2c1dee -v /opt/radcis/ci.rad.levitte.org/cci/state/cabac6ee-1b98-45df-82b3-65563d2c1dee/s:/cabac6ee-1b98-45df-82b3-65563d2c1dee/s:ro -v /opt/radcis/ci.rad.levitte.org/cci/state/cabac6ee-1b98-45df-82b3-65563d2c1dee/w:/cabac6ee-1b98-45df-82b3-65563d2c1dee/w -w /cabac6ee-1b98-45df-82b3-65563d2c1dee/w -v /opt/radcis/ci.rad.levitte.org/.radicle:/${id}/.radicle:ro -e RAD_HOME=/${id}/.radicle rust:trixie bash /cabac6ee-1b98-45df-82b3-65563d2c1dee/s/script.sh
+ cargo --version
info: syncing channel updates for '1.77-x86_64-unknown-linux-gnu'
info: latest update on 2024-04-09, rust version 1.77.2 (25ef9e3d8 2024-04-09)
info: downloading component 'cargo'
info: downloading component 'rust-std'
info: downloading component 'rustc'
info: installing component 'cargo'
info: installing component 'rust-std'
info: installing component 'rustc'
cargo 1.77.2 (e52e36006 2024-03-26)
+ rustc --version
rustc 1.77.2 (25ef9e3d8 2024-04-09)
+ cargo fmt --check
error: 'cargo-fmt' is not installed for the toolchain '1.77-x86_64-unknown-linux-gnu'.
To install, run `rustup component add --toolchain 1.77-x86_64-unknown-linux-gnu rustfmt`
Exit code: 1
{
"response": "finished",
"result": "failure"
}