Commit Graph

40 Commits

Author SHA1 Message Date
joshua-spacetime 41d935bb10 Make keynote bench job reusable (#5433)
# Description of Changes

Makes the keynote benchmark job reusable so that it can be invoked and
run in other CI environments.

# API and ABI breaking changes

N/A

# Expected complexity level and risk

2

# Testing

Refactor. Relies on existing coverage.
2026-06-25 13:52:29 +00:00
joshua-spacetime 5ea558ed1b Drop tps threshold in keynote bench (#5360)
# Description of Changes

Reviewing recent benchmark runs, it appears that #5071 probably
regressed TPS by around 3-5%. I don't want to revert that change because
it has implications for replication, and so for now we'll just live with
the slight regression.

# API and ABI breaking changes

None

# Expected complexity level and risk

0

# Testing

N/A
2026-06-17 03:34:17 +00:00
joshua-spacetime fc47257d85 Use SpacetimeDBGuard for SDK test suite (#5340)
# Description of Changes

Use an isolated server process per SDK test instead of a single process
for all of the tests. In addition to reducing the memory footprint of
each test run, this should also allow for more parallelism among the
individual tests.

# API and ABI breaking changes

None

# Expected complexity level and risk

1.5

# Testing

The SDK test suite should continue to work
2026-06-17 00:16:10 +00:00
clockwork-labs-bot d93b381719 Add CLA gate status wrapper (#5299)
## Summary
- Add a CLA Gate workflow that publishes a repository-owned commit
status.
- Mirror CLA Assistant license/cla status on pull requests and status
events.
- Publish CLA Gate=success on merge_group runs, because entries have
already passed PR checks before entering the queue.

## Required settings change after merge
 - Remove license/cla from required checks.
 - Add CLA Gate as the required CLA check.

This keeps CLA enforcement before merge queue while removing CLA
Assistant from the merge-group critical path.

## Test plan
 - Parsed .github/workflows/cla-gate.yml with Ruby YAML loader.
 - Ran git diff --check.

---------

Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-06-14 22:26:28 +00:00
clockwork-labs-bot 11276aa839 Nest CLA Assistant retry command (#5313)
## Summary
- Move `cargo ci retry-cla-assistant` under `cargo ci cla-assistant
retry`.
- Rename the helper module to `cla_assistant.rs`.
- Update the Retry CLA Assistant workflow and generated `cargo ci` docs.

## Verification
- `cargo fmt --all`
- `cargo check -p ci`
- `cargo ci self-docs --check`
- `git diff --check`

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
2026-06-14 20:08:59 +00:00
clockwork-labs-bot edfab0febd Add CLA Assistant retry workflow (#5234)
## Summary
- Add a small `Retry CLA Assistant` workflow for cases where
`license/cla` is missing or pending after the normal PR checks have gone
green.
- Keep the workflow thin: it checks out trusted default-branch code,
determines the PR number from the GitHub event, and runs `cargo ci
retry-cla-assistant --pr-number <number>`.
- Put the retry gate and CLA Assistant recheck call in the existing Rust
`tools/ci` crate.
- Trigger it from PR updates, any workflow completion, manual dispatch
with a PR number, and a 15-minute scheduled fallback sweep.

## Behavior
The workflow passes explicit PR numbers into the Rust command. For
scheduled runs, it enumerates open `master` PRs in the workflow and
invokes the Rust command for each one.

The `cargo ci retry-cla-assistant --pr-number <number>` command only
calls CLA Assistant's recheck endpoint when the PR is open, non-draft,
targets `master`, the head SHA is at least 10 minutes old, at least one
check run exists, all reported check runs are green, no non-CLA commit
status is non-green, and `license/cla` is missing/pending/failing.

The `workflow_run` trigger is intentionally unfiltered, so adding or
renaming CI workflows does not require changing this workflow.

It calls
`https://cla-assistant.io/check/{owner}/{repo}?pullRequest={number}` and
polls `license/cla` for up to 3 minutes.

## Safety
- The workflow uses `pull_request_target`, but it does not check out or
execute PR code. It checks out the trusted default branch before running
the CI tool.
- It ignores completion of the `Retry CLA Assistant` workflow itself.
- It intentionally does not forge a `license/cla` status.

## Validation
- Parsed the workflow YAML locally with Ruby/Psych.
- Ran `cargo fmt --package ci`.
- Ran `cargo check -p ci`.
- Ran `cargo ci retry-cla-assistant --help` and verified `--pr-number`
is required.
- Tested the first Rust version against live PR #5164 metadata and
caught that a hard-coded required-check list was too strict; replaced
that list with a reported-checks-all-green gate.

Addresses #5215.

---------

Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-06-08 17:15:13 +00:00
Zeke Foppa 746d00265d Port bindings-doctests.sh into CI (#5155)
# Description of Changes

Part of https://github.com/clockworklabs/SpacetimeDB/issues/4970.

Doing this part in a separate PR because it turns out that this test was
failing, so this PR also includes the fixes.

# API and ABI breaking changes

None

# Expected complexity level and risk

1

# Testing

CI passes (but only with the "code" changes).

---------

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-06-03 06:22:13 +00:00
Noa 5291f57d7f Stop conflating EnergyQuanta and FunctionBudget (#4930)
# Description of Changes

A sort of followup to/unrevert of #4884, an alternative to #4927.

In #3832, we made FunctionBudget a different unit than EnergyQuanta, but
there were still many places where we treated them the same and directly
converted between them. I got confused by that in #4884, and now this PR
properly separates them and corrects the v8 energy calculation.

Also, since we now benchmark the same module in rust and typescript in
the form of the keynote benchmark, this patch adds a new assertion to
that test that the fuel usage of both modules is within 2X of each
other.

# Expected complexity level and risk

3 - touches energy calculation without reverting the problematic #4884,
but I'm confident it's correct this time.

# Testing

- [x] Verified that the conversion factors make sense for wasmtime and
for v8.
- [x] Assert that typescript and rust keynote bench runs have similar
cpu usage

---------

Co-authored-by: joshua-spacetime <josh@clockworklabs.io>
2026-06-02 23:05:47 +00:00
Zeke Foppa ef293f7c84 CI - ci self-docs includes value names (#5152)
# Description of Changes

the `README.md` (generated by `cargo ci self-docs`) now properly
includes the value names passed to args.

This change was made by AI.

# API and ABI breaking changes

None. CI only.

# Expected complexity level and risk

1

# Testing
CI, including the docs check, passes

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-06-02 13:55:55 +00:00
joshua-spacetime 0922704154 Drop tps threshold for rust keynote-2 ci check (#5159)
# Description of Changes

The keynote benchmark check has had a couple spurious failures in CI
recently, namely for the rust module. I set a higher TPS threshold for
rust than I did for typescript since rust is a bit faster, but it looks
like the threshold I set is within the margin of error, so this change
drops it to 275K - exactly what it is for typescript.

A failure now almost certainly represents a real performance regression
and requires deeper investigation.

# API and ABI breaking changes

N/A

# Expected complexity level and risk

0 (one liner)

# Testing

Should have no more spurious failures for this CI job.
2026-06-01 19:41:46 +00:00
Phoebe Goldman 5c04860649 Implement HTTP handlers / webhooks in Rust modules (#4636)
# Description of Changes

Adds support to Rust modules and the SpacetimeDB host for defining HTTP
handlers and registering them to routes.

## User-facing API

In a Rust module, users can annotate functions with the new macro
`#[spacetimedb::http::handler]`. A function annotated this way must
accept exactly two arguments, of types `&mut
spacetimedb::http::HandlerContext` and `spacetimedb::http::Request`
(which is a type alias for `http::Request<spacetimedb::http::Body>`. It
must also return `spacetimedb::http::Response` (which is a type alias
for `http::Response<spacetimedb::http::Body>`).

Once the user has defined an HTTP handler, they can register it to a
route by annotating a function with `#[spacetimedb::http::router]`. Such
a function must take no arguments and return a
`spacetimedb::http::Router`. (The original design put this annotation on
a `static` variable rather than a function, but that turned out to be
undesirable because it required that constructing a `Router` be
`const`.) `Router` exposes various methods for registering handlers to
routes.

All of a database's user-defined routes are exposed under
`/v1/database/:name_or_identity/route/{*path}`.

## Example

See [the new
smoketest](https://github.com/clockworklabs/SpacetimeDB/blob/phoebe/http-handlers-webhooks/crates/smoketests/tests/smoketests/http_routes.rs)
for a more exhaustive example.

A simpler example, which stores arbitrary byte data in a table via a
`POST` request, returns an ID, and then retrieves that same data via a
`GET` request with a query parameter:

```rust
#[spacetimedb::table(accessor = data)]
struct Data {
    #[primary_key]
    #[auto_inc]
    id: u64,
    body: Vec<u8>,
}

#[spacetimedb::http::handler]
fn insert(ctx: &mut HandlerContext, request: Request) -> Response {
    let body: Vec<u8> = request.into_body().into_bytes().into();
    let id = ctx.with_tx(|tx| tx.db.data().insert(Data { id: 0, body: body.clone() }).id);
    Response::new(Body::from_bytes(format!("{id}")))
}

#[spacetimedb::http::handler]
fn retrieve(ctx: &mut HandlerContext, request: Request) -> Response {
    let id = request
        .uri()
        .query()
        .and_then(|query| query.strip_prefix("id="))
        .and_then(|id| u64::from_str(id).ok())
        .unwrap();
    let body = ctx.with_tx(|tx| tx.db.data().id().find(id).map(|data| data.body));
    if let Some(body) = body {
        Response::new(Body::from_bytes(body))
    } else {
        Response::builder().status(404).body(Body::empty()).unwrap()
    }
}

#[spacetimedb::http::router]
fn router() -> Router {
    Router::new().post("/insert", insert).get("/retrieve", retrieve)
}
```

## Design and implementation notes

- As mentioned above, the router is registered via a function, not a
`static` or `const` item. This is because `static` or `const`
initializers must be `const`, and it turns out to be a pain to make all
of the `Router` constructors be `const fn`s.
- The `#[handler]` macro clobbers the original function name with a
`const` variable of type `HttpHandler`. This is unfortunate, but AFAICT
necessary, 'cause we need to pass the string identifier for the handler
to the `Router`, not the function pointer, and Rust allows no (stable
and reliable) way to get a unique string identifier out of a function
item/value, nor to attach data or implement traits for function
items/values. The alternative(s) would involve changing the signature of
the `Router` methods to have uglier and more complex callsites, e.g.
like `.get("/retrieve", retrieve::handler())`, `.get("/retrieve",
handler!(retrieve))` or `.get::<retrieve>("/retrieve")`. I believe that
registering handlers will be much more common than calling their
functions, so I've chosen to make it so that registering them gets the
convenient syntax, even though the inability to call them directly will
be somewhat surprising.
- I haven't wired up energy handling or timing metrics for handler
execution to anywhere. Procedures are still in the same boat.
- HTTP requests to user-defined routes bypass the usual SpacetimeDB auth
middleware, meaning that the host does not validate (or inspect in any
way) `Authorization` headers in requests before invoking the
user-defined handler. This is required to allow arbitrary
user-programmable handling of `Authorization` headers, including those
in formations which SpacetimeDB would reject. As a result of this,
`HandlerContext` doesn't expose a `sender` or `sender_connection_id`.
- HTTP route paths may consist only of a very restrictive set of
characters. I've chosen this set to keep our options open in the future
to add additional syntax to routes, like for registering wildcard
segments and path parameters:
  - ASCII digits.
  - ASCII letters.
  - `-_~/`.
- The internal data structure that represents a `Router` is currently a
`Vec<Route>`, meaning that resolving a request to a route is
`O(num_routes)`. Registering a route checks against each previous route
for uniqueness, meaning that constructing a router is `O(num_routes ^
2)`. There are TODO comments to use a trie, but I think this can wait,
as I expect most databases to register few routes.
- Commit 999a7c317 contains a fix to a mostly-unrelated bug where a few
bindings introduced by the SATS derive macros were unhygienic and not in
a reserved namespace, leading to name conflicts. I discovered this
'cause I tried writing an HTTP handler named `index` to serve the
index/root of a website and it broke.

## Still TODO

- [x] Resolve various TODO comments in the diff.
- [x] Documentation.
- [x] C# bindings support.
- [x] C++ bindings support.
- [x] V8 host support.
- [x] TypeScript bindings support.

# API and ABI breaking changes

New APIs, currently flagged as `unstable`, which will eventually need
stability guarantees. No (intentional) breaking changes, or changes to
existing APIs at all.

# Expected complexity level and risk

3? Changes to our HTTP routing to support the user-defined routes.

# Testing

<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- [x] New smoketest of the behavior!
- [x] I dunno, maybe try hosting a simple webpage and see how it works?
- [x] Build a test app with Stripe integration.
  - @aasoni did this.

---------

Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: Jason Larabie <jason@clockworklabs.io>
2026-05-29 16:06:15 +00:00
joshua-spacetime 4cf01ed964 Add required ci check for keynote-2 benchmark (#5078)
# Description of Changes

Adds a new required ci check for keynote-2 benchmark regressions. The
test runs for 60s and fails if throughput < 300K TPS.

Note, this check will be flaky as long as it's running concurrently with
other CI jobs. It may need a dedicated runner/host machine. Although it
may be sufficient to only schedule one runner/VM to a single host
machine at a time. I'll need to sync with @jdetter to determine the best
way forward here.

UPDATE: We're using a dedicated runner. See the **Testing** section.

# API and ABI breaking changes

N/A

# Expected complexity level and risk

2

Mainly copy-paste from the other CI workflows.

# Testing

This job now uses `spacetimedb-benchmark-runner` which is entirely
dedicated to this one CI job. I've tested this at different times of the
day when the CI runners are under load and not. The performance is
consistent and the test isn't flaky. It has passed every time.
2026-05-28 19:16:45 +00:00
Zeke Foppa c39141de6a Undo .npmrc in templates (#5084)
# Description of Changes

See https://github.com/clockworklabs/SpacetimeDB/issues/5083 for
motivation.

# API and ABI breaking changes

None

# Expected complexity level and risk

2

# Testing

<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- [x] `cargo run -pspcaetimedb-cli -- init --template nodejs-ts` no
longer creates a directory with `.npmrc`

---------

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-05-21 16:21:22 +00:00
Zeke Foppa fead68c308 CI - enforce minimum pnpm package age (#5032)
# Description of Changes

Due to the relatively frequent supply chain attacks on especially npm
packages, we're instituting a minimum package age in the whole repo.

- Globally set a minimum npm package age in CI
- Best-effort set npm package age using `.npmrc` beside any
`package.json`
- Add CI checks that pnpm version and minimum package age values are the
same everywhere

# API and ABI breaking changes

None

# Expected complexity level and risk

2

# Testing

<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- [x] CI passes
- [x] if I remove a `.npmrc` then `cargo ci lint` fails
- [x] if I change a value in `.npmrc` then `cargo ci lint` fails

---------

Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-05-16 12:47:56 -07:00
Zeke Foppa 8df7df3270 cargo ci dlls -> cargo regen csharp dlls (#4972)
# Description of Changes

Just moving this command in preparation to create a lot more `cargo
regen` commands.

- `master`
  - **[This PR] `cargo ci dlls` -> `cargo regen csharp dlls`**
- [#4971 Translate some bash scripts to
Rust](https://github.com/clockworklabs/SpacetimeDB/pull/4971)
- [#4921 CI - `cargo test` runs C# and TypeScript
tests](https://github.com/clockworklabs/SpacetimeDB/pull/4921)
- [#4948 CI - Run unity tests through `cargo
test`](https://github.com/clockworklabs/SpacetimeDB/pull/4948)

# API and ABI breaking changes

None

# Expected complexity level and risk

1

# Testing

- [x] CI still passes

---------

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-05-08 12:48:22 +00:00
Zeke Foppa 0e8973c306 CI - version upgrade check happens in ci.yml (#4950)
# Description of Changes

Merged the `upgrade-version-check.yml` into `ci.yml`, and moved the
business logic under `cargo ci`.

I would also be very open to just removing this test until we choose to
define a better suite of tests for `cargo bump-version`.

# API and ABI breaking changes

None. CI only.

# Expected complexity level and risk

1

# Testing

- [x] Ran it locally. It made a diff

---------

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-05-05 20:05:33 +00:00
Zeke Foppa 604bb3e649 CI - Move simple jobs into cargo ci (#4871)
# Description of Changes

Migrate these checks into `cargo ci`:
- Check that packages are publishable
- Docs test
- TypeScript - Tests

# API and ABI breaking changes

None. CI only.

# Expected complexity level and risk

2

# Testing

- [ ] CI passes

---------

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-04-23 01:13:25 +00:00
Zeke Foppa 0a08879e8a CI - cargo ci update-flow runs on Windows (#4874)
# Description of Changes

Removed some "if we're on windows" checks in the CI so that we're always
running through `cargo ci update-flow`.

# API and ABI breaking changes

None. CI only.

# Expected complexity level and risk

1.

# Testing

- [x] Upgrade flow tests pass

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-04-22 23:51:53 +00:00
Zeke Foppa 2aa27b0dd7 CI - Move the DLL updating code into a function (#4868)
# Description of Changes

Just moving code into functions so it can be reused, no functional
changes.

# API and ABI breaking changes

None. CI only.

# Expected complexity level and risk

1

# Testing

None

---------

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-04-22 19:35:18 +00:00
Zeke Foppa e2a74b5d1a cargo ci self-docs uses doc comments as well as explicit helptext (#4860)
# Description of Changes

Several args for `cargo ci` had empty helptext, because we were only
printing the explicitly-annotated helptext. This PR updates it so that
inline helptext also shows in the README.

# API and ABI breaking changes

None. CI only.

# Expected complexity level and risk

1

# Testing
- [x] Updated README has more helptext

---------

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-04-22 19:04:53 +00:00
Zeke Foppa a7729f7dab CI - Fold typescript lint into cargo ci lint (#4856)
# Description of Changes

Merge the `TypeScript - Lint` CI job into `cargo ci lint`.

Note that this removes the custom caching for the pnpm store, but we're
planning to overhaul our CI cache approach anyway.

# API and ABI breaking changes

None. CI only.

# Expected complexity level and risk

1

# Testing

- [x] Lint step passes on this PR

---------

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-04-22 16:24:00 +00:00
Zeke Foppa ea834acb79 CI - move pnpm build into cargo ci test (#4855)
# Description of Changes

To make `cargo ci test` more properly include the full test logic.

# API and ABI breaking changes

<!-- If this is an API or ABI breaking change, please apply the
corresponding GitHub label. -->

# Expected complexity level and risk

1

# Testing

honestly none

---------

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-04-21 20:23:07 +00:00
Zeke Foppa 1c10afea0b CI - Move the git diff check under cargo ci smoketests (#4854)
# Description of Changes

To make `cargo ci` more properly the full test logic.

# API and ABI breaking changes

<!-- If this is an API or ABI breaking change, please apply the
corresponding GitHub label. -->

# Expected complexity level and risk

1

# Testing

honestly none

---------

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-04-21 20:10:40 +00:00
Zeke Foppa 10a4779b13 wasm support for Rust SDK (#4183)
# Description of Changes

This PR adapts the Rust SDK test suite to work with the wasm version
added in https://github.com/clockworklabs/SpacetimeDB/pull/4089 (which
I've closed in favor of this PR).

Most of the changes revolve around wasm's different async semantics -
everything runs in one thread, so things that relied on background
threads didn't work directly. Several tests would lock up because
something in them blocked synchronously, which blocked any background
work from progressing.

We moved the test-clients contents into a `test_handlers.rs` so that it
could be called from both `main` (for native tests) and `lib` (for wasm
tests). To show what actually changed, use:
```bash
git diff --no-index -- <(git show origin/master:sdks/rust/tests/procedure-client/src/main.rs) sdks/rust/tests/procedure-client/src/test_handlers.rs
```
(or similar for other test-clients)

# API and ABI breaking changes

None, I think/hope.

# Expected complexity level and risk

2

# Testing

- [x] I've augmented the CI to also run the test suite with the `web`
feature

---------

Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: Thales R <thlsrmsdev@gmail.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-03-23 01:27:51 +00:00
Zeke Foppa 6d9cf691f2 CI - rustfmt instead of cargo fmt (#4595)
# Description of Changes

`cargo ci lint` was running `cargo fmt`, but that didn't pick up all
files. As a result, our pre-commit hook (which just runs `rustfmt` on
any changed `.rs` files) would change otherwise-untouched files in merge
commits.

This PR addresses that discrepancy by having `cargo ci lint` run
`rustfmt` on all tracked `.rs` files.

The entire diff is just `rustfmt` changes except for the changes in
`tools/ci/src/main.rs`.

# API and ABI breaking changes

<!-- If this is an API or ABI breaking change, please apply the
corresponding GitHub label. -->

# Expected complexity level and risk

2

# Testing

- [x] `cargo ci lint` fails
- [x] `cargo ci lint` passes after running `rustfmt` on everything
- [x] `cargo fmt --all` doesn't cause any diff after doing the above

---------

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-03-10 05:58:54 +00:00
Noa e3582131fe Migrate to Rust 2024 (#3802)
# Description of Changes

It'd be best to review this commit-by-commit, and using
[difftastic](https://difftastic.wilfred.me.uk) to easily tell when
changes are minor in terms of syntax but a line based diff doesn't show
that.

# Expected complexity level and risk

3 - edition2024 does bring changes to drop order, which could cause
issues with locks, but I looked through [all of the warnings that
weren't fixed
automatically](https://gistcdn.githack.com/coolreader18/80485ae5c5f82de1784229cce2febb26/raw/ba80f3fecda66ceb34f4f7ad73b98ea02d4893a2/warnings.html)
and couldn't find any issues.

# Testing

n/a; internal code change
2026-03-03 11:06:52 +00:00
Zeke Foppa 3a2e2346e7 CI - Fix smoketests running twice (#4281)
# Description of Changes

Smoketests were running twice because `tests/foo.rs` automatically gets
turned into a test binary, but we also had a `mod.rs` that listed each
file, so they were getting tested via that as well.

This was first broken in
https://github.com/clockworklabs/SpacetimeDB/pull/4184.

# API and ABI breaking changes

None.

# Expected complexity level and risk

1

# Testing

- [x] CI passes
- [x] If I run `cargo ci smoketests` locally, I still see the CLI tests
running
- [x] If I run `cargo ci smoketests` locally, I do not see a particular
CLI test name appearing more than once (e.g.
`cli_cannot_publish_breaking_change_without_flag`)
- [x] `cargo ci smoketests check-mod-list` passes
- [x] `cargo ci smoketests check-mod-list` fails if I `touch
crates/smoketests/tests/smoketests/foo.rs`

---------

Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-02-24 19:18:08 +00:00
Zeke Foppa dd3f7666bc Fix template global.json under Windows (#4357)
# Description of Changes

Make the `global.json` files under `templates` into literal copies of
the root one, instead of symlinks. The symlinks were causing template
breakage when the CLI was built under windows.

# API and ABI breaking changes

None

# Expected complexity level and risk

1

# Testing

<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- [x] Changing a template's global.json causes `cargo ci
global-json-policy` to fail
- [x] Making a template's global.json into a symlink also causes `cargo
ci global-json-policy` to fail

---------

Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2026-02-19 23:33:51 +00:00
Noa d0b9254ba7 Fix CI error stemming from cargo update (#4341)
# Description of Changes

Now we only `cargo update` the dependencies of the module, not of
`spacetimedb-cli`.

---------

Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-02-18 20:47:13 +00:00
Piotr Sarnacki 4c962b9170 spacetime.json config implementation (#4199)
# Description of Changes

This PR implements support for the `spacetime.json` configuration file
that can be used to set up common `generate` and `publish` targets. An
example of `spacetime.json` could look like this:

```
{
  "dev_run": "pnpm dev",
  "generate": [
    { "out-dir": "./foobar", "module-path": "region-module", "language": "c-sharp" },
    { "out-dir": "./global", "module-path": "global-module", "language": "c-sharp" },
  ],
  "publish": {
    "database": "bitcraft",
    "module-path": "spacetimedb",
    "server": "local",
    "children": [
      { "database": "region-1", "module-path": "region-module", server: "local" },
      { "database": "region-2", "module-path": "region-module", server: "local" }
    ]
  }
}
```

With this config, running `spacetime generate` without any arguments
would generate bindings for two targets: `region-module` and
`global-module`. `spacetime publish` without any arguments would publish
three modules, starting from the parent: `bitcraft`, `region-1`, and
`region-2`. On top of that, the command `pnpm dev` would be executed
when using `spacetime dev`.

It is also possible to pass additional command line arguments when
calling the `publish` and `generate` commands, but there are certain
limitations. There is a special case when passing either a module path
to generate or a module name to publish. Doing that will filter out
entries in the config file that do not match. For example, running:

```
spacetime generate --project-path global-module
```

would only generate bindings for the second entry in the `generate`
list.

In a similar fashion, running:

```
spacetime publish region-1
```

would only publish the child database with the name `region-1`

Passing other existing arguments is also possible, but not all of the
arguments are available for multiple configs. For example, when running
`spacetime publish --server maincloud`, the publish command would be
applied to all of the modules listed in the config file, but the
`server` value from the command line arguments would take precedence.
Running with arguments like `--bin-path` would, however, would throw an
error as `--bin-path` makes sense only in a context of a specific
module, thus this wouldn't work: `spacetime publish --bin-path
spacetimedb/target/debug/bitcraft.wasm`. I will throw an error unless
there is only one entry to process, thus `spacetime publish --bin-path
spacetimedb/target/debug/bitcraft.wasm bitcraft` would work, as it
filters the publish targets to one entry.

# API and ABI breaking changes

None

# Expected complexity level and risk

3

The config file in itself is not overly complex, but when coupled with
the CLI it is somewhat tricky to get right. There are also some changes
that I had to make to how clap arguments are validated - because the
values can now come from both the config file and the clap config, we
can't use some of the built-in validations like `required`, or at least
I haven't found a clean way to do so.

# Testing

I've added some automated tests, but more tests and manual testing is
coming.

---------

Signed-off-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
Co-authored-by: bradleyshep <148254416+bradleyshep@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: = <cloutiertyler@gmail.com>
Co-authored-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
2026-02-15 23:22:44 +00:00
joshua-spacetime 2d656d49b6 Block procedures from requesting private ip ranges (#4243)
# Description of Changes

Blocks procedures from requesting private ip ranges after dns
resolution.

Adds a new cargo feature to `spacetimedb-standalone` permitting loopback
http requests in test environments only.

# API and ABI breaking changes

None

# Expected complexity level and risk

2. I may have missed a range.

# Testing

- [x] Unit tests for IP address matching
- [x] Smoketests for blocking a private IP address
2026-02-11 05:27:12 +00:00
Zeke Foppa 21cf6afe54 CI - Merge xtask-smoketest into cargo ci smoketests (#4185)
# Description of Changes

Just merging two CI packages into one.

# API and ABI breaking changes

None

# Expected complexity level and risk

1

# Testing

- [x] CI passes
- [x] `cargo ci smoketests prepare` still just builds the binaries

---------

Signed-off-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: = <cloutiertyler@gmail.com>
Co-authored-by: John Detter <4099508+jdetter@users.noreply.github.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
Co-authored-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
Co-authored-by: Tyler Cloutier <cloutiertyler@aol.com>
2026-02-06 00:17:06 +00:00
Tyler Cloutier 9686139dbc Translate smoketests from Python to Rust (#4102)
# Description of Changes

This PR translates all of our Python smoketests into Rust tests which
can be run from `cargo run`

## Motivation

The purpose of this fivefold:

1. All developers on the team are familiar with Rust
2. It simplifies our devops because we can drop Python as a dependency
to run the tests
3. You can now run all tests in the repo through the single `cargo test`
interface
4. Because we use the `SpacetimeDbGuard` and `cargo test`/`cargo
nextest` we can easily parallelize the smoke tests
5. The smoketests can now use machinery imported from SpacetimeDB crates
(e.g. `bsatn` etc.)

IMPORTANT NOTE!

There are several ways to implement the smoke tests in Rust (none are
great):

1. A separate xtask specifically for the smoke tests
- This doesn't solve the problem of the CLI tests which also use the
`guard` crate
    - Idiosyncratic way to run the smoke tests as opposed to cargo test
- Does NOT resolve the cargo within cargo problem because we still have
to build the test modules with cargo
2. A `build.rs` script in `guard` which first builds the executables as
a compile step for compiling guard
- Deadlocks on a cargo lock file conflict (Outer cargo compiles guard →
runs build.rs, inner cargo tries to acquire the build directory lock,
outer cargo holds the directory lock, deadlock)
- If you fix the deadlock by using different target dirs, it still looks
stuck on building guard because it's actually compiling all of
spacetimedb-standalone and spacetimedb-cli.
    - Still technically runs cargo inside of cargo.
3. Add `spacetimedb-cli` and `spacetimedb-standalone` as an artifact
dependency of the guard crate
- Has good and clear output but requires +nightly when running the
smoketests and CLI tests, otherwise won't do the right thing. See
https://github.com/rust-lang/cargo/issues/9096
4. Compile the executables at runtime during the tests themselves where
the first test takes a lock while the executables are building using
cargo within cargo
- Makes the tests look like they're taking a long time when they're just
waiting for the build to complete
- Requires relatively complex locking machinery across
binaries/tests/processes
5. A two step solution where the developer has to build the binaries
before calling the smoke tests
    - Very error prone

None of these are good. `xtask` is not bad, but doesn't enable us to run
other integration tests in other crates (e.g. the CLI)

(3) is the correct solution and has the best user experience, but it
requires nightly and I don't want to introduce that for all of our
tests.

I have chosen to do a combination of (1) and (4). You will now run the
smoketests with `cargo smoketest`. If you run `cargo test --all` (or use
`guard`) without doing `cargo smoketest` it will fall back to (4) which
compiles the executables at runtime. Running `cargo build` is the **only
way** to ensure that the executables are not stale because of the
internal fingerprint checking. Everything else is fragile not robust.

NOTE! There is no way to avoid cargo within cargo and have the smoke
tests be run as cargo tests because the modules under test must be
compiled with cargo.

# API and ABI breaking changes

Note that this is a BREAKING CHANGE to `cargo test --all`. The
smoketests are now part of `cargo test --all` unless you specifically
exclude them.

# Expected complexity level and risk

3, this is partially AI translated. We need to carefully review to
ensure the semantics have not regressed.

# Testing

<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- [ ] <!-- maybe a test you want to do -->
- [ ] <!-- maybe a test you want a reviewer to do, so they can check it
off when they're satisfied. -->

---------

Signed-off-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: John Detter <4099508+jdetter@users.noreply.github.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2026-02-04 21:44:32 +00:00
Ryan 0977098ea1 Fix for cargo ci dlls missing some .meta files (#4178)
# Description of Changes
This patches a regression introduced in
[#4033](https://github.com/clockworklabs/SpacetimeDB/pull/4033) where
cargo ci dlls stopped copying the Unity .meta files that live outside
the package skeleton tree:
1. `overlay_unity_meta_skeleton` now copies any
`sdks/csharp/unity-meta-skeleton~/spacetimedb.<pkg>.meta` file into
`sdks/csharp/packages/` before overlaying nested content.
2. Added support for a `version.meta` template inside each skeleton
package; it’s renamed to match the single restored version directory
(e.g. `1.11.2.meta`).
3. Added the missing `version.meta` templates for both
`spacetimedb.bsatn.runtime` and `spacetimedb.runtime`, based on the
historical GUIDs Unity already knows about.

Together this restores the `spacetimedb.bsatn.runtime.meta` and
`<version>.meta` files that Unity requires to keep those folders visible
when developers run `cargo ci dlls` on a clean checkout.

# API and ABI breaking changes
None. This only affects the CI helper responsible for syncing Unity
metadata.

# Expected complexity level and risk
2 — localized changes to the CI helper and skeleton assets. Primary risk
is forgetting a template or mis-copying a GUID; the code paths
themselves are straightforward.

# Testing
- [X] Ran `cargo check -p ci`
- [X] Ran `cargo ci dlls` on a clean tree, verifying that:
  * `sdks/csharp/packages/spacetimedb.bsatn.runtime.meta` exists
* The restored version directory (e.g.
`sdks/csharp/packages/spacetimedb.bsatn.runtime/1.11.2.meta`) exists
- [X] Locally launched Unity with a SpacetimeDB project and had no
errors/issues.
2026-02-03 01:50:07 +00:00
Zeke Foppa 6772f0c171 Make global.json global again (#4166)
# Description of Changes

We have had several `global.json` files introduced that aren't symlinks
to the root `global.json`.

This PR fixes that drift, and adds a CI check.

# API and ABI breaking changes

None.

# Expected complexity level and risk

2

# Testing

- [x] `cargo ci global-json-policy` succeeds
- [x] `cargo ci global-json-policy` fails if you add a new `global.json`
file somewhere
- [x] Rest of CI passes, confirming that templates are still working
properly

---------

Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-01-30 18:24:26 +00:00
John Detter d8d63e2d29 Reduce Test Suite test concurrency to reduce test flakes (#3979)
# Description of Changes

<!-- Please describe your change, mention any related tickets, and so on
here. -->

This PR started as an experiment to see if restricting the amount of
test job threads would reduce the flakiness in the `Test Suite` CI job.
I have tested several values here (`1`, `2` and `10`) and I believe 2 is
very stable. I'm also very confused with this change because it seems
like somehow the `Test Suite` CI job is now faster than it was before:

Before:

<img width="502" height="57" alt="image"
src="https://github.com/user-attachments/assets/d944041c-8ccc-4382-a8a7-06e7ff5cba12"
/>

After:

<img width="481" height="46" alt="image"
src="https://github.com/user-attachments/assets/49b89143-b201-4a1a-820c-13e5b3feda76"
/>

It's possible that having less test threads means less cpu contention on
the github runners, but I'm not completely sure. It could also somehow
be less lock contention in SpacetimeDB. I have looked at the output of
the `Test Suite` job and it does appear that all tests are running.

# API and ABI breaking changes

<!-- If this is an API or ABI breaking change, please apply the
corresponding GitHub label. -->

None

# Expected complexity level and risk

0 - this only updates our workflow and has no impact on the code.

<!--
How complicated do you think these changes are? Grade on a scale from 1
to 5,
where 1 is a trivial change, and 5 is a deep-reaching and complex
change.

This complexity rating applies not only to the complexity apparent in
the diff,
but also to its interactions with existing and future code.

If you answered more than a 2, explain what is complex about the PR,
and what other components it interacts with in potentially concerning
ways. -->

# Testing

<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- [x] CI is passing and `Test Suite` is less flakey

---------

Signed-off-by: John Detter <4099508+jdetter@users.noreply.github.com>
2026-01-23 10:30:57 +00:00
Ryan 1fd3394972 Add cargo ci dlls command for building C# DLLs and NuGet packages (#4033)
# Description of Changes
* Added a new `cargo ci dlls` subcommand to build/pack the in-repo C#
NuGet packages and the C# SDK.
* `cargo ci dlls` restores `sdks/csharp/SpacetimeDB.ClientSDK.csproj`
using the freshly built local package outputs as to populate
`sdks/csharp/packages/**`.
* Added a Unity `.meta` skeleton under
`sdks/csharp/unity-meta-skeleton~/**` and overlays those `.meta` files
onto the latest restored versioned package directory to keep Unity GUIDs
stable and import settings consistent.
* Unity-specific import fixes are captured in the skeleton overlay
(notably: preventing Unity from importing incompatible TFMs like
`net8.0`, and marking analyzer DLLs with the `RoslynAnalyzer` label so
Unity can recognize them).
# How to use (local)
```bash
# Build/pack + restore local packages into sdks/csharp/packages/**
cargo ci dlls
```
# API and ABI breaking changes
N/A
# Expected complexity level and risk
2 - Local developer tooling + file overlay into restore output; no
runtime/SDK API behavior changes.
# Testing
- [x] `cargo check -p ci`
- [x] Ran `cargo ci dlls` and verified the output under
`sdks/csharp/packages/**` and the various NuGet package locations.
- [x] Tested a Unity project importing the SpacetimeDB SDK after
generating output and confirmed no errors.

---------

Signed-off-by: Ryan <r.ekhoff@clockworklabs.io>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: John Detter <4099508+jdetter@users.noreply.github.com>
2026-01-22 18:26:55 +00:00
Zeke Foppa 70628fb51e cargo ci on windows (#3859)
# Description of Changes

Make `cargo ci` work properly on Windows, in preparation for
https://github.com/clockworklabs/SpacetimeDB/pull/3702.

# API and ABI breaking changes

No. CI-only.

# Expected complexity level and risk

2. Not trivial, but not complicated.

# Testing

- [x] CI output seems to be genuinely running the tests, and it's
passing on Windows
- [x] Make a change to `crates/bindings-csharp` and see that `cargo ci
test` fails
- [x] I can manually run a minimal `cargo ci smoketests` invocation on a
Windows machine

---------

Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: Kasama <robertoaall@gmail.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2025-12-17 17:34:49 +00:00
Zeke Foppa f49945cc6a Fix CLI reference generation (#3403)
# Description of Changes

Add back the instructions for regenerating CLI docs, which were removed
in https://github.com/clockworklabs/SpacetimeDB/pull/3343. I also made a
script for it.

This also fixes the CI checking this file, which was silently broken in
the same PR.

I have **not** verified that this works in Git Bash in Windows.

# API and ABI breaking changes

None

# Expected complexity level and risk

1

# Testing
- [x] CI passes
- [x] CI fails if I change the CLI reference
- [x] CLI reference looks visually reasonable on a local `pnpm dev`

---------

Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
2025-12-16 20:17:51 +00:00
Roberto Pommella Alegro 5ac65739e5 add initial cargo ci (#3409)
# Description of Changes

This changes the ci runs to execute `cargo ci` instead of running
commands directly from the github workflow.

The goal here is to unify the commands under `cargo ci` so that it's
easier and more intuitive to run locally

# API and ABI breaking changes

There are no API/ABI changes.

<!-- If this is an API or ABI breaking change, please apply the
corresponding GitHub label. -->

# Expected complexity level and risk

Complexity: 1

It is not a complex change as it is mostly localized to the ci runs and
is easily reversible if something goes wrong. The biggest risk here is
to have future CI runs break, which can be remediated by reverting these
changes.

<!--
How complicated do you think these changes are? Grade on a scale from 1
to 5,
where 1 is a trivial change, and 5 is a deep-reaching and complex
change.

This complexity rating applies not only to the complexity apparent in
the diff,
but also to its interactions with existing and future code.

If you answered more than a 2, explain what is complex about the PR,
and what other components it interacts with in potentially concerning
ways. -->

# Testing

<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->

- [x] run `cargo ci` and its subcommands locally
- [x] run the github workflow against this branch to check if the CI
jobs are working properly.

---------

Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Signed-off-by: Roberto Pommella Alegro <robertoaall@gmail.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
2025-12-10 19:18:43 +00:00