Skip to content

Commit 94dfc31

Browse files
Merge branch 'master' into jlarabie/agent-chat
2 parents af20d0a + d31301a commit 94dfc31

145 files changed

Lines changed: 9752 additions & 881 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 0 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -878,151 +878,6 @@ jobs:
878878
exit 1
879879
}
880880
881-
internal-tests:
882-
name: Internal Tests
883-
needs: [lints]
884-
# Skip if not a PR or a push to master
885-
# Skip if this is an external contribution. GitHub secrets will be empty, so the step would fail anyway.
886-
if: ${{ (github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref == 'refs/heads/master'))
887-
&& (github.event_name != 'pull_request' || !github.event.pull_request.head.repo.fork) }}
888-
permissions:
889-
contents: read
890-
pull-requests: read
891-
runs-on: ubuntu-latest
892-
env:
893-
TARGET_OWNER: clockworklabs
894-
TARGET_REPO: SpacetimeDBPrivate
895-
steps:
896-
# Skip the private dispatch entirely when only `docs/` is touched. The job
897-
# itself still completes successfully so required-status-check gating is
898-
# satisfied without spending private-runner time on a docs-only change.
899-
- name: Detect non-docs changes
900-
id: filter
901-
uses: dorny/paths-filter@v3
902-
with:
903-
filters: |
904-
non_docs:
905-
- '!docs/**'
906-
907-
- id: dispatch
908-
name: Trigger tests
909-
if: steps.filter.outputs.non_docs == 'true'
910-
uses: actions/github-script@v7
911-
with:
912-
github-token: ${{ secrets.SPACETIMEDB_PRIVATE_TOKEN }}
913-
script: |
914-
const workflowId = 'ci.yml';
915-
const targetRef = 'master';
916-
const targetOwner = process.env.TARGET_OWNER;
917-
const targetRepo = process.env.TARGET_REPO;
918-
// Use the ref for pull requests because the head sha is brittle (github does some extra dance where it merges in master).
919-
const publicRef = (context.eventName === 'pull_request') ? context.payload.pull_request.head.ref : context.sha;
920-
const publicPrNumber = context.payload.pull_request?.number ?? context.payload.inputs?.pr_number;
921-
const preDispatch = new Date().toISOString();
922-
const inputs = { public_ref: publicRef };
923-
if (publicPrNumber) {
924-
inputs.public_pr_number = String(publicPrNumber);
925-
}
926-
927-
// Dispatch the workflow in the target repository
928-
await github.rest.actions.createWorkflowDispatch({
929-
owner: targetOwner,
930-
repo: targetRepo,
931-
workflow_id: workflowId,
932-
ref: targetRef,
933-
inputs,
934-
});
935-
936-
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
937-
938-
// Find the dispatched run by name
939-
let runId = null;
940-
for (let attempt = 0; attempt < 20 && !runId; attempt++) { // up to ~10 minutes to locate the run
941-
await sleep(5000);
942-
const runsResp = await github.rest.actions.listWorkflowRuns({
943-
owner: targetOwner,
944-
repo: targetRepo,
945-
workflow_id: workflowId,
946-
event: 'workflow_dispatch',
947-
branch: targetRef,
948-
per_page: 50,
949-
});
950-
951-
const expectedName = `CI [public_ref=${publicRef}]`;
952-
const candidates = runsResp.data.workflow_runs
953-
.filter(r => r.name === expectedName && new Date(r.created_at) >= new Date(preDispatch))
954-
.sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
955-
956-
if (candidates.length > 0) {
957-
runId = candidates[0].id;
958-
break;
959-
}
960-
}
961-
962-
if (!runId) {
963-
core.setFailed('Failed to locate dispatched run in the private repository.');
964-
return;
965-
}
966-
967-
const runUrl = `https://github.com/${targetOwner}/${targetRepo}/actions/runs/${runId}`;
968-
core.info(`View run: ${runUrl}`);
969-
core.setOutput('run_id', String(runId));
970-
core.setOutput('run_url', runUrl);
971-
972-
- name: Wait for Internal Tests to complete
973-
if: steps.filter.outputs.non_docs == 'true'
974-
uses: actions/github-script@v7
975-
with:
976-
github-token: ${{ secrets.SPACETIMEDB_PRIVATE_TOKEN }}
977-
script: |
978-
const targetOwner = process.env.TARGET_OWNER;
979-
const targetRepo = process.env.TARGET_REPO;
980-
const runId = Number(`${{ steps.dispatch.outputs.run_id }}`);
981-
const runUrl = `${{ steps.dispatch.outputs.run_url }}`;
982-
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
983-
984-
core.info(`Waiting for workflow result... ${runUrl}`);
985-
986-
let conclusion = null;
987-
for (let attempt = 0; attempt < 240; attempt++) { // up to ~2 hours
988-
const runResp = await github.rest.actions.getWorkflowRun({
989-
owner: targetOwner,
990-
repo: targetRepo,
991-
run_id: runId
992-
});
993-
const { status, conclusion: c } = runResp.data;
994-
if (status === 'completed') {
995-
conclusion = c || 'success';
996-
break;
997-
}
998-
await sleep(30000);
999-
}
1000-
1001-
if (!conclusion) {
1002-
core.setFailed('Timed out waiting for private workflow to complete.');
1003-
return;
1004-
}
1005-
1006-
if (conclusion !== 'success') {
1007-
core.setFailed(`Private workflow failed with conclusion: ${conclusion}`);
1008-
}
1009-
1010-
- name: Cancel invoked run if workflow cancelled
1011-
if: ${{ cancelled() && steps.dispatch.outputs.run_id }}
1012-
uses: actions/github-script@v7
1013-
with:
1014-
github-token: ${{ secrets.SPACETIMEDB_PRIVATE_TOKEN }}
1015-
script: |
1016-
const targetOwner = process.env.TARGET_OWNER;
1017-
const targetRepo = process.env.TARGET_REPO;
1018-
const runId = Number(`${{ steps.dispatch.outputs.run_id }}`);
1019-
if (!runId) return;
1020-
await github.rest.actions.cancelWorkflowRun({
1021-
owner: targetOwner,
1022-
repo: targetRepo,
1023-
run_id: runId,
1024-
});
1025-
1026881
global_json_policy:
1027882
name: Verify global.json files are symlinks
1028883
runs-on: ubuntu-latest
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
name: Internal Tests
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- master
8+
merge_group:
9+
workflow_dispatch:
10+
11+
run-name: Internal Tests [ref=${{ github.ref }}]
12+
13+
concurrency:
14+
group: ${{ github.workflow }}-${{ github.ref }}
15+
cancel-in-progress: true
16+
17+
permissions:
18+
contents: read
19+
pull-requests: read
20+
21+
jobs:
22+
internal-tests:
23+
name: Internal Tests
24+
# Skip if not a PR or a push to master
25+
# Skip if this is an external contribution. GitHub secrets will be empty, so the step would fail anyway.
26+
if: ${{ (github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref == 'refs/heads/master'))
27+
&& (github.event_name != 'pull_request' || !github.event.pull_request.head.repo.fork) }}
28+
runs-on: ubuntu-latest
29+
env:
30+
TARGET_OWNER: clockworklabs
31+
TARGET_REPO: SpacetimeDBPrivate
32+
steps:
33+
# Skip the private dispatch entirely when only `docs/` is touched. The job
34+
# itself still completes successfully so required-status-check gating is
35+
# satisfied without spending private-runner time on a docs-only change.
36+
- name: Detect non-docs changes
37+
id: filter
38+
uses: dorny/paths-filter@v3
39+
with:
40+
filters: |
41+
non_docs:
42+
- '!docs/**'
43+
44+
- id: dispatch
45+
name: Trigger tests
46+
if: steps.filter.outputs.non_docs == 'true'
47+
uses: actions/github-script@v7
48+
with:
49+
github-token: ${{ secrets.SPACETIMEDB_PRIVATE_TOKEN }}
50+
script: |
51+
const workflowId = 'ci.yml';
52+
const targetRef = 'master';
53+
const targetOwner = process.env.TARGET_OWNER;
54+
const targetRepo = process.env.TARGET_REPO;
55+
// Use the ref for pull requests because the head sha is brittle (github does some extra dance where it merges in master).
56+
const publicRef = (context.eventName === 'pull_request') ? context.payload.pull_request.head.ref : context.sha;
57+
const publicPrNumber = context.payload.pull_request?.number;
58+
const preDispatch = new Date().toISOString();
59+
const inputs = { public_ref: publicRef };
60+
if (publicPrNumber) {
61+
inputs.public_pr_number = String(publicPrNumber);
62+
}
63+
64+
// Dispatch the workflow in the target repository
65+
await github.rest.actions.createWorkflowDispatch({
66+
owner: targetOwner,
67+
repo: targetRepo,
68+
workflow_id: workflowId,
69+
ref: targetRef,
70+
inputs,
71+
});
72+
73+
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
74+
75+
// Find the dispatched run by name
76+
let runId = null;
77+
for (let attempt = 0; attempt < 20 && !runId; attempt++) { // up to ~10 minutes to locate the run
78+
await sleep(5000);
79+
const runsResp = await github.rest.actions.listWorkflowRuns({
80+
owner: targetOwner,
81+
repo: targetRepo,
82+
workflow_id: workflowId,
83+
event: 'workflow_dispatch',
84+
branch: targetRef,
85+
per_page: 50,
86+
});
87+
88+
const expectedName = `CI [public_ref=${publicRef}]`;
89+
const candidates = runsResp.data.workflow_runs
90+
.filter(r => r.name === expectedName && new Date(r.created_at) >= new Date(preDispatch))
91+
.sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
92+
93+
if (candidates.length > 0) {
94+
runId = candidates[0].id;
95+
break;
96+
}
97+
}
98+
99+
if (!runId) {
100+
core.setFailed('Failed to locate dispatched run in the private repository.');
101+
return;
102+
}
103+
104+
const runUrl = `https://github.com/${targetOwner}/${targetRepo}/actions/runs/${runId}`;
105+
core.info(`View run: ${runUrl}`);
106+
core.setOutput('run_id', String(runId));
107+
core.setOutput('run_url', runUrl);
108+
109+
- name: Wait for Internal Tests to complete
110+
if: steps.filter.outputs.non_docs == 'true'
111+
uses: actions/github-script@v7
112+
with:
113+
github-token: ${{ secrets.SPACETIMEDB_PRIVATE_TOKEN }}
114+
script: |
115+
const targetOwner = process.env.TARGET_OWNER;
116+
const targetRepo = process.env.TARGET_REPO;
117+
const runId = Number(`${{ steps.dispatch.outputs.run_id }}`);
118+
const runUrl = `${{ steps.dispatch.outputs.run_url }}`;
119+
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
120+
121+
core.info(`Waiting for workflow result... ${runUrl}`);
122+
123+
let conclusion = null;
124+
for (let attempt = 0; attempt < 240; attempt++) { // up to ~2 hours
125+
const runResp = await github.rest.actions.getWorkflowRun({
126+
owner: targetOwner,
127+
repo: targetRepo,
128+
run_id: runId
129+
});
130+
const { status, conclusion: c } = runResp.data;
131+
if (status === 'completed') {
132+
conclusion = c || 'success';
133+
break;
134+
}
135+
await sleep(30000);
136+
}
137+
138+
if (!conclusion) {
139+
core.setFailed('Timed out waiting for private workflow to complete.');
140+
return;
141+
}
142+
143+
if (conclusion !== 'success') {
144+
core.setFailed(`Private workflow failed with conclusion: ${conclusion}`);
145+
}
146+
147+
- name: Cancel invoked run if workflow cancelled
148+
if: ${{ cancelled() && steps.dispatch.outputs.run_id }}
149+
uses: actions/github-script@v7
150+
with:
151+
github-token: ${{ secrets.SPACETIMEDB_PRIVATE_TOKEN }}
152+
script: |
153+
const targetOwner = process.env.TARGET_OWNER;
154+
const targetRepo = process.env.TARGET_REPO;
155+
const runId = Number(`${{ steps.dispatch.outputs.run_id }}`);
156+
if (!runId) return;
157+
await github.rest.actions.cancelWorkflowRun({
158+
owner: targetOwner,
159+
repo: targetRepo,
160+
run_id: runId,
161+
});

Cargo.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/bindings-cpp/CMakeLists.txt

Lines changed: 3 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ target_sources(spacetimedb_cpp_library PRIVATE ${LIBRARY_SOURCES})
3030

3131
# Require C++20 for consumers of this library without forcing global flags
3232
target_compile_features(spacetimedb_cpp_library PUBLIC cxx_std_20)
33+
target_compile_definitions(spacetimedb_cpp_library PRIVATE SPACETIMEDB_UNSTABLE_FEATURES)
3334

3435
# Set include directories
3536
target_include_directories(spacetimedb_cpp_library
@@ -60,46 +61,5 @@ if(PROJECT_IS_TOP_LEVEL)
6061
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
6162
endif()
6263

63-
# ---- Tests ----
64-
# Default: ON only when building this project directly; OFF when used via FetchContent/add_subdirectory
65-
if(CMAKE_VERSION VERSION_LESS 3.21)
66-
# Fallback heuristic for older CMake
67-
set(_is_top_level FALSE)
68-
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
69-
set(_is_top_level TRUE)
70-
endif()
71-
else()
72-
set(_is_top_level ${PROJECT_IS_TOP_LEVEL})
73-
endif()
74-
75-
option(BUILD_TESTS "Build the test suite" ${_is_top_level})
76-
77-
if(BUILD_TESTS AND NOT CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
78-
enable_testing()
79-
80-
# Add test executable
81-
add_executable(test_bsatn tests/main.cpp tests/module_library_unit_tests.cpp)
82-
83-
# Link against the module library
84-
target_link_libraries(test_bsatn PRIVATE spacetimedb_cpp_library)
85-
86-
# Set C++20 standard for tests
87-
target_compile_features(test_bsatn PRIVATE cxx_std_20)
88-
89-
# Add test to CTest
90-
add_test(NAME bsatn_tests COMMAND test_bsatn)
91-
92-
# Add verbose test variant
93-
add_test(NAME bsatn_tests_verbose COMMAND test_bsatn -v)
94-
95-
# Set test properties
96-
set_tests_properties(bsatn_tests PROPERTIES
97-
TIMEOUT 30
98-
LABELS "unit"
99-
)
100-
101-
set_tests_properties(bsatn_tests_verbose PROPERTIES
102-
TIMEOUT 30
103-
LABELS "unit;verbose"
104-
)
105-
endif()
64+
# Unit/compile/smoke test harnesses live under `tests/` as standalone runners
65+
# rather than being built through the top-level library CMake target.

0 commit comments

Comments
 (0)