chore(wasm): check, clippy, test, CI
This commit is contained in:
@@ -23,6 +23,7 @@ jobs:
|
||||
outputs:
|
||||
frontend: ${{ steps.filter.outputs.frontend }}
|
||||
backend: ${{ steps.filter.outputs.backend }}
|
||||
wasm: ${{ steps.filter.outputs.wasm }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dorny/paths-filter@v3
|
||||
@@ -44,6 +45,9 @@ jobs:
|
||||
- 'Cargo.toml'
|
||||
- 'Cargo.lock'
|
||||
- 'tests/**'
|
||||
wasm:
|
||||
- 'wasm/**'
|
||||
- 'scripts/build-wasm.sh'
|
||||
|
||||
frontend-check:
|
||||
name: Frontend — CSS and JS checks (format, lint, css-rules, types)
|
||||
@@ -122,6 +126,51 @@ jobs:
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- run: cargo clippy --all-targets --all-features -- -D warnings
|
||||
|
||||
# Mirrors the `wasm-check` justfile recipe. The wasm crate is a
|
||||
# standalone workspace under `wasm/oxicloud-hash/` and is NOT
|
||||
# built by the server's `cargo build` — these checks have to run
|
||||
# explicitly from inside the sub-workspace. clippy + tests run
|
||||
# against the HOST target (no wasm32 target needed in CI) which
|
||||
# is enough to cover the algorithmic logic; the wasm32 build is
|
||||
# exercised by `scripts/build-wasm.sh` and the frontend tests.
|
||||
wasm-check:
|
||||
name: Wasm — fmt + clippy
|
||||
needs: changes
|
||||
if: needs.changes.outputs.wasm == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: wasm/oxicloud-hash
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
components: rustfmt, clippy
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: wasm/oxicloud-hash
|
||||
- run: cargo fmt --all --check
|
||||
- run: cargo clippy --all-features --release -- -D warnings
|
||||
|
||||
# Mirrors the `wasm-test` justfile recipe. Tests run in release
|
||||
# mode because the FastCDC + BLAKE3 workload takes minutes in
|
||||
# the default debug profile (no inlining / no SIMD).
|
||||
wasm-test:
|
||||
name: Wasm — release tests
|
||||
needs: changes
|
||||
if: needs.changes.outputs.wasm == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: wasm/oxicloud-hash
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: wasm/oxicloud-hash
|
||||
- run: cargo test --release
|
||||
|
||||
rust-test:
|
||||
name: Server Unit and Functionnal Tests
|
||||
needs: changes
|
||||
|
||||
@@ -69,6 +69,13 @@ frontend-check:
|
||||
node scripts/check-dead-tokens.mjs
|
||||
node scripts/check-brand-drift.mjs
|
||||
|
||||
wasm-check:
|
||||
cd wasm/oxicloud-hash; cargo fmt --all
|
||||
cd wasm/oxicloud-hash; cargo clippy --all-features --release -- -D warnings
|
||||
|
||||
wasm-test:
|
||||
cd wasm/oxicloud-hash; cargo test --release
|
||||
|
||||
# audit security (condition: cargo install cargo-audit)
|
||||
audit:
|
||||
cargo audit
|
||||
|
||||
@@ -20,6 +20,19 @@ cd "$(dirname "$0")/.."
|
||||
CRATE=wasm/oxicloud-hash
|
||||
OUT=static/js/vendors/hash-wasm
|
||||
|
||||
if ! ( rustup target list --installed | grep -q wasm32-unknown-unknown )
|
||||
then
|
||||
echo -e "install first wasm32-unknown-unknown via:\n\trustup target add wasm32-unknown-unknown"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! which wasm-bindgen >/dev/null 2>/dev/null
|
||||
then
|
||||
WASM_BINDGEN_VERSION=$(grep -A1 'name = "wasm-bindgen"' $CREATE/Cargo.lock | head -2 | grep version | sed 's/version = //')
|
||||
echo -e "wasm-bindgen not found, install it via:\n\tcargo install wasm-bindgen-cli --version $WASM_BINDGEN_VERSION"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# SIMD128 is baseline in every evergreen browser (Chrome 91+, Firefox 89+,
|
||||
# Safari 16.4+) and is worth ~3-4× in hashing throughput. Browsers without
|
||||
# it fail instantiation; the frontend detects that and falls back to a
|
||||
|
||||
Binary file not shown.
@@ -153,7 +153,7 @@ impl DeltaChunker {
|
||||
let bytes = &self.buf[chunk.offset..chunk.offset + chunk.length];
|
||||
push_chunk_json(
|
||||
&mut out,
|
||||
&blake3::hash(bytes).to_hex().to_string(),
|
||||
blake3::hash(bytes).to_hex().as_ref(),
|
||||
chunk.length,
|
||||
);
|
||||
consumed = chunk.offset + chunk.length;
|
||||
@@ -175,13 +175,13 @@ impl DeltaChunker {
|
||||
if !self.buf.is_empty() {
|
||||
push_chunk_json(
|
||||
&mut out,
|
||||
&blake3::hash(&self.buf).to_hex().to_string(),
|
||||
blake3::hash(&self.buf).to_hex().as_ref(),
|
||||
self.buf.len(),
|
||||
);
|
||||
self.buf.clear();
|
||||
}
|
||||
out.push_str("],\"file_hash\":\"");
|
||||
out.push_str(&self.file_hasher.finalize().to_hex().to_string());
|
||||
out.push_str(self.file_hasher.finalize().to_hex().as_ref());
|
||||
out.push_str("\",\"total\":");
|
||||
out.push_str(&self.total.to_string());
|
||||
out.push('}');
|
||||
@@ -238,7 +238,7 @@ mod tests {
|
||||
fn run_chunker(data: &[u8], slice: usize) -> (Vec<(String, usize)>, String) {
|
||||
let mut chunker = DeltaChunker::new();
|
||||
let mut chunks: Vec<(String, usize)> = Vec::new();
|
||||
let mut parse = |json: &str, into: &mut Vec<(String, usize)>| {
|
||||
let parse = |json: &str, into: &mut Vec<(String, usize)>| {
|
||||
// items look like ["<hex>",N] — split on '[' groups.
|
||||
for item in json.split("[\"").skip(1) {
|
||||
let hash = &item[..64];
|
||||
|
||||
Reference in New Issue
Block a user