Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
e93cfb3
help text fix
bfops Apr 21, 2026
ac1dc96
readme
bfops Apr 21, 2026
2c8803d
comment
bfops Apr 21, 2026
e9d387c
WIP
bfops Apr 21, 2026
358150c
move
bfops Apr 21, 2026
675005c
fix
bfops Apr 21, 2026
f4ad5eb
readme
bfops Apr 21, 2026
34f1e79
revert
bfops Apr 21, 2026
107e1ed
Apply suggestion from @bfops
bfops Apr 21, 2026
bf1d20e
refactor
bfops Apr 22, 2026
c6813bd
revert
bfops Apr 22, 2026
1a4aec4
Merge remote-tracking branch 'origin/bfops/factor-ci' into bfops/ci-all
bfops Apr 22, 2026
322aa82
review
bfops Apr 22, 2026
7fa0859
CI - Merge workflow files
bfops Apr 22, 2026
428d0f5
revert
bfops Apr 22, 2026
6a89902
fix warnings
bfops Apr 22, 2026
85c08a5
fix permissions
bfops Apr 22, 2026
cf5a1cc
Merge remote-tracking branch 'origin/bfops/move-ci' into bfops/ci-all
bfops Apr 22, 2026
8ae4217
revert
bfops Apr 22, 2026
cf5250a
Merge branch 'master' into bfops/move-ci
bfops Apr 22, 2026
6d22b2b
Merge remote-tracking branch 'origin/bfops/move-ci' into bfops/ci-all
bfops Apr 22, 2026
545a53f
CI - Move simple jobs into `cargo ci`
bfops Apr 22, 2026
784c13d
remove
bfops Apr 22, 2026
ec7dcc1
remove unnecessary
bfops Apr 22, 2026
cdbe9bf
comment out unused
bfops Apr 22, 2026
0b70cfa
Merge remote-tracking branch 'origin/bfops/simple-ci' into bfops/ci-all
bfops Apr 22, 2026
13f930f
revert
bfops Apr 22, 2026
5fd2dab
update README
bfops Apr 22, 2026
b788529
Merge remote-tracking branch 'origin/bfops/simple-ci' into bfops/ci-all
bfops Apr 22, 2026
71c6c08
Revert "CI - Upgrade job runs on windows"
bfops Apr 22, 2026
62fb353
Merge commit '2aa27b0dd' into bfops/simple-ci
bfops Apr 22, 2026
4a6c2b0
Merge remote-tracking branch 'origin/master' into bfops/simple-ci
bfops Apr 22, 2026
b82ba3d
Merge commit 'origin/bfops/simple-ci~1' into bfops/ci-all
bfops Apr 22, 2026
009eab2
Merge remote-tracking branch 'origin/bfops/simple-ci' into bfops/ci-all
bfops Apr 22, 2026
f6e71be
readme
bfops Apr 22, 2026
b13c284
Merge remote-tracking branch 'origin/bfops/simple-ci' into bfops/ci-all
bfops Apr 22, 2026
300cd85
Merge commit '0a08879e8' into bfops/ci-all
bfops Apr 23, 2026
8549502
Merge commit '604bb3e64' into bfops/ci-all
bfops Apr 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 4 additions & 101 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -619,31 +619,7 @@ jobs:
with:
global-json-file: global.json

- name: Override NuGet packages
run: |
dotnet pack crates/bindings-csharp/BSATN.Runtime
dotnet pack crates/bindings-csharp/Runtime

# Write out the nuget config file to `nuget.config`. This causes the spacetimedb-csharp-sdk repository
# to be aware of the local versions of the `bindings-csharp` packages in SpacetimeDB, and use them if
# available. Otherwise, `spacetimedb-csharp-sdk` will use the NuGet versions of the packages.
# This means that (if version numbers match) we will test the local versions of the C# packages, even
# if they're not pushed to NuGet.
# See https://learn.microsoft.com/en-us/nuget/reference/nuget-config-file for more info on the config file.
cd sdks/csharp
./tools~/write-nuget-config.sh ../..

- name: Restore .NET solution
working-directory: sdks/csharp
run: dotnet restore --configfile NuGet.Config SpacetimeDB.ClientSDK.sln

# Now, setup the Unity tests.
- name: Patch spacetimedb dependency in Cargo.toml
working-directory: demo/Blackholio/server-rust
run: |
sed -i "s|spacetimedb *=.*|spacetimedb = \{ path = \"../../../crates/bindings\" \}|" Cargo.toml
cat Cargo.toml

- name: Install Rust toolchain
uses: dsherret/rust-toolchain-file@v1
- name: Set default rust toolchain
Expand Down Expand Up @@ -681,19 +657,8 @@ jobs:
# Add a handy alias using the old binary name, so that we don't have to rewrite all scripts (incl. in submodules).
ln -sf $CARGO_HOME/bin/spacetimedb-cli $CARGO_HOME/bin/spacetime

- name: Generate client bindings
working-directory: demo/Blackholio/server-rust
run: bash ./generate.sh -y

- name: Check for changes
run: |
tools/check-diff.sh demo/Blackholio/client-unity/Assets/Scripts/autogen || {
echo 'Error: Bindings are dirty. Please run `demo/Blackholio/server-rust/generate.sh`.'
exit 1
}

- name: Hydrate Unity SDK DLLs
run: cargo ci dlls
- name: Prepare Unity test workspace
run: cargo ci unity-tests

- name: Check Unity meta files
uses: DeNA/unity-meta-check@v3
Expand All @@ -703,23 +668,6 @@ jobs:
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"

- name: Start SpacetimeDB
run: |
spacetime start &
disown

- name: Publish unity-tests module to SpacetimeDB
working-directory: demo/Blackholio/server-rust
run: |
spacetime logout && spacetime login --server-issued-login local
bash ./publish.sh

- name: Patch com.clockworklabs.spacetimedbsdk dependency in manifest.json
working-directory: demo/Blackholio/client-unity/Packages
run: |
yq e -i '.dependencies["com.clockworklabs.spacetimedbsdk"] = "file:../../../../sdks/csharp"' manifest.json
cat manifest.json

- uses: actions/cache@v3
with:
path: demo/Blackholio/client-unity/Library
Expand Down Expand Up @@ -764,32 +712,6 @@ jobs:
with:
global-json-file: global.json

- name: Override NuGet packages
run: |
dotnet pack crates/bindings-csharp/BSATN.Runtime
dotnet pack crates/bindings-csharp/Runtime

# Write out the nuget config file to `nuget.config`. This causes the spacetimedb-csharp-sdk repository
# to be aware of the local versions of the `bindings-csharp` packages in SpacetimeDB, and use them if
# available. Otherwise, `spacetimedb-csharp-sdk` will use the NuGet versions of the packages.
# This means that (if version numbers match) we will test the local versions of the C# packages, even
# if they're not pushed to NuGet.
# See https://learn.microsoft.com/en-us/nuget/reference/nuget-config-file for more info on the config file.
cd sdks/csharp
./tools~/write-nuget-config.sh ../..

- name: Restore .NET solution
working-directory: sdks/csharp
run: dotnet restore --configfile NuGet.Config SpacetimeDB.ClientSDK.sln

- name: Run .NET tests
working-directory: sdks/csharp
run: dotnet test -warnaserror --no-restore

- name: Verify C# formatting
working-directory: sdks/csharp
run: dotnet format --no-restore --verify-no-changes SpacetimeDB.ClientSDK.sln

- name: Install Rust toolchain
uses: dsherret/rust-toolchain-file@v1
- name: Set default rust toolchain
Expand Down Expand Up @@ -833,15 +755,6 @@ jobs:
# Add a handy alias using the old binary name, so that we don't have to rewrite all scripts (incl. in submodules).
ln -sf $CARGO_HOME/bin/spacetimedb-cli $CARGO_HOME/bin/spacetime

- name: Check quickstart-chat bindings are up to date
working-directory: sdks/csharp
run: |
bash tools~/gen-quickstart.sh
"${GITHUB_WORKSPACE}"/tools/check-diff.sh examples~/quickstart-chat || {
echo 'Error: quickstart-chat bindings have changed. Please run `sdks/csharp/tools~/gen-quickstart.sh`.'
exit 1
}

# TODO: Re-enable this once csharp is using the v2 ws api.
# - name: Check client-api bindings are up to date
# working-directory: sdks/csharp
Expand All @@ -852,18 +765,8 @@ jobs:
# exit 1
# }

- name: Start SpacetimeDB
run: |
spacetime start &
disown

- name: Run regression tests
run: |
bash sdks/csharp/tools~/run-regression-tests.sh
tools/check-diff.sh sdks/csharp/examples~/regression-tests || {
echo 'Error: Bindings are dirty. Please run `sdks/csharp/tools~/gen-regression-tests.sh`.'
exit 1
}
- name: Run C# tests
run: cargo ci csharp-tests

internal-tests:
name: Internal Tests
Expand Down
22 changes: 22 additions & 0 deletions tools/ci/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,28 @@ Usage: docs

- `--help`: Print help

### `csharp-tests`

**Usage:**
```bash
Usage: csharp-tests
```

**Options:**

- `--help`: Print help

### `unity-tests`

**Usage:**
```bash
Usage: unity-tests
```

**Options:**

- `--help`: Print help

### `help`

**Usage:**
Expand Down
141 changes: 140 additions & 1 deletion tools/ci/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#![allow(clippy::disallowed_macros)]

use anyhow::{bail, Result};
use anyhow::{bail, ensure, Result};
use clap::{CommandFactory, Parser, Subcommand};
use duct::cmd;
use regex::Regex;
use std::ffi::OsStr;
use std::ffi::OsString;
use std::path::Path;
Expand Down Expand Up @@ -278,6 +279,10 @@ enum CiCmd {
TypescriptTest,
/// Builds the docs site.
Docs,
/// Runs the C# SDK test suite and binding checks.
CsharpTests,
/// Prepares the Unity test workspace and publishes the local test module.
UnityTests,
}

fn run_all_clap_subcommands(skips: &[String]) -> Result<()> {
Expand Down Expand Up @@ -443,6 +448,132 @@ fn run_docs_build() -> Result<()> {
Ok(())
}

fn prepare_csharp_sdk_solution() -> Result<()> {
cmd!(
"dotnet",
"pack",
"crates/bindings-csharp/BSATN.Runtime",
"-c",
"Release"
)
.run()?;
cmd!("dotnet", "pack", "crates/bindings-csharp/Runtime", "-c", "Release").run()?;
cmd!("bash", "./tools~/write-nuget-config.sh", "../..")
.dir("sdks/csharp")
.run()?;
cmd!(
"dotnet",
"restore",
"--configfile",
"NuGet.Config",
"SpacetimeDB.ClientSDK.sln"
)
.dir("sdks/csharp")
.run()?;
Ok(())
}

fn run_local_spacetime_script(script_name: &str, body: &str) -> Result<()> {
let script = format!(
r#"set -euo pipefail
spacetime start >"/tmp/{script_name}.log" 2>&1 &
STDB_PID=$!
trap 'kill "$STDB_PID" >/dev/null 2>&1 || true' EXIT
sleep 3
{body}
"#
);
cmd!("bash", "-lc", &script).run()?;
Ok(())
}

fn run_csharp_tests() -> Result<()> {
prepare_csharp_sdk_solution()?;

cmd!("dotnet", "test", "-warnaserror", "--no-restore")
.dir("sdks/csharp")
.run()?;
cmd!(
"dotnet",
"format",
"--no-restore",
"--verify-no-changes",
"SpacetimeDB.ClientSDK.sln"
)
.dir("sdks/csharp")
.run()?;

cmd!("bash", "tools~/gen-quickstart.sh").dir("sdks/csharp").run()?;
let diff_status = cmd!("bash", "tools/check-diff.sh", "sdks/csharp/examples~/quickstart-chat").run()?;
if !diff_status.status.success() {
bail!("quickstart-chat bindings have changed. Please run `sdks/csharp/tools~/gen-quickstart.sh`.");
}

run_local_spacetime_script(
"spacetimedb-csharp-tests",
r#"bash sdks/csharp/tools~/run-regression-tests.sh"#,
)?;
let diff_status = cmd!("bash", "tools/check-diff.sh", "sdks/csharp/examples~/regression-tests").run()?;
if !diff_status.status.success() {
bail!("Bindings are dirty. Please run `sdks/csharp/tools~/gen-regression-tests.sh`.");
}

Ok(())
}

fn patch_blackholio_server_dependency() -> Result<()> {
let cargo_toml_path = Path::new("demo/Blackholio/server-rust/Cargo.toml");
let existing = fs::read_to_string(cargo_toml_path)?;
let dependency_line = Regex::new(r#"(?m)^spacetimedb\s*=.*$"#)?;
let updated = dependency_line.replace(&existing, r#"spacetimedb = { path = "../../../crates/bindings" }"#);

ensure!(
updated.as_ref() != existing,
"Failed to patch demo/Blackholio/server-rust/Cargo.toml with local spacetimedb dependency"
);

fs::write(cargo_toml_path, updated.as_ref())?;
Ok(())
}

fn run_unity_tests() -> Result<()> {
prepare_csharp_sdk_solution()?;
patch_blackholio_server_dependency()?;

cmd!("bash", "./generate.sh", "-y")
.dir("demo/Blackholio/server-rust")
.run()?;
let diff_status = cmd!(
"bash",
"tools/check-diff.sh",
"demo/Blackholio/client-unity/Assets/Scripts/autogen",
)
.run()?;
if !diff_status.status.success() {
bail!("Bindings are dirty. Please run `demo/Blackholio/server-rust/generate.sh`.");
}

run_dlls()?;

run_local_spacetime_script(
"spacetimedb-unity-tests",
r#"spacetime logout && spacetime login --server-issued-login local
cd demo/Blackholio/server-rust
bash ./publish.sh"#,
)?;

cmd!(
"bash",
"-lc",
r#"cd demo/Blackholio/client-unity/Packages
yq e -i '.dependencies["com.clockworklabs.spacetimedbsdk"] = "file:../../../../sdks/csharp"' manifest.json
cat manifest.json"#
)
.run()?;

Ok(())
}

fn main() -> Result<()> {
env_logger::init();

Expand Down Expand Up @@ -715,6 +846,14 @@ fn main() -> Result<()> {
run_docs_build()?;
}

Some(CiCmd::CsharpTests) => {
run_csharp_tests()?;
}

Some(CiCmd::UnityTests) => {
run_unity_tests()?;
}

None => run_all_clap_subcommands(&cli.skip)?,
}

Expand Down
Loading