From a782d06b2b077b903e5f4e03a8a7e7c5bdd4453e Mon Sep 17 00:00:00 2001 From: Zeke Foppa Date: Sun, 31 May 2026 18:06:26 -0700 Subject: [PATCH 1/2] Remove `cargo bump-versions` --- .cargo/config.toml | 1 - Cargo.lock | 13 - Cargo.toml | 1 - tools/upgrade-version/Cargo.toml | 16 -- tools/upgrade-version/LICENSE | 1 - tools/upgrade-version/src/main.rs | 386 ------------------------------ 6 files changed, 418 deletions(-) delete mode 100644 tools/upgrade-version/Cargo.toml delete mode 120000 tools/upgrade-version/LICENSE delete mode 100644 tools/upgrade-version/src/main.rs diff --git a/.cargo/config.toml b/.cargo/config.toml index cd65da0b165..7b7b2eb4e1f 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -2,7 +2,6 @@ rustflags = ["--cfg", "tokio_unstable"] [alias] -bump-versions = "run -p upgrade-version --" llm = "run --package xtask-llm-benchmark --bin llm_benchmark --" ci = "run -p ci --" regen = "run -p regen --" diff --git a/Cargo.lock b/Cargo.lock index 862a2f4d67c..8452be2ce12 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10173,19 +10173,6 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" -[[package]] -name = "upgrade-version" -version = "0.1.0" -dependencies = [ - "anyhow", - "chrono", - "clap 4.5.50", - "duct", - "regex", - "semver", - "toml_edit 0.22.27", -] - [[package]] name = "url" version = "2.5.7" diff --git a/Cargo.toml b/Cargo.toml index 2968240b375..05f6fbcc387 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,7 +60,6 @@ members = [ "sdks/rust/tests/view-pk-client", "sdks/rust/tests/event-table-client", "tools/ci", - "tools/upgrade-version", "tools/license-check", "tools/replace-spacetimedb", "tools/generate-client-api", diff --git a/tools/upgrade-version/Cargo.toml b/tools/upgrade-version/Cargo.toml deleted file mode 100644 index 261cab36c58..00000000000 --- a/tools/upgrade-version/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "upgrade-version" -version = "0.1.0" -edition.workspace = true -license-file = "LICENSE" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -toml_edit = "0.22.4" -anyhow.workspace = true -chrono = { workspace = true, features=["clock"] } -clap.workspace = true -regex.workspace = true -duct.workspace = true -semver = "1" diff --git a/tools/upgrade-version/LICENSE b/tools/upgrade-version/LICENSE deleted file mode 120000 index 8540cf8a991..00000000000 --- a/tools/upgrade-version/LICENSE +++ /dev/null @@ -1 +0,0 @@ -../../licenses/BSL.txt \ No newline at end of file diff --git a/tools/upgrade-version/src/main.rs b/tools/upgrade-version/src/main.rs deleted file mode 100644 index a7a6bc41d31..00000000000 --- a/tools/upgrade-version/src/main.rs +++ /dev/null @@ -1,386 +0,0 @@ -#![allow(clippy::disallowed_macros)] - -use anyhow::Context; -use chrono::{Datelike, Local}; -use clap::{Arg, ArgGroup, Command}; -use duct::cmd; -use regex::Regex; -use semver::Version; -use std::env; -use std::fs; -use std::path::Path; -use std::path::PathBuf; - -fn process_license_file(path: &str, version: &str) { - let file = fs::read_to_string(path).unwrap(); - - let version_re = Regex::new(r"(?m)^(Licensed Work:\s+SpacetimeDB )([^\s\r\n]+)\r?$").unwrap(); - let file = version_re.replace_all(&file, |caps: ®ex::Captures| format!("{}{}", &caps[1], version)); - - let date_re = Regex::new(r"(?m)^Change Date:\s+\d{4}-\d{2}-\d{2}\r?$").unwrap(); - let new_date = Local::now() - .with_year(Local::now().year() + 5) - .unwrap() - .format("Change Date: %Y-%m-%d") - .to_string(); - - let file = date_re.replace_all(&file, new_date.as_str()); - - fs::write(path, &*file).unwrap(); -} - -fn edit_toml(path: impl AsRef, f: impl FnOnce(&mut toml_edit::DocumentMut)) -> anyhow::Result<()> { - let path = path.as_ref(); - let mut doc = fs::read_to_string(path)?.parse::()?; - f(&mut doc); - fs::write(path, doc.to_string())?; - Ok(()) -} - -// Update only the first occurrence of the top-level "version" field in a JSON file, -// preserving original formatting and key order. -fn rewrite_json_version_inplace(path: impl AsRef, new_version: &str) -> anyhow::Result<()> { - let path = path.as_ref(); - let contents = fs::read_to_string(path)?; - let re = Regex::new(r#"(?m)^(\s*\"version\"\s*:\s*\")(.*?)(\")"#).unwrap(); - let mut replaced = false; - let updated = re.replacen(&contents, 1, |caps: ®ex::Captures| { - replaced = true; - format!("{}{}{}", &caps[1], new_version, &caps[3]) - }); - if !replaced { - anyhow::bail!( - "Could not find top-level \"version\" field to update in {}", - path.display() - ); - } - fs::write(path, updated.as_ref())?; - Ok(()) -} - -pub fn rewrite_package_json_dependency_version_inplace( - path: impl AsRef, - new_version: &str, -) -> anyhow::Result<()> { - let path = path.as_ref(); - let contents = fs::read_to_string(path).with_context(|| format!("Failed to read {}", path.display()))?; - - // This regex matches: - // "spacetimedb": "1.5.*" → capturing leading whitespace and quotes, then replacing only the version. - let re = Regex::new(r#"(?m)^(\s*"spacetimedb"\s*:\s*")([^"]*)(")"#).expect("Invalid regex"); - - let mut replaced = false; - let updated = re.replacen(&contents, 1, |caps: ®ex::Captures| { - replaced = true; - format!("{}{}{}", &caps[1], new_version, &caps[3]) - }); - - if !replaced { - anyhow::bail!( - "Could not find \"spacetimedb\" dependency to update in {}", - path.display() - ); - } - - fs::write(path, updated.as_ref()).with_context(|| format!("Failed to write updated file to {}", path.display()))?; - - Ok(()) -} - -fn rewrite_cmake_version_inplace(path: impl AsRef, new_version: &str) -> anyhow::Result<()> { - let path = path.as_ref(); - let contents = fs::read_to_string(path)?; - - let mut updated = contents.clone(); - let mut replaced_any = false; - - // (?s) enables dotall mode so . matches newlines - // Matches: project(...VERSION ...) across multiple lines - let re_project = Regex::new(r"(?s)(project\s*\([^)]*?VERSION\s+)([^\s\)]+)").unwrap(); - let replaced_project = re_project.replacen(&updated, 1, |caps: ®ex::Captures| { - replaced_any = true; - format!("{}{}", &caps[1], new_version) - }); - updated = replaced_project.to_string(); - - // Matches: set(SPACETIMEDB_CPP_VERSION "1.12.0" ...) - let re_set = Regex::new(r#"(?m)(\bset\(SPACETIMEDB_CPP_VERSION\s+\")(.*?)(\"\s+CACHE\s+STRING)"#).unwrap(); - let replaced_set = re_set.replacen(&updated, 1, |caps: ®ex::Captures| { - replaced_any = true; - format!("{}{}{}", &caps[1], new_version, &caps[3]) - }); - updated = replaced_set.to_string(); - - if !replaced_any { - anyhow::bail!("Could not find CMake version to update in {}", path.display()); - } - - fs::write(path, updated)?; - Ok(()) -} - -fn main() -> anyhow::Result<()> { - let matches = Command::new("upgrade-version") - .version("1.0") - .about("Upgrades the version of the SpacetimeDB repository") - .arg( - Arg::new("upgrade_version") - .required(true) - .help("The version to upgrade to"), - ) - .arg( - Arg::new("spacetime-path") - .value_parser(clap::value_parser!(PathBuf)) - .long("spacetime-path") - .help("The path to SpacetimeDB. If not provided, uses the current directory."), - ) - .arg( - Arg::new("typescript") - .long("typescript") - .action(clap::ArgAction::SetTrue) - .help("Also bump the version of the TypeScript SDK (crates/bindings-typescript/package.json)"), - ) - .arg( - Arg::new("rust-and-cli") - .long("rust-and-cli") - .action(clap::ArgAction::SetTrue) - .help("Whether to update Rust workspace TOMLs, CLI template, and license files (default: true)"), - ) - .arg( - Arg::new("csharp") - .long("csharp") - .action(clap::ArgAction::SetTrue) - .help("Also bump versions in C# SDK and templates"), - ) - .arg( - Arg::new("cpp") - .long("cpp") - .action(clap::ArgAction::SetTrue) - .help("Also bump the version in C++ bindings (crates/bindings-cpp/CMakeLists.txt)"), - ) - .arg( - Arg::new("all") - .long("all") - .action(clap::ArgAction::SetTrue) - .help("Update all targets (equivalent to --typescript --rust-and-cli --csharp --cpp)") - .conflicts_with_all(["typescript", "rust-and-cli", "csharp", "cpp"]), - ) - .arg( - Arg::new("accept-snapshots") - .long("accept-snapshots") - .action(clap::ArgAction::SetTrue) - .help("If there are snapshots to review automatically accept them all."), - ) - .group( - ArgGroup::new("update-targets") - .args(["all", "typescript", "rust-and-cli", "csharp", "cpp"]) - .required(true) - .multiple(true), - ) - .get_matches(); - - let unparsed_version_arg = matches.get_one::("upgrade_version").unwrap(); - let semver = Version::parse(unparsed_version_arg).expect("Invalid semver provided to upgrade-version"); - let numeric_version = format!("{}.{}.{}", semver.major, semver.minor, semver.patch); - let full_version = semver.to_string(); - let wildcard_patch = format!("{}.{}.*", semver.major, semver.minor); - - if let Some(path) = matches.get_one::("spacetime-path") { - env::set_current_dir(path).ok(); - } - - let current_dir = env::current_dir().expect("No current directory!"); - let dir_name = current_dir.file_name().expect("No current directory!"); - if dir_name != "SpacetimeDB" && dir_name != "public" { - anyhow::bail!("You must execute this binary from inside of the SpacetimeDB directory, or use --spacetime-path"); - } - - if matches.get_flag("rust-and-cli") || matches.get_flag("all") { - // Use `=` for dependency versions, to avoid issues where Cargo automatically rolls forward to later minor versions. - // See https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#default-requirements. - let dep_version = format!("={full_version}"); - - // root Cargo.toml - edit_toml("Cargo.toml", |doc| { - doc["workspace"]["package"]["version"] = toml_edit::value(full_version.clone()); - for (key, dep) in doc["workspace"]["dependencies"] - .as_table_like_mut() - .expect("workspace.dependencies is not a table") - .iter_mut() - { - if key.get().starts_with("spacetime") { - dep["version"] = toml_edit::value(dep_version.clone()) - } - } - })?; - - process_license_file("LICENSE.txt", &full_version); - process_license_file("licenses/BSL.txt", &full_version); - // Rebuild `Cargo.lock` - println!("$> cargo check"); - cmd!("cargo", "check").run().expect("Cargo check failed!"); - - // Update the lockfile in crates/smoketests/modules.. - println!("$> cd crates/smoketests/modules && cargo check"); - cmd!("cargo", "check") - .dir("crates/smoketests/modules") - .run() - .expect("cargo check in crates/smoketests/modules failed!"); - - println!("$> pnpm install"); - cmd!("pnpm", "install").run().expect("pnpm run build failed!"); - - println!("$> pnpm run build"); - cmd!("pnpm", "run", "build").run().expect("pnpm run build failed!"); - - println!("$> pnpm --dir templates/chat-react-ts generate"); - cmd!("pnpm", "--dir", "templates/chat-react-ts", "generate") - .run() - .expect("pnpm generate failed!"); - - if matches.get_flag("accept-snapshots") { - // Generate and auto-accept snapshots - println!("$> INSTA_UPDATE=always cargo test -p spacetimedb-codegen --test codegen"); - cmd!("cargo", "test", "-p", "spacetimedb-codegen", "--test", "codegen") - .env("INSTA_UPDATE", "always") - .run() - .expect("cargo test -p spacetimedb-codegen --test codegen (INSTA_UPDATE=always) failed!"); - } else { - println!("$> cargo install cargo-insta"); - cmd!("cargo", "install", "cargo-insta") - .run() - .expect("cargo install cargo-insta failed!"); - - // Initial test - this will generate snapshots. This is expected to fail. - println!("$> cargo test -p spacetimedb-codegen --test codegen"); - let _ = cmd!("cargo", "test", "-p", "spacetimedb-codegen", "--test", "codegen").run(); - - // Review the new snapshots - println!("$> cargo insta review"); - cmd!("cargo", "insta", "review") - .run() - .expect("cargo insta review failed!"); - - // Test again now that the user has had a chance to accept the snapshots - println!("$> cargo test -p spacetimedb-codegen --test codegen"); - cmd!("cargo", "test", "-p", "spacetimedb-codegen", "--test", "codegen") - .run() - .expect("cargo test -p spacetimedb-codegen --test codegen failed!"); - } - } - - if matches.get_flag("typescript") || matches.get_flag("all") { - rewrite_json_version_inplace("crates/bindings-typescript/package.json", &full_version)?; - - rewrite_package_json_dependency_version_inplace( - "crates/cli/src/subcommands/project/typescript/package._json", - &wildcard_patch, - )?; - } - - if matches.get_flag("csharp") || matches.get_flag("all") { - // Helpers for XML edits - fn rewrite_xml_tag_value(path: &str, tag: &str, new_value: &str) -> anyhow::Result<()> { - let contents = fs::read_to_string(path)?; - let re = Regex::new(&format!(r"(?ms)(<\s*{tag}\s*>\s*)([^<]*?)(\s*<\s*/\s*{tag}\s*>)")).unwrap(); - let mut replaced = false; - let updated = re.replacen(&contents, 1, |caps: ®ex::Captures| { - replaced = true; - format!("{}{}{}", &caps[1], new_value, &caps[3]) - }); - if replaced { - fs::write(path, updated.as_ref())?; - } - Ok(()) - } - - fn rewrite_csproj_package_ref_version(path: &str, package: &str, new_version: &str) -> anyhow::Result<()> { - let contents = fs::read_to_string(path)?; - let mut changed = false; - // Version as attribute - let re_attr = Regex::new(&format!( - r#"(?ms)(]*?Include="{}"[^>]*?\sVersion=")(.*?)(")"#, - regex::escape(package) - )) - .unwrap(); - let updated_attr = re_attr.replace_all(&contents, |caps: ®ex::Captures| { - changed = true; - format!("{}{}{}", &caps[1], new_version, &caps[3]) - }); - - // Version as child element - let re_child = Regex::new(&format!( - r#"(?ms)(]*?Include="{}"[^>]*?>.*?)([^<]*?)()"#, - regex::escape(package) - )) - .unwrap(); - let updated = re_child.replace_all(updated_attr.as_ref(), |caps: ®ex::Captures| { - changed = true; - format!("{}{}{}", &caps[1], new_version, &caps[3]) - }); - - if changed { - fs::write(path, updated.as_ref())?; - } - Ok(()) - } - - // 1) Client SDK csproj - let client_sdk = "sdks/csharp/SpacetimeDB.ClientSDK.csproj"; - rewrite_xml_tag_value(client_sdk, "Version", &full_version)?; - // doesn't support prerelease or metadata version suffixes like does. - rewrite_xml_tag_value(client_sdk, "AssemblyVersion", &numeric_version)?; - // Update SpacetimeDB.BSATN.Runtime dependency to major.minor.* - rewrite_csproj_package_ref_version(client_sdk, "SpacetimeDB.BSATN.Runtime", &wildcard_patch)?; - - // Also bump the C# SDK package.json version (preserve formatting) - rewrite_json_version_inplace("sdks/csharp/package.json", &full_version)?; - - // 2) StdbModule.csproj files: SpacetimeDB.Runtime dependency -> major.minor - let stdb_modules: &[&str] = &[ - "demo/Blackholio/server-csharp/StdbModule.csproj", - "templates/chat-console-cs/spacetimedb/StdbModule.csproj", - "sdks/csharp/examples~/regression-tests/server/StdbModule.csproj", - ]; - for path in stdb_modules { - rewrite_csproj_package_ref_version(path, "SpacetimeDB.Runtime", &wildcard_patch)?; - } - - // 3) Version in BSATN.Runtime.csproj, Runtime.csproj, BSATN.Codegen.csproj, Codegen.csproj - rewrite_xml_tag_value( - "crates/bindings-csharp/BSATN.Runtime/BSATN.Runtime.csproj", - "Version", - &full_version, - )?; - rewrite_xml_tag_value( - "crates/bindings-csharp/Runtime/Runtime.csproj", - "Version", - &full_version, - )?; - rewrite_xml_tag_value( - "crates/bindings-csharp/BSATN.Codegen/BSATN.Codegen.csproj", - "Version", - &full_version, - )?; - rewrite_xml_tag_value( - "crates/bindings-csharp/Codegen/Codegen.csproj", - "Version", - &full_version, - )?; - - // 4) Template StdbModule.csproj: SpacetimeDB.Runtime dependency -> major.minor.* - rewrite_csproj_package_ref_version( - "templates/basic-cs/spacetimedb/StdbModule.csproj", - "SpacetimeDB.Runtime", - &wildcard_patch, - )?; - } - if matches.get_flag("cpp") || matches.get_flag("all") { - #[allow(unreachable_code)] - { - rewrite_cmake_version_inplace("crates/bindings-cpp/CMakeLists.txt", &full_version)?; - rewrite_cmake_version_inplace("templates/basic-cpp/spacetimedb/CMakeLists.txt", &full_version)?; - } - } - Ok(()) -} From 50d11694e983cefb0167ad58f456d872b293acbf Mon Sep 17 00:00:00 2001 From: Zeke Foppa Date: Sun, 31 May 2026 18:13:37 -0700 Subject: [PATCH 2/2] CI --- .github/workflows/ci.yml | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a4cf78b4ac0..bda5458d10d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1118,24 +1118,3 @@ jobs: # - name: Print rows in the user table # if: always() # run: spacetime sql quickstart-chat "SELECT * FROM user" - - version_upgrade_check: - runs-on: spacetimedb-new-runner-2 - steps: - - name: Checkout - uses: actions/checkout@v3 - - uses: dsherret/rust-toolchain-file@v1 - - name: Set default rust toolchain - run: rustup default $(rustup show active-toolchain | cut -d' ' -f1) - # pnpm is required for regenerating the typescript bindings - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: 20 - - uses: ./.github/actions/setup-pnpm - with: - run_install: true - - name: Verify that upgrade-version still works - run: cargo ci version-upgrade-check - - name: Show diff - run: git diff HEAD