lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README

commit 646e3c75b633b03aac6d1828632dd1719ed3b8fc
parent 6b5512f76de02819b2db90ddc4f3f0bc1b17af6a
Author: triesap <tyson@radroots.org>
Date:   Tue,  4 Aug 2026 11:38:03 +0000

build(release): stage sdk crate publication

- enable only radroots_sdk and the radroots facade
- preserve private sdk workspace publication blocks
- record sdk before facade in the local order
- validate staged registry flags and policy order

Diffstat:
Mcrates/radroots/Cargo.toml | 2+-
Mcrates/sdk/Cargo.toml | 2+-
Mtools/sdk_xtask_import/src/architecture.rs | 10+++++++---
Mtools/sdk_xtask_import/src/check.rs | 40++++++++++++++++++++++++++++++++++++++--
4 files changed, 47 insertions(+), 7 deletions(-)

diff --git a/crates/radroots/Cargo.toml b/crates/radroots/Cargo.toml @@ -13,7 +13,7 @@ documentation = "https://docs.rs/radroots" keywords = ["radroots", "local-food", "sdk", "nostr"] categories = ["api-bindings", "asynchronous", "network-programming"] include = ["src/**", "examples/**", "Cargo.toml", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] -publish = false +publish = ["crates-io"] autoexamples = false [package.metadata.docs.rs] diff --git a/crates/sdk/Cargo.toml b/crates/sdk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "radroots_sdk" -publish = false +publish = ["crates-io"] version.workspace = true edition.workspace = true authors.workspace = true diff --git a/tools/sdk_xtask_import/src/architecture.rs b/tools/sdk_xtask_import/src/architecture.rs @@ -443,9 +443,13 @@ fn validate_public_package_metadata( "public package {name} must use an existing crate-local {PUBLIC_README}" )); } - if package.get("publish").and_then(toml::Value::as_bool) != Some(false) { + let publish_registries = package + .get("publish") + .and_then(toml::Value::as_array) + .ok_or_else(|| format!("public package {name} must set publish = [\"crates-io\"]"))?; + if publish_registries.len() != 1 || publish_registries[0].as_str() != Some("crates-io") { return Err(format!( - "public package {name} must remain publish = false during migration" + "public package {name} must set publish = [\"crates-io\"]" )); } let inherits_lints = manifest @@ -1387,7 +1391,7 @@ adr_required = false complete_workspace_manifest("\"crates/radroots\""), ) .expect("write workspace manifest"); - let manifest = "[package]\nname = \"radroots\"\nversion.workspace = true\nedition.workspace = true\nrust-version.workspace = true\nlicense.workspace = true\nrepository.workspace = true\nhomepage.workspace = true\nauthors.workspace = true\nreadme = \"README.md\"\npublish = false\n\n[lints]\nworkspace = true\n"; + let manifest = "[package]\nname = \"radroots\"\nversion.workspace = true\nedition.workspace = true\nrust-version.workspace = true\nlicense.workspace = true\nrepository.workspace = true\nhomepage.workspace = true\nauthors.workspace = true\nreadme = \"README.md\"\npublish = [\"crates-io\"]\n\n[lints]\nworkspace = true\n"; fs::write(root.join("crates/radroots/Cargo.toml"), manifest) .expect("write public manifest"); fs::write(root.join("crates/radroots/README.md"), "fixture\n") diff --git a/tools/sdk_xtask_import/src/check.rs b/tools/sdk_xtask_import/src/check.rs @@ -93,6 +93,13 @@ struct CargoMetadataPackage { struct PublicationPolicyFile { publication: PublicationPolicy, workspace_classification: WorkspacePublicationClassification, + #[serde(default)] + publish_order: PublishOrder, +} + +#[derive(Debug, Default, Deserialize)] +struct PublishOrder { + crates: Vec<String>, } #[derive(Debug, Deserialize)] @@ -198,8 +205,12 @@ fn check_radroots_facade_conformance(root: &Path) -> Result<(), String> { )); } } - if package.get("publish").and_then(toml::Value::as_bool) != Some(false) { - return Err("radroots facade must remain publish = false during the scaffold".to_owned()); + let publish = package + .get("publish") + .and_then(toml::Value::as_array) + .ok_or_else(|| "radroots facade must set publish = [\"crates-io\"]".to_owned())?; + if publish.len() != 1 || publish[0].as_str() != Some("crates-io") { + return Err("radroots facade must set publish = [\"crates-io\"]".to_owned()); } for field in [ "version", @@ -408,6 +419,7 @@ fn check_publication_policy(root: &Path) -> Result<(), String> { .map_err(|error| format!("failed to read {}: {error}", policy_path.display()))?; let policy_file = toml::from_str::<PublicationPolicyFile>(&raw) .map_err(|error| format!("failed to parse {}: {error}", policy_path.display()))?; + let publish_order = policy_file.publish_order.crates.clone(); let policy = policy_file.publication; if policy.registry != "crates-io" { return Err("publication.registry must be crates-io".to_owned()); @@ -490,6 +502,24 @@ fn check_publication_policy(root: &Path) -> Result<(), String> { "local and external package ownership must partition approved packages".to_owned(), ); } + if policy.frozen { + if !publish_order.is_empty() { + return Err( + "publish_order.crates must remain empty while publication is frozen".to_owned(), + ); + } + } else { + let publish_order_set = policy_set(publish_order.iter().cloned(), "publish_order.crates")?; + if publish_order_set != local { + return Err( + "publish_order.crates must contain exactly the approved local packages when publication is enabled" + .to_owned(), + ); + } + if publish_order != ["radroots_sdk", "radroots"] { + return Err("publish_order.crates must place radroots_sdk before radroots".to_owned()); + } + } let mut workspace_packages = BTreeSet::new(); for path in sdk_manifest_paths(root)?.into_iter().skip(1) { @@ -2526,6 +2556,11 @@ mod tests { private: &[&str], build_codegen: &[&str], ) -> String { + let publish_order = if frozen { + String::new() + } else { + "\n[publish_order]\ncrates = [\"radroots_sdk\", \"radroots\"]\n".to_owned() + }; format!( r#"[publication] frozen = {frozen} @@ -2542,6 +2577,7 @@ build_codegen = [{}] test_support = [] preview = [] retired = [] +{publish_order} "#, toml_strings(approved), toml_strings(&APPROVED_CRATES[..17]),