From 7c2a9d43817d04ceabe48fabf7bf0a34b9803c24 Mon Sep 17 00:00:00 2001 From: Maxerns Date: Mon, 26 Oct 2026 20:32:55 +0000 Subject: [PATCH 1/3] allow the csharp demo to roll forward across major dotnet sdk versions target net8.0 with latest major roll forward enabled so developers with dotnet 8, 9, or 10 installed locally can build and run the csharp example without installing another sdk while ci continues testing against dotnet 10. Signed-off-by: Maxerns --- csharp/Demo.csproj | 3 ++- csharp/README.md | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/csharp/Demo.csproj b/csharp/Demo.csproj index 238f157..edb4445 100644 --- a/csharp/Demo.csproj +++ b/csharp/Demo.csproj @@ -1,7 +1,8 @@ Exe - net10.0 + net8.0 + LatestMajor enable enable diff --git a/csharp/README.md b/csharp/README.md index a8072cb..f38b784 100644 --- a/csharp/README.md +++ b/csharp/README.md @@ -1,6 +1,6 @@ # C# demo -Requires **.NET 10 SDK**. Follow the [root quick start](../README.md#quick-start-with-python) +Requires **.NET 8 SDK or newer**. Follow the [root quick start](../README.md#quick-start-with-python) to install Sotto, run `sotto init` once, and set `DEMO_SECRET`. Run from the **repository root**: From 05d53527bf0c8baa2432e825f461ac6bab111e85 Mon Sep 17 00:00:00 2001 From: Maxerns Date: Mon, 26 Oct 2026 20:33:15 +0000 Subject: [PATCH 2/3] clarify minimum node versions in the javascript and typescript demo guides the javascript example uses only standard process environment apis supported since node 18, and the typescript example uses built in type stripping available without flags since node 22.18. state the actual minimum runtime versions while noting that ci exercises node 24 lts. Signed-off-by: Maxerns --- javascript/README.md | 2 +- typescript/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/README.md b/javascript/README.md index 1a6ed9a..a626768 100644 --- a/javascript/README.md +++ b/javascript/README.md @@ -1,6 +1,6 @@ # JavaScript demo -Requires **Node.js 24 LTS**. Follow the [root quick start](../README.md#quick-start-with-python) +Requires **Node.js 18 or newer** (24 LTS in CI). Follow the [root quick start](../README.md#quick-start-with-python) to install Sotto, run `sotto init` once, and set `DEMO_SECRET`. Run from the **repository root**: diff --git a/typescript/README.md b/typescript/README.md index ebb77c8..f3de973 100644 --- a/typescript/README.md +++ b/typescript/README.md @@ -1,6 +1,6 @@ # TypeScript demo -Requires **Node.js 24.12 or newer**. Follow the [root quick start](../README.md#quick-start-with-python) +Requires **Node.js 22.18 or newer** (24 LTS in CI). Follow the [root quick start](../README.md#quick-start-with-python) to install Sotto, run `sotto init` once, and set `DEMO_SECRET`. Run from the **repository root**: From 8820861c3d426c3e36edfd128fed27b7470d298d Mon Sep 17 00:00:00 2001 From: Maxerns Date: Mon, 26 Oct 2026 20:34:31 +0000 Subject: [PATCH 3/3] add a standard library rust demo and wire it into the example test runner introduce a dependency free rust example that reads demo secret from the process environment with the same exit code and message contract as the existing eight languages. prebuild the binary in check examples before running the four test cases across ubuntu, macos, and windows. Signed-off-by: Maxerns --- .github/workflows/check-examples.yml | 2 +- .gitignore | 2 ++ rust/Cargo.toml | 5 +++++ rust/README.md | 25 +++++++++++++++++++++++++ rust/src/main.rs | 12 ++++++++++++ scripts/check_examples.py | 5 ++++- 6 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 rust/Cargo.toml create mode 100644 rust/README.md create mode 100644 rust/src/main.rs diff --git a/.github/workflows/check-examples.yml b/.github/workflows/check-examples.yml index b14523f..060038a 100644 --- a/.github/workflows/check-examples.yml +++ b/.github/workflows/check-examples.yml @@ -41,7 +41,7 @@ jobs: php-version: '8.4' coverage: none tools: none - - name: Check all eight languages + - name: Check all nine languages run: python scripts/check_examples.py local-sotto: diff --git a/.gitignore b/.gitignore index 190fbed..ee95b29 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,8 @@ sotto.toml **/build/ **/bin/ **/obj/ +**/target/ +**/Cargo.lock **/__pycache__/ *.class node_modules/ diff --git a/rust/Cargo.toml b/rust/Cargo.toml new file mode 100644 index 0000000..4350131 --- /dev/null +++ b/rust/Cargo.toml @@ -0,0 +1,5 @@ +[package] +name = "demo" +version = "0.1.0" +edition = "2021" +publish = false diff --git a/rust/README.md b/rust/README.md new file mode 100644 index 0000000..be2d1cc --- /dev/null +++ b/rust/README.md @@ -0,0 +1,25 @@ +# Rust demo + +Requires **Rust and Cargo** (stable toolchain). Follow the [root quick start](../README.md#quick-start-with-python) +to install Sotto, run `sotto init` once, and set `DEMO_SECRET`. + +Run from the **repository root**: + +```sh +sotto run -- cargo run --quiet --manifest-path rust/Cargo.toml +``` + +Cargo compiles and runs this single binary crate using only the Rust standard library. No external crates are needed. + +Expected output: + +```text +Sotto demo: secret loaded successfully. +``` + +The program reads `DEMO_SECRET` through the standard environment API and never +prints its value. A missing or empty value produces a helpful stderr message +and exit code `1`; any non empty value returns `0`. + +To see the failure, run the same program command without `sotto run --` while +`DEMO_SECRET` is unset in your shell. diff --git a/rust/src/main.rs b/rust/src/main.rs new file mode 100644 index 0000000..4f8846a --- /dev/null +++ b/rust/src/main.rs @@ -0,0 +1,12 @@ +use std::env; +use std::process; + +fn main() { + let has_secret = env::var_os("DEMO_SECRET").is_some_and(|value| !value.is_empty()); + if !has_secret { + eprintln!("DEMO_SECRET is missing or empty. Set it with `sotto set DEMO_SECRET`, then run this demo with `sotto run -- `."); + process::exit(1); + } + + println!("Sotto demo: secret loaded successfully."); +} diff --git a/scripts/check_examples.py b/scripts/check_examples.py index 0eca381..cd7b780 100644 --- a/scripts/check_examples.py +++ b/scripts/check_examples.py @@ -17,13 +17,14 @@ "csharp": ["dotnet", "run", "--no-build", "--no-restore", "--project", "csharp/Demo.csproj"], "php": ["php", "php/main.php"], "go": ["go", "run", "go/main.go"], + "rust": [str(ROOT / "rust/target/debug" / ("demo.exe" if os.name == "nt" else "demo"))], "cpp": [str(ROOT / "cpp/build" / ("demo.exe" if os.name == "nt" else "demo"))], } def main(): parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument("languages", nargs="*", help="Default: all eight languages") + parser.add_argument("languages", nargs="*", help="Default: all nine languages") args = parser.parse_args() languages = args.languages or list(COMMANDS) for language in languages: @@ -32,6 +33,8 @@ def main(): if "csharp" in languages: subprocess.run(["dotnet", "build", "csharp/Demo.csproj", "--nologo"], cwd=ROOT, check=True) + if "rust" in languages: + subprocess.run(["cargo", "build", "--quiet", "--manifest-path", "rust/Cargo.toml"], cwd=ROOT, check=True) if "cpp" in languages: subprocess.run(["cmake", "-S", "cpp", "-B", "cpp/build"], cwd=ROOT, check=True) subprocess.run(["cmake", "--build", "cpp/build", "--config", "Release"], cwd=ROOT, check=True)