Repository: paritytech/polkadot-sdk (language: rust)

Issue:
Polkadot umbrella crate needs a README
No readme https://crates.io/crates/polkadot-sdk 😭

Should explain:
- what it is
- how it is supposed to be used (with small example)
- tips to get the most out of it
- versioning schema
- should look somewhat nice ✨ 


Discussion / hints:
A better example: 

https://crates.io/crates/polkadot-sdk-frame (README is bad, but this is better: https://docs.rs/polkadot-sdk-frame/0.8.0/polkadot_sdk_frame/)

We can use `docify_readme` to have a synchronized `lib.rs` and `README`. @iulianbarbu has experience with this, if need be whoever takes this on, can get some pointers from him.

Next, @ggwpez can you please link a few follow-up features that are needed in the umbrella-crate, seeding the way to have a roadmap for it? like https://github.com/paritytech/polkadot-sdk/issues/5934

Former doc about this, which maybe we can remove if no need for it anymore: 

https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/umbrella_crate/index.html
I’d be happy to help out if that’s okay! 😊

I think I get the motive of syncing the README with doc comments, and I know Rust has something like `#![doc = include_str!("../README.md")]` for that. But it sounds like you’re looking for something more sophisticated? Any pointers on you're referring to? @iulianbarbu @kianenigma 

If it’s still along the lines of "embedding README into the doc comments" regardless, I’d be glad to start working on the README! 💕
Trying to reuse what’s still relevant from https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/umbrella_crate/index.html. I’m a bit confused about the 'Known Issues' section—isn’t it expected behavior that imports aren’t inherited by inner modules? Or am I misunderstanding something here?
>I’m a bit confused about the 'Known Issues' section—isn’t it expected behavior that imports aren’t inherited by inner modules?

Yea but not sure how many devs keep it in mind. Just wanted to point it out.

>I think I get the motive of syncing the README with doc comments, and I know Rust has something like #![doc = include_str!("../README.md")] for that. But it sounds like you’re looking for something more sophisticated?

Not sure what we finally settles on; @kianenigma rather README.md and then `include_str` or writing rust docs directly and then exporting the README?  

I dont really mind either, there just should be a README and it should stay up-to-date somehow with the Rust docs.

Fix patch:
diff --git a/scripts/generate-umbrella.py b/scripts/generate-umbrella.py
index 388573707822f..13b39a6172a90 100644
--- a/scripts/generate-umbrella.py
+++ b/scripts/generate-umbrella.py
@@ -77,7 +77,7 @@ def main(path, version):
 		with open(lib_path, "r") as f:
 			nostd_crate = False
 			for line in f:
-				line = line.strip() 
+				line = line.strip()
 				if line == "#![no_std]" or line == '#![cfg_attr(not(feature = "std"), no_std)]':
 					nostd_crate = True
 					break
@@ -179,16 +179,17 @@ def main(path, version):
 Delete the umbrella folder and remove the umbrella crate from the workspace.
 """
 def delete_umbrella(path):
-	umbrella_dir = os.path.join(path, "umbrella")
 	# remove the umbrella crate from the workspace
 	manifest = os.path.join(path, "Cargo.toml")
 	manifest = open(manifest, "r").read()
 	manifest = re.sub(r'\s+"umbrella",\n', "", manifest)
 	with open(os.path.join(path, "Cargo.toml"), "w") as f:
 		f.write(manifest)
+	umbrella_dir = os.path.join(path, "umbrella")
 	if os.path.exists(umbrella_dir):
 		print(f"Deleting {umbrella_dir}")
-		shutil.rmtree(umbrella_dir)
+		os.remove(os.path.join(umbrella_dir, "Cargo.toml"))
+		shutil.rmtree(os.path.join(umbrella_dir, "src"))
 
 """
 Create the umbrella crate and add it to the workspace.
diff --git a/umbrella/MAINTAIN.md b/umbrella/MAINTAIN.md
new file mode 100644
index 0000000000000..0f092b75ae8ec
--- /dev/null
+++ b/umbrella/MAINTAIN.md
@@ -0,0 +1,12 @@
+`polkadot-sdk` should be updated when another crate is added to or removed from the workspace. There
+is a CI check to ensure that it is in sync with the
+[Polkadot-sdk](https://github.com/paritytech/polkadot-sdk) workspace.​
+
+All the code in this crate is generated by
+[`./scripts/generate-umbrella.py`](../scripts/generate-umbrella.py). We strongly recommend using the
+script for updating rather than editing the files manually. Running the script requires
+[`toml`](https://pypi.org/project/toml/) and
+[`cargo-workspace>=2.2.6`](https://pypi.org/project/cargo-workspace/).​ ​
+```shell​
+python3 ./scripts/generate-umbrella.py --sdk . --version 0.1.0​
+```
diff --git a/umbrella/README.md b/umbrella/README.md
new file mode 100644
index 0000000000000..91b32a72df665
--- /dev/null
+++ b/umbrella/README.md
@@ -0,0 +1,183 @@
+<div align="center">
+
+![SDK Logo](../docs/images/Polkadot_Logo_Horizontal_Pink_White.png#gh-dark-mode-only)
+![SDK Logo](../docs/images/Polkadot_Logo_Horizontal_Pink_Black.png#gh-light-mode-only)
+
+<!-- markdownlint-disable-next-line MD044 -->
+# `polkadot-sdk`
+
+[![StackExchange](https://img.shields.io/badge/StackExchange-Community%20&%20Support-222222?logo=stackexchange)](https://substrate.stackexchange.com/)
+
+</div>
+
+`polkadot-sdk` is an umbrella crate for the [Polkadot
+SDK](https://github.com/paritytech/polkadot-sdk), in the sense that it is an "umbrella" that
+encompasses other components. More specifically, it re-exports all the crates that are needed by
+builders.
+
+`polkadot-sdk` aims to be the entry to the Polkadot and Substrate ecosystem and make the SDK more
+approachable—the entire development environment made available with **one dependency**. More
+importantly, it guarantees the compatible combination of crate versions. So even if you know exactly
+which crates to use, you may still benefit from using `polkadot-sdk` for painless dependency
+updates.
+
+You may have seen another umbrella crate named `polkadot-sdk-frame`. For clarification, while
+`polkadot-sdk` aims to ease dependency management, `polkadot-sdk-frame` intends to simplify
+[FRAME](https://docs.polkadot.com/polkadot-protocol/glossary/#frame-framework-for-runtime-aggregation-of-modularized-entities)
+pallet implementation, as demonstrated in the example below.
+
+## 💻 Usage
+
+The re-exported crates are grouped under the following feature sets.
+
+- `node`: Anything that you need to build a node
+- `runtime`: Most things that you need to build a runtime
+- `runtime-full`: Also the extended runtime features that are sometimes needed
+
+<details>
+<summary>🏋️ Power User Features</summary>
+
+- `experimental`
+- `runtime-benchmarks`
+- `serde`
+- `tuples-96`
+- `try-runtime`
+- `with-tracing`
+
+The power user features are meant to use alongside `node`, `runtime`, or `runtime-full` for extra
+development support. For example, if the runtime relies on [serde](https://crates.io/crates/serde)
+for serialization, and needs tracing and benchmarking for debugging and profiling, the `Cargo.toml`
+may contain the following.
+
+```toml
+[dependencies]
+polkadot-sdk = { version = "0.12.0", features = ["runtime", "serde"], default-features = false }
+
+[features]
+runtime-benchmarks = ["polkadot-sdk/runtime-benchmarks"]
+with-tracing = ["polkadot-sdk/with-tracing"]
+```
+
+```shell
+cargo build --features "runtime-benchmarks,with-tracing"
+```
+
+Substrate's [try-runtime](https://paritytech.github.io/try-runtime-cli/try_runtime/) is an essential
+tool for testing runtime protocol upgrades locally, which can be enabled with the `try-runtime`
+feature.
+
+```toml
+[dependencies]
+polkadot-sdk = { version = "0.12.0", features = ["runtime"], default-features = false }
+
+[features]
+try-runtime = ["polkadot-sdk/try-runtime"]
+```
+
+```shell
+cargo build --features "try-runtime"
+```
+
+In Substrate, a runtime can be seen as a tuple of various pallets. Since the number of pallets can
+vary and there is no way to anticipate it, we have to generate impl-trait for tuples of different
+sizes upfront, from 0-tuple to 64-tuple to be specific (64 is chosen to balance between usability
+and compile time).
+
+Seldomly, when the runtime grows to have more than 64 pallets, the trait implementations will cease
+to apply, in which case the feature `tuples-96` (or even `tuples-128`) must be enabled (at the cost
+of increased compile time).
+
+```toml
+[dependencies]
+polkadot-sdk = { version = "0.12.0", features = ["runtime", "tuples-96"], default-features = false }
+```
+
+In addition to all the features mentioned earlier, each exported crate is feature-gated individually
+with the name identical to the crate name, to provide fine-grained control over the dependencies.
+Enabling features like `node` may pull in dependencies that you don't need. As you become more
+knowledgeable about the SDK, you may consider specifying the exact crate names in the `features`
+list instead to reduce build time.
+
+</details>
+
+---
+
+When using `polkadot-sdk` to build a node, it is a good start to enable the `node` feature.
+
+```toml
+[dependencies]
+polkadot-sdk = { version = "0.12.0", features = ["node"] }
+```
+
+For a runtime implementation, you need the `runtime` feature instead. Besides, you may want to opt
+out of `std` with `default-features = false` to allow the runtime to be executed in environments
+where `std` isn't available.
+
+```toml
+[dependencies]
+polkadot-sdk = { version = "0.12.0", features = ["runtime"], default-features = false }
+```
+
+When building a runtime or writing an application pallet, `polkadot-sdk-frame` can be a handy
+toolkit to start with. It gathers all the common types, traits, and functions from many different
+crates so that you can import them with a one-liner.
+
+`polkadot-sdk-frame` is also a part of `polkadot-sdk`. It is enabled by the `runtime` feature.
+
+```rust
+// It's a convention to rename it to `frame`.
+use polkadot_sdk::polkadot_sdk_frame as frame;
+
+#[frame::pallet(dev_mode)]
+pub mod pallet {
+    // Import declarations aren't automatically inherited.
+    // Need to "re-import" to make `frame` available here.
+    use super::*;
+    // One-liner to import all the dependencies used here.
+    use frame::prelude::*;
+
+    pub type Balance = u128;
+
+    #[pallet::pallet]
+    pub struct Pallet<T>(_);
+
+    #[pallet::config]
+    #[pallet::disable_frame_system_supertrait_check]
+    pub trait Config: frame_system::Config {}
+
+    #[pallet::storage]
+    pub type Balances<T: Config> = StorageMap<_, _, T::AccountId, Balance>;
+
+    impl<T: Config> Pallet<T> {
+        pub fn transfer(
+            from: T::RuntimeOrigin,
+            to: T::AccountId,
+            amount: Balance,
+        ) -> DispatchResult {
+            let sender = ensure_signed(from)?;
+            let sender_balance = Balances::<T>::get(&sender).ok_or("NonExistentAccount")?;
+            let sender_remainder = sender_balance
+                .checked_sub(amount)
+                .ok_or("InsufficientBalance")?;
+
+            Balances::<T>::mutate(to, |b| *b = Some(b.unwrap_or(0) + amount));
+            Balances::<T>::insert(&sender, sender_remainder);
+
+            Ok(())
+        }
+    }
+}
+```
+
+To learn more about building with the Polkadot SDK, you may start with these
+[guides](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/guides/index.html) and
+our [official docs](https://docs.polkadot.com/).
+
+## 🚀 Versioning
+
+We do a stable release for the SDK every three months with a version schema reflecting the release
+cadence, which is tracked in the [release
+registry](https://github.com/paritytech/release-registry/). At the time of writing, the latest
+version is `stable2412` (released in 2024 December). To avoid confusion, we will align the
+versioning of `polkadot-sdk` with the established schema. For instance, the next stable version will
+be `2503.0.0`.


Test patch: