Skip to content

Commit bd42eca

Browse files
authored
Merge pull request #5 from NodeDB-Lab/lite
Sync collection registration + core API catch-up (lite→Origin round-trip)
2 parents 979b369 + 73c50ea commit bd42eca

417 files changed

Lines changed: 66178 additions & 6490 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.

.config/nextest.toml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55
#
66
# Run with: cargo nextest run -p nodedb-lite
77

8+
experimental = ["setup-scripts"]
9+
10+
[scripts.setup.build-origin]
11+
command = { command-line = "scripts/ensure-origin.sh", relative-to = "workspace-root" }
12+
slow-timeout = { period = "600s", terminate-after = 1 }
13+
capture-stderr = true
14+
815
[profile.default]
916
# Hard ceiling per test. Anything above this is a bug, not a slow test.
1017
slow-timeout = { period = "30s", terminate-after = 4 }
@@ -39,10 +46,18 @@ binary(/concurrency/)
3946
| binary(/e2e/)
4047
| binary(/integration/)
4148
| binary(/compensation/)
49+
| binary(/sync_interop/)
50+
| binary(/sync_load/)
51+
| binary(/sql_parity/)
52+
| binary(/definition_sync_interop/)
4253
'''
4354
test-group = 'heavy'
4455
threads-required = 'num-test-threads'
4556

57+
[[profile.default.scripts]]
58+
filter = 'binary(/sync_interop/) | binary(/sync_load/) | binary(/definition_sync_interop/) | binary(/sql_parity/)'
59+
setup = 'build-origin'
60+
4661
[test-groups]
4762
heavy = { max-threads = 1 }
4863

@@ -52,3 +67,7 @@ fail-fast = false
5267

5368
[profile.ci.junit]
5469
path = "junit.xml"
70+
71+
[[profile.ci.scripts]]
72+
filter = 'binary(/sync_interop/) | binary(/sync_load/) | binary(/definition_sync_interop/) | binary(/sql_parity/)'
73+
setup = 'build-origin'

.github/workflows/ci.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# CI — thin wrapper that calls the reusable test workflow.
2+
3+
name: CI
4+
5+
on:
6+
pull_request:
7+
branches: [main]
8+
types: [opened, synchronize, reopened, ready_for_review]
9+
workflow_dispatch:
10+
workflow_call:
11+
12+
concurrency:
13+
group: ci-${{ github.ref }}
14+
cancel-in-progress: true
15+
16+
permissions:
17+
contents: read
18+
19+
jobs:
20+
test:
21+
if: github.event.pull_request.draft == false
22+
name: Test Suite
23+
uses: ./.github/workflows/test.yml

.github/workflows/release.yml

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
name: Release
2+
run-name: Release ${{ github.ref_name }}
3+
4+
on:
5+
push:
6+
tags:
7+
- "v*"
8+
9+
concurrency:
10+
group: release
11+
cancel-in-progress: false
12+
13+
permissions:
14+
contents: read
15+
16+
env:
17+
CARGO_TERM_COLOR: always
18+
19+
jobs:
20+
# ── Validate tag ─────────────────────────────────────────────────────────────
21+
validate-version:
22+
name: Validate Version Tag
23+
runs-on: ubuntu-latest
24+
outputs:
25+
version: ${{ steps.version.outputs.version }}
26+
is_full_release: ${{ steps.version.outputs.is_full_release }}
27+
steps:
28+
- uses: actions/checkout@v6
29+
30+
- name: Install Rust
31+
uses: dtolnay/rust-toolchain@stable
32+
33+
- name: Validate tag against Cargo.toml
34+
id: version
35+
run: |
36+
TAG="${GITHUB_REF_NAME}"
37+
TAG_VERSION="${TAG#v}"
38+
39+
CARGO_VERSION=$(cargo metadata --no-deps --format-version=1 \
40+
| jq -r '.packages[] | select(.name == "nodedb-lite") | .version')
41+
CARGO_BASE=$(echo "$CARGO_VERSION" | grep -oP '^\d+\.\d+\.\d+')
42+
43+
echo "Tag version: $TAG_VERSION"
44+
echo "Cargo.toml version: $CARGO_VERSION"
45+
echo "Cargo.toml base: $CARGO_BASE"
46+
47+
if [[ ! "$TAG_VERSION" =~ ^([0-9]+\.[0-9]+\.[0-9]+)(-[a-zA-Z]+\.[0-9]+)?$ ]]; then
48+
echo "::error::Invalid tag format '$TAG'. Expected: vX.Y.Z or vX.Y.Z-label.N"
49+
exit 1
50+
fi
51+
52+
TAG_BASE="${BASH_REMATCH[1]}"
53+
54+
if [[ "$TAG_BASE" != "$CARGO_BASE" ]]; then
55+
echo "::error::Base version mismatch! Tag '$TAG_BASE' != Cargo.toml '$CARGO_BASE'"
56+
exit 1
57+
fi
58+
59+
# Full release = no hyphen suffix (v0.1.0, not v0.1.0-beta.1)
60+
if [[ "$TAG_VERSION" == *-* ]]; then
61+
echo "is_full_release=false" >> "$GITHUB_OUTPUT"
62+
else
63+
echo "is_full_release=true" >> "$GITHUB_OUTPUT"
64+
fi
65+
66+
echo "version=$TAG_VERSION" >> "$GITHUB_OUTPUT"
67+
68+
# ── CI gate ──────────────────────────────────────────────────────────────────
69+
ci:
70+
name: CI Gate
71+
needs: validate-version
72+
uses: ./.github/workflows/ci.yml
73+
74+
# ── WASM gate ────────────────────────────────────────────────────────────────
75+
wasm:
76+
name: WASM Gate
77+
needs: validate-version
78+
uses: ./.github/workflows/wasm.yml
79+
80+
# ── Publish crates to crates.io ──────────────────────────────────────────────
81+
# Requires secret: CARGO_REGISTRY_TOKEN
82+
# Tier 1: nodedb-lite (no internal Lite deps).
83+
# Tier 2: nodedb-lite-ffi, nodedb-lite-wasm (both depend on nodedb-lite).
84+
# is_published / wait_for polling mirrors the nodedb workspace pattern so
85+
# a re-run after a failed publish never double-publishes an already-indexed
86+
# crate.
87+
publish-crates:
88+
name: Publish to crates.io
89+
needs: [validate-version, ci, wasm]
90+
runs-on: ubuntu-latest
91+
environment: crates.io
92+
permissions:
93+
contents: read
94+
steps:
95+
- uses: actions/checkout@v6
96+
97+
- name: Install Rust
98+
uses: dtolnay/rust-toolchain@stable
99+
100+
- name: Install system deps
101+
run: |
102+
sudo apt-get update
103+
sudo apt-get install -y --no-install-recommends \
104+
cmake clang libclang-dev pkg-config protobuf-compiler perl
105+
106+
- name: Set version from tag
107+
run: |
108+
VERSION="${{ needs.validate-version.outputs.version }}"
109+
CURRENT=$(cargo metadata --no-deps --format-version=1 \
110+
| jq -r '.packages[] | select(.name == "nodedb-lite") | .version')
111+
if [[ "$VERSION" != "$CURRENT" ]]; then
112+
sed -i "0,/^version = \".*\"/s//version = \"$VERSION\"/" Cargo.toml
113+
114+
# For pre-release versions, pin internal dep requirements so
115+
# semver "0.1.0" doesn't fail to match "0.1.0-beta.1".
116+
if [[ "$VERSION" == *-* ]]; then
117+
sed -i -E 's/(nodedb-lite = \{ [^}]*version = )"[^"]*"/\1"='"$VERSION"'"/' Cargo.toml
118+
echo "Updated internal dep versions to =$VERSION"
119+
fi
120+
121+
echo "Updated workspace version: $CURRENT -> $VERSION"
122+
else
123+
echo "Version already matches, no change needed"
124+
fi
125+
126+
- name: Publish crates
127+
env:
128+
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
129+
run: |
130+
TIER1="nodedb-lite"
131+
TIER2="nodedb-lite-ffi nodedb-lite-wasm"
132+
133+
is_published() {
134+
curl -sf \
135+
-H "User-Agent: nodedb-lite-ci (github.com/NodeDB-Lab/nodedb-lite)" \
136+
"https://crates.io/api/v1/crates/$1/$2" > /dev/null 2>&1
137+
}
138+
139+
wait_for() {
140+
local crate="$1" version="$2"
141+
echo -n " Waiting for $crate@$version..."
142+
for i in $(seq 1 30); do
143+
if is_published "$crate" "$version"; then
144+
echo " ready"
145+
return 0
146+
fi
147+
sleep 5
148+
done
149+
echo " timed out!"
150+
return 1
151+
}
152+
153+
publish_tier() {
154+
local tier_name="$1"; shift
155+
local crates=("$@")
156+
local need_wait=()
157+
158+
echo "::group::Tier: $tier_name"
159+
for crate in "${crates[@]}"; do
160+
VERSION=$(cargo metadata --no-deps --format-version=1 \
161+
| jq -r --arg name "$crate" '.packages[] | select(.name == $name) | .version')
162+
if is_published "$crate" "$VERSION"; then
163+
echo " $crate@$VERSION already published — skipping"
164+
else
165+
echo " Publishing $crate@$VERSION..."
166+
cargo publish -p "$crate" --allow-dirty --no-verify
167+
need_wait+=("$crate:$VERSION")
168+
fi
169+
done
170+
171+
for entry in "${need_wait[@]}"; do
172+
wait_for "${entry%%:*}" "${entry##*:}"
173+
done
174+
echo "::endgroup::"
175+
}
176+
177+
publish_tier "1 (no internal Lite deps)" $TIER1
178+
publish_tier "2 (depends on nodedb-lite)" $TIER2
179+
180+
# ── Publish npm package ──────────────────────────────────────────────────────
181+
# Requires secret: NPM_TOKEN
182+
publish-npm:
183+
name: Publish to npm
184+
needs: [validate-version, ci, wasm, publish-crates]
185+
runs-on: ubuntu-latest
186+
environment: npm
187+
permissions:
188+
contents: read
189+
steps:
190+
- uses: actions/checkout@v6
191+
192+
- name: Install Rust
193+
uses: dtolnay/rust-toolchain@stable
194+
with:
195+
targets: wasm32-unknown-unknown
196+
197+
- name: Install wasm-pack
198+
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
199+
200+
- uses: actions/setup-node@v4
201+
with:
202+
node-version: 20
203+
registry-url: https://registry.npmjs.org
204+
205+
- name: Build WASM release
206+
run: wasm-pack build --target web --release nodedb-lite-wasm
207+
208+
- name: Rewrite pkg/package.json metadata
209+
working-directory: nodedb-lite-wasm/pkg
210+
run: |
211+
node -e "
212+
const fs = require('fs');
213+
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
214+
pkg.name = '@nodedb/lite';
215+
pkg.version = '${{ needs.validate-version.outputs.version }}';
216+
pkg.license = 'Apache-2.0';
217+
pkg.repository = { type: 'git', url: 'https://github.com/NodeDB-Lab/nodedb-lite' };
218+
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
219+
"
220+
221+
- name: Publish to npm
222+
working-directory: nodedb-lite-wasm/pkg
223+
env:
224+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
225+
run: |
226+
if [[ "${{ needs.validate-version.outputs.is_full_release }}" == "true" ]]; then
227+
npm publish --access public
228+
else
229+
npm publish --access public --tag beta
230+
fi
231+
232+
# ── Create GitHub Release ─────────────────────────────────────────────────────
233+
github-release:
234+
name: Create GitHub Release
235+
needs: [validate-version, publish-crates, publish-npm]
236+
runs-on: ubuntu-latest
237+
permissions:
238+
contents: write
239+
steps:
240+
- uses: actions/checkout@v6
241+
242+
- name: Create GitHub Release
243+
uses: softprops/action-gh-release@v2
244+
with:
245+
tag_name: v${{ needs.validate-version.outputs.version }}
246+
name: NodeDB Lite ${{ needs.validate-version.outputs.version }}
247+
generate_release_notes: true
248+
draft: false
249+
prerelease: ${{ contains(needs.validate-version.outputs.version, '-') }}

.github/workflows/test.yml

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Reusable test workflow: fmt, clippy, native test suite, and wasm32 check.
2+
#
3+
# Called by:
4+
# - ci.yml (PR checks)
5+
# - release.yml (pre-publish gate)
6+
#
7+
# Lite is a separate workspace from Origin. It consumes the nodedb-* shared
8+
# crates from crates.io. Local development uses `.cargo/config.toml`
9+
# [patch.crates-io] to resolve to a sibling Origin checkout; CI uses the
10+
# published versions.
11+
12+
name: Test
13+
14+
on:
15+
workflow_call:
16+
17+
permissions:
18+
contents: read
19+
20+
env:
21+
CARGO_TERM_COLOR: always
22+
23+
jobs:
24+
lint:
25+
name: Lint & Check
26+
runs-on: ubuntu-latest
27+
steps:
28+
- uses: actions/checkout@v6
29+
- name: Install Rust
30+
uses: dtolnay/rust-toolchain@stable
31+
with:
32+
components: rustfmt, clippy
33+
targets: wasm32-unknown-unknown
34+
- uses: Swatinem/rust-cache@v2
35+
with:
36+
shared-key: lite-workspace
37+
- name: Install system deps
38+
run: |
39+
sudo apt-get update
40+
sudo apt-get install -y --no-install-recommends \
41+
cmake clang libclang-dev pkg-config protobuf-compiler perl
42+
- name: Check formatting
43+
run: cargo fmt --all -- --check
44+
- name: Run clippy
45+
run: cargo clippy --workspace --all-targets --profile ci -- -D warnings
46+
- name: Check wasm32 target
47+
run: cargo check -p nodedb-lite-wasm --target wasm32-unknown-unknown
48+
49+
test:
50+
name: Test
51+
runs-on: ubuntu-latest
52+
steps:
53+
- uses: actions/checkout@v6
54+
- name: Install Rust
55+
uses: dtolnay/rust-toolchain@stable
56+
- uses: Swatinem/rust-cache@v2
57+
with:
58+
shared-key: lite-workspace
59+
- name: Install system deps
60+
run: |
61+
sudo apt-get update
62+
sudo apt-get install -y --no-install-recommends \
63+
cmake clang libclang-dev pkg-config protobuf-compiler perl
64+
- name: Install cargo-nextest
65+
uses: taiki-e/install-action@v2
66+
with:
67+
tool: nextest
68+
- name: Run tests
69+
run: |
70+
cargo nextest run \
71+
--workspace \
72+
--cargo-profile ci --profile ci \
73+
--no-fail-fast
74+
- name: Upload JUnit report
75+
if: always()
76+
uses: actions/upload-artifact@v4
77+
with:
78+
name: junit-report
79+
path: target/nextest/ci/junit.xml
80+
if-no-files-found: ignore

0 commit comments

Comments
 (0)