Skip to content

Release 0.6.0

Release 0.6.0 #751

Workflow file for this run

---
name: CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
version-check:
name: Version consistency
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: '3.10'
- name: Check version sync
run: python scripts/version_sync.py --check
rust:
name: Rust (fmt, clippy, test)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- uses: Swatinem/rust-cache@v2
- name: Check formatting
run: cargo fmt --all --check
- name: Run clippy
run: cargo clippy --workspace --exclude iscc-rb --all-targets -- -D warnings
- name: Clippy iscc-lib (no default features)
run: cargo clippy -p iscc-lib --no-default-features -- -D warnings
- name: Clippy iscc-lib (all features)
run: cargo clippy -p iscc-lib --all-features -- -D warnings
- name: Run tests
run: cargo test --workspace --exclude iscc-rb
- name: Test iscc-lib (no default features)
run: cargo test -p iscc-lib --no-default-features
- name: Test iscc-lib (all features)
run: cargo test -p iscc-lib --all-features
- name: Test iscc-lib (text-processing only)
run: cargo test -p iscc-lib --no-default-features --features text-processing
python-test:
name: Python ${{ matrix.python-version }} (ruff, pytest)
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.10', '3.14']
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: actions/setup-python@v7
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true
# exact tag: setup-uv publishes no floating major tag past v7 (v8/v9 are
# exact release tags only), so @v9 does not resolve
- uses: astral-sh/setup-uv@v9.0.0
- name: Install dev dependencies
run: uv sync --group dev
- name: Build Python bindings
run: uv run maturin develop --manifest-path crates/iscc-py/Cargo.toml
- name: Run ruff check
run: uv run ruff check
- name: Run ruff format check
run: uv run ruff format --check
- name: Run pytest
run: uv run pytest
python:
name: Python (ruff, pytest)
if: always()
needs: python-test
runs-on: ubuntu-latest
steps:
- name: Verify all Python versions passed
run: test "${{ needs.python-test.result }}" = "success"
nodejs:
name: Node.js (napi build, test)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: actions/setup-node@v7
with:
node-version: '20'
- name: Install npm dependencies
run: npm install
working-directory: crates/iscc-napi
- name: Build native addon
run: npx napi build --platform
working-directory: crates/iscc-napi
- name: Run tests
run: npm test
working-directory: crates/iscc-napi
wasm:
name: WASM (wasm-pack test)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown
- uses: Swatinem/rust-cache@v2
- name: Install wasm-pack
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
# The blake3 dep in crates/iscc-wasm/Cargo.toml exists only to feature-unify
# `wasm32_simd` onto iscc-lib's blake3 — nothing in the crate imports it, so a
# dep-pruner or refactor could drop it and silently return the published
# @iscc/wasm to the scalar BLAKE3 backend with every test still green.
- name: Assert blake3 wasm32_simd feature is enabled
run: |
cargo tree -p iscc-wasm --target wasm32-unknown-unknown -i blake3 -f "{p} {f}" \
| grep -q 'wasm32_simd' \
|| { echo "::error::blake3 wasm32_simd feature is not enabled for iscc-wasm — the published WASM build would fall back to scalar BLAKE3"; exit 1; }
- name: Run tests
env:
RUSTFLAGS: -C target-feature=+simd128
run: wasm-pack test --node crates/iscc-wasm --features conformance
c-ffi:
name: C FFI (cbindgen, gcc, test)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Install cbindgen
run: cargo install cbindgen
- name: Build FFI crate
run: cargo build -p iscc-ffi
- name: Check C header freshness
run: |
cbindgen --config crates/iscc-ffi/cbindgen.toml --crate iscc-ffi --output crates/iscc-ffi/include/iscc.h
git diff --exit-code crates/iscc-ffi/include/iscc.h || \
(echo "::error::iscc.h is stale. Run: cbindgen --config crates/iscc-ffi/cbindgen.toml --crate iscc-ffi --output crates/iscc-ffi/include/iscc.h" && exit 1)
- name: Compile C test program
run: >
gcc -o test_iscc
crates/iscc-ffi/tests/test_iscc.c
-I crates/iscc-ffi/include
-L target/debug
-liscc_ffi
-lpthread -ldl -lm
- name: Run C test program
run: LD_LIBRARY_PATH=target/debug ./test_iscc
dotnet:
name: C# / .NET (dotnet build, test)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: actions/setup-dotnet@v6
with:
dotnet-version: '8.0'
- name: Build FFI native library
run: cargo build -p iscc-ffi
- name: Restore .NET packages (locked mode)
run: dotnet restore packages/dotnet/Iscc.Lib.Tests/Iscc.Lib.Tests.csproj --locked-mode
- name: Build .NET projects
run: dotnet build packages/dotnet/Iscc.Lib.Tests/Iscc.Lib.Tests.csproj --no-restore
- name: Run .NET tests
run: >
dotnet test packages/dotnet/Iscc.Lib.Tests/ --no-restore
-e LD_LIBRARY_PATH=${{ github.workspace }}/target/debug
java:
name: Java (JNI build, mvn test)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: actions/setup-java@v5
with:
distribution: temurin
java-version: '17'
- name: Build JNI native library
run: cargo build -p iscc-jni
- name: Run Maven tests
run: mvn test -f crates/iscc-jni/java/pom.xml
go:
name: Go (go test, go vet)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-go@v7
with:
go-version-file: packages/go/go.mod
- name: Run Go tests
run: CGO_ENABLED=0 go test -v -count=1 ./...
working-directory: packages/go
- name: Run Go vet
run: go vet ./...
working-directory: packages/go
ruby:
name: Ruby (magnus build, test)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- uses: Swatinem/rust-cache@v2
- name: Install libclang-dev
run: sudo apt-get update && sudo apt-get install -y libclang-dev
- uses: ruby/setup-ruby@v1
with:
ruby-version: '3.1'
working-directory: crates/iscc-rb
bundler-cache: true
- name: Run standardrb
run: bundle exec standardrb
working-directory: crates/iscc-rb
- name: Run clippy
run: cargo clippy -p iscc-rb -- -D warnings
- name: Compile native extension
run: bundle exec rake compile
working-directory: crates/iscc-rb
- name: Run tests
run: bundle exec rake test
working-directory: crates/iscc-rb
cpp:
name: C++ (cmake, ASAN, test)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Install cmake
run: sudo apt-get update && sudo apt-get install -y cmake
- name: Build FFI native library
run: cargo build -p iscc-ffi
- name: Configure CMake
run: >
cmake -B build -DCMAKE_BUILD_TYPE=Debug
-DFFI_LIB_DIR=../../target/debug -DSANITIZE_ADDRESS=ON
working-directory: packages/cpp
- name: Build C++ tests
run: cmake --build build
working-directory: packages/cpp
- name: Run C++ tests
run: LD_LIBRARY_PATH=../../target/debug ./build/tests/test_iscc
working-directory: packages/cpp
swift:
name: Swift (swift build, swift test)
runs-on: macos-14
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Validate root Package.swift manifest
run: swift package dump-package
- name: Build UniFFI native library
run: cargo build -p iscc-uniffi
- name: Build Swift package
run: >
swift build
-Xlinker -L${{ github.workspace }}/target/debug
working-directory: packages/swift
- name: Run Swift tests
run: >
swift test
-Xlinker -L${{ github.workspace }}/target/debug
-Xlinker -rpath
-Xlinker ${{ github.workspace }}/target/debug
working-directory: packages/swift
kotlin:
name: Kotlin (gradle build, test)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: actions/setup-java@v5
with:
distribution: temurin
java-version: '17'
- name: Build UniFFI native library
run: cargo build -p iscc-uniffi
- name: Run Gradle tests
run: ./gradlew test
working-directory: packages/kotlin
bench:
name: Bench (compile check)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Compile benchmarks
run: cargo bench --no-run
perf:
name: Perf (iai-callgrind)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Install valgrind
run: sudo apt-get update && sudo apt-get install -y valgrind
- name: Install cargo-binstall
uses: taiki-e/install-action@v2
with:
tool: cargo-binstall
# --force is load-bearing: Swatinem/rust-cache restores cargo's install
# metadata WITHOUT the ~/.cargo/bin/iai-callgrind-runner binary, so a plain
# binstall would skip the install and the next `cargo bench` would die with
# "no such command". The version must match the iai-callgrind dep (0.16.1).
- name: Install iai-callgrind-runner
run: cargo binstall -y --force iai-callgrind-runner@0.16.1
# IAI_CALLGRIND_ALLOW_ASLR pins ASLR-on everywhere so CI and local runs
# behave identically and the committed baseline is portable; ASLR does not
# affect Ir counts. The regression gate runs in the "Check perf regression"
# step below against the committed .iai-baseline.json.
- name: Run iai-callgrind benches
env:
IAI_CALLGRIND_ALLOW_ASLR: 'true'
run: cargo bench -p iscc-lib --bench iai_benches
# Guard against a false green: the bench binary must keep its
# __iai_callgrind_wrapper symbols (see [profile.bench] in Cargo.toml) or
# callgrind collects zero instructions for every bench while still exiting 0.
# On a clean runner target/iai/ holds only this run, so a non-zero summary
# proves real counts were collected.
- name: Assert non-zero instruction collection
run: |
if grep -rEq '^summary: [1-9]' target/iai/; then
echo "iai-callgrind collected non-zero instructions"
else
echo "::error::iai-callgrind collected ZERO instructions for all benches"
exit 1
fi
# Enforcing regression gate: fail if any benchmark's instruction count (Ir)
# exceeds the committed .iai-baseline.json by more than 10%. Stdlib-only
# Python, so no uv/Python setup step is needed. Refresh the baseline in a
# reviewed commit via `mise run bench:iai:baseline`.
- name: Check perf regression
run: python3 scripts/iai_regression.py --check
# if: always() preserves the artifact even when the regression step fails,
# so a real regression can be inspected against the committed baseline.
- name: Upload iai-callgrind results
if: always()
uses: actions/upload-artifact@v7
with:
name: iai-baseline
path: target/iai/
semver:
name: Semver (cargo-semver-checks)
runs-on: ubuntu-latest
# Informational during the 0.4.0 -> 1.0.0 transition; enforcing from v1.0.0.
continue-on-error: true
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Check semver
uses: obi1kenobi/cargo-semver-checks-action@v2
with:
package: iscc-lib
coverage:
name: Coverage + CRAP (cargo llvm-cov + cargo crap)
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
with:
components: llvm-tools-preview
- uses: Swatinem/rust-cache@v2
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@v2
with:
tool: cargo-llvm-cov
- name: Install cargo-binstall
uses: taiki-e/install-action@v2
with:
tool: cargo-binstall
- name: Install cargo-crap
run: cargo binstall -y --force cargo-crap@0.2.2
- name: Generate LCOV coverage report
run: cargo llvm-cov -p iscc-lib --lcov --output-path lcov.info
- name: Upload coverage report
uses: actions/upload-artifact@v7
with:
name: lcov
path: lcov.info
# Phase 2: report-only CRAP scoring. No score gate, so these steps exit 0.
- name: CRAP report (GitHub annotations)
run: cargo crap --lcov lcov.info --format github
- name: CRAP report (SARIF)
run: cargo crap --lcov lcov.info --format sarif --output crap.sarif
- name: Upload CRAP SARIF to Code Scanning
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: crap.sarif
# Phase 3: enforcing regression + absolute gate. `--fail-regression` fails if
# any function's CRAP score worsens versus the committed .crap-baseline.json
# (refresh via `mise run crap:baseline`); `--fail-above` independently fails any
# function whose CRAP score exceeds the `.cargo-crap.toml` threshold (30),
# including new/renamed functions absent from the baseline. Runs last so the
# report-only diagnostics above still execute when the gate fails.
- name: CRAP regression gate
run: cargo crap --lcov lcov.info --baseline .crap-baseline.json --fail-regression
--fail-above
audit:
name: Audit (cargo-deny)
runs-on: ubuntu-latest
# Enforcing supply-chain gate: cargo deny check fails CI on a RustSec
# advisory, a yanked or banned crate, a disallowed license, or an unknown
# source. Policy lives in the workspace-root deny.toml. No continue-on-error.
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
# taiki-e/install-action fetches a prebuilt cargo-deny binary; pin the
# version for reproducibility (same discipline as cargo-crap / iai-runner).
- name: Install cargo-deny
uses: taiki-e/install-action@v2
with:
tool: cargo-deny@0.19.9
- name: Run cargo-deny
run: cargo deny check
release-workflow:
name: Release workflow (action inputs)
runs-on: ubuntu-latest
# Validates release.yml `with:` keys and step-output reads against each
# action's published action.yml (needs network, so CI-only — prek and the
# pytest suite run the network-free checks). Transport failures degrade to
# a stderr warning, never a red gate.
steps:
- uses: actions/checkout@v7
# exact tag: setup-uv publishes no floating major tag past v7 (v8/v9 are
# exact release tags only), so @v9 does not resolve
- uses: astral-sh/setup-uv@v9.0.0
- name: Check release workflow action inputs
run: uv run --no-project --with pyyaml python scripts/check_release_workflow.py
--check-action-inputs